Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Прочее";
Текущий архив: 2016.05.01;
Скачать: [xml.tar.bz2];

Вниз

Головоломка выходного дня.   Найти похожие ветки 

 
Sha ©   (2015-08-14 23:58) [0]

Предположим, что разработчики Delphi вместо замечательного типа TDateTime
придумали тип TDayTime, который в int64-переменной хранит неотрицательное время
в битовом представлении в формате дни:часы:минуты:секунды следующим образом:

dddd dddd dddd dddd dddd dddd dddd dddd dddd dddd dddd dddh hhhh mmmm mmss ssss


Требуется без использования операций деления-умножения написать процедуры:

procedure DayTimeAdd(p1, p2, p3: PDayTime); //p3^:=p1^+p2^
function DayTimeSub(p1, p2, p3: PDayTime): boolean; //p3^:=abs(p1^-p2^); result:=(p1>p2)


 
Sha ©   (2015-08-15 00:43) [1]

Ах, да, забыл самое главное.
Побеждает решение  с минимальным количеством операторов.
Включая и IFы и их внутренности.


 
NoUser ©   (2015-08-15 21:20) [2]

// 30-строчек кода: 4-сложения, 4-вычитания, 10-сравнений( 3-или, 12-масок ) .


 
Dennis I. Komarov ©   (2015-08-15 21:37) [3]

Не умные программисты такое придумали - это еще и валидность значения каждый раз проверять надо...
DayTimeToStr($3F)?


 
NoUser ©   (2015-08-15 21:58) [4]

>  валидность значения каждый раз проверять надо
так оно везде так, в этом суровом мире ))

TFloatSpecial = ( ...., fsDenormal, fsNDenormal, .... fsInf, fsNInf, fsNaN );
DateTimeToStr( NaN )?


 
Sha ©   (2015-08-15 23:07) [5]

> NoUser ©   (15.08.15 21:20) [2]

есть вариант попроще


 
SergP ©   (2015-08-17 10:29) [6]


> Побеждает решение  с минимальным количеством операторов.
>
> Включая и IFы и их внутренности.


c:=a+b;
это один оператор или два (сложение и присваивание)?

c:=a+b+c+d; - это сколько операторов?


 
SergP ©   (2015-08-17 10:56) [7]


> procedure DayTimeAdd(p1, p2, p3: PDayTime); //p3^:=p1^+p2^


Если без всяких проверок валидности, то приблизительно (не проверял или будет правильно работать), должно быть так:

procedure DayTimeAdd(p1, p2, p3: PDayTime);
begin
 p3:=p1+p2;
 p3:=(((p3+$8104) xor p3 or $21040) shr 4 +$3000) and $4104+p3;
end;

хотя оно слишком мутное, могу и ошибаться...


 
SergP ©   (2015-08-17 11:01) [8]

не. там я явно ошибся...
вроде так правильнее:
procedure DayTimeAdd(p1, p2, p3: PDayTime);
begin
p3:=p1+p2;
p3:=(((p3+$8104) xor p3 or $21040) shr 4 +$6000) and $8104+p3;
end;


 
SergP ©   (2015-08-17 12:10) [9]

не. вроде нифига не правильно


 
SergP ©   (2015-08-17 12:20) [10]

procedure DayTimeAdd(p1, p2, p3: PDayTime);
begin
p3:=p1+p2;
p3:=(((p3+$8104) xor p1 xor p2 or $21040) shr 4 +$6000) and $8104+p3;
end;


 
SergP ©   (2015-08-17 13:08) [11]

Вроде так: (без проверок на валидность исходных данных)
procedure DayTimeAdd(p1, p2, p3: TDayTime);
begin
p3:=p1+p2;
p3:=(((p3+$8104) xor p1 xor p2 or $21040) shr 4 +$6000) and $8104+p3;
end;

function DayTimeSub(p1, p2, p3: TDayTime): boolean;
 result:=p1>p2;
 DayTimeAdd(p1, $80c4-p2, p3);
end;


Если с указателями, то хз, иногда путаюсь с ними:

procedure DayTimeAdd(p1, p2, p3: PDayTime);
begin
p3^:=p1^+p2^;
p3^:=(((p3^+$8104) xor p1^ xor p2^ or $21040) shr 4 +$6000) and $8104+p3^;
end;

function DayTimeSub(p1, p2, p3: PDayTime): boolean;
 result:=p1^>p2^;
 DayTimeAdd(p1, @($80c4-p2^), p3);
end;


 
SergP ©   (2015-08-17 13:12) [12]


> procedure DayTimeAdd(p1, p2, p3: TDayTime);
> begin
>  p3:=p1+p2;
>  p3:=(((p3+$8104) xor p1 xor p2 or $21040) shr 4 +$6000)
> and $8104+p3;
> end;
>  
> function DayTimeSub(p1, p2, p3: TDayTime): boolean;
>   result:=p1>p2;
>   DayTimeAdd(p1, $80c4-p2, p3);
> end;


Опять ошибка, не $80c4, а -$80c4

procedure DayTimeAdd(p1, p2, p3: TDayTime);
begin
p3:=p1+p2;
p3:=(((p3+$8104) xor p1 xor p2 or $21040) shr 4 +$6000) and $8104+p3;
end;

function DayTimeSub(p1, p2, p3: TDayTime): boolean;
 result:=p1>p2;
 DayTimeAdd(p1, -$80c4-p2, p3);
end;


 
SergP ©   (2015-08-17 13:13) [13]

М-да... Ну и нафлудил я тут ))))


 
Sha ©   (2015-08-17 13:45) [14]

Во-первых хочу исправить небольшую неточность в условии:
при вычитании функция должна возвращать result:=(p1>=p2), а не result:=(p1>p2).

> SergP

Немного подправил функции, чтобы они компилировались:
procedure DayTimeAddSergP(p1, p2, p3: pint64);
begin
 p3^:=p1^+p2^;
 p3^:=(((p3^+$8104) xor p1^ xor p2^ or $21040) shr 4 +$6000) and $8104+p3^;
end;

function DayTimeSubSergP(p1, p2, p3: pint64): boolean;
var
 tmp: int64;
begin
 result:=p1^>=p2^;
 tmp:=-$80c4-p2^;
 DayTimeAddSergP(p1, @tmp, p3);
end;


Обе функции тест провалили. Тест не исчерпывающий, но достаточно полный:

procedure TForm1.Button3Click(Sender: TObject);
var
 d1, h1, m1, s1: integer;
 d2, h2, m2, s2: integer;
 d3, h3, m3, s3: integer;
 i1, i2: integer;
 t1, t2, t3: integer;
 v1, v2, v3: integer;
 x1, x2, x3: int64;
begin;
 for i1:=0 to $1FFF do begin;
   d1:=i1 shr 12;                               t1:=d1 shl 17;       v1:=     d1 * (60*60*24);
   h1:=i1 shr 8 and 15; h1:=h1 + h1 and 8;      t1:=t1 or h1 shl 12; v1:=v1 + h1 * (60*60);
   m1:=i1 shr 4 and 15; if m1>7 then m1:=m1+44; t1:=t1 or m1 shl 6;  v1:=v1 + m1 * 60;
   s1:=i1       and 15; if s1>7 then s1:=s1+44; t1:=t1 or s1;        v1:=v1 + s1;

   for i2:=0 to $1FFF do begin;
     d2:=i2 shr 12;                               t2:=d2 shl 17;       v2:=     d2 * (60*60*24);
     h2:=i2 shr 8 and 15; h2:=h2 + h2 and 8;      t2:=t2 or h2 shl 12; v2:=v2 + h2 * (60*60);
     m2:=i2 shr 4 and 15; if m2>7 then m2:=m2+44; t2:=t2 or m2 shl 6;  v2:=v2 + m2 * 60;
     s2:=i2       and 15; if s2>7 then s2:=s2+44; t2:=t2 or s2;        v2:=v2 + s2;

     x1:=t1;
     x2:=t2;
     DayTimeAdd(@x1, @x2, @x3);
     t3:=x3;

     d3:=t3 shr 17;         v3:=     d3 * (60*60*24);
     h3:=t3 shr 12 and $1f; v3:=v3 + h3 * (60*60);
     m3:=t3 shr 6 and $3f;  v3:=v3 + m3 * 60;
     s3:=t3 and $3f;        v3:=v3 + s3;

     if v3<>v1+v2 then begin;
       Memo1.Lines.Add(Format("%d %d %d %d",[d1,h1,m1,s1]));
       Memo1.Lines.Add(Format("%d %d %d %d",[d2,h2,m2,s2]));
       Memo1.Lines.Add(Format("%d %d %d %d",[d3,h3,m3,s3]));
       Memo1.Lines.Add("failed");
       exit;
       end;

     end;
   end;

 Memo1.Lines.Add("done")
 end;

procedure TForm1.Button4Click(Sender: TObject);
var
 d1, h1, m1, s1: integer;
 d2, h2, m2, s2: integer;
 d3, h3, m3, s3: integer;
 i1, i2: integer;
 t1, t2, t3: integer;
 v1, v2, v3: integer;
 x1, x2, x3: int64;
 res: boolean;
begin;
 for i1:=0 to $1FFF do begin;
   d1:=i1 shr 12;                               t1:=d1 shl 17;       v1:=     d1 * (60*60*24);
   h1:=i1 shr 8 and 15; h1:=h1 + h1 and 8;      t1:=t1 or h1 shl 12; v1:=v1 + h1 * (60*60);
   m1:=i1 shr 4 and 15; if m1>7 then m1:=m1+44; t1:=t1 or m1 shl 6;  v1:=v1 + m1 * 60;
   s1:=i1       and 15; if s1>7 then s1:=s1+44; t1:=t1 or s1;        v1:=v1 + s1;

   for i2:=0 to $1FFF do begin;
     d2:=i2 shr 12;                               t2:=d2 shl 17;       v2:=     d2 * (60*60*24);
     h2:=i2 shr 8 and 15; h2:=h2 + h2 and 8;      t2:=t2 or h2 shl 12; v2:=v2 + h2 * (60*60);
     m2:=i2 shr 4 and 15; if m2>7 then m2:=m2+44; t2:=t2 or m2 shl 6;  v2:=v2 + m2 * 60;
     s2:=i2       and 15; if s2>7 then s2:=s2+44; t2:=t2 or s2;        v2:=v2 + s2;

     x1:=t1;
     x2:=t2;
     res:=DayTimeSubSergP(@x1, @x2, @x3);
     t3:=x3;

     d3:=t3 shr 17;         v3:=     d3 * (60*60*24);
     h3:=t3 shr 12 and $1f; v3:=v3 + h3 * (60*60);
     m3:=t3 shr 6 and $3f;  v3:=v3 + m3 * 60;
     s3:=t3 and $3f;        v3:=v3 + s3;

     if (res<>(v1>=v2)) or (v3<>abs(v1-v2)) then begin;
       Memo1.Lines.Add(Format("%d %d %d %d",[d1,h1,m1,s1]));
       Memo1.Lines.Add(Format("%d %d %d %d",[d2,h2,m2,s2]));
       Memo1.Lines.Add(Format("%d %d %d %d",[d3,h3,m3,s3]));
       Memo1.Lines.Add("failed");
       exit;
       end;

     end;
   end;

 Memo1.Lines.Add("done")
 end;


 
SergP ©   (2015-08-17 14:03) [15]

Эх. не получилось написать не используя компилятор.... пришлось запускать Delphi
В первой функции нашел ошибку:
там вместо or нужно and

procedure DayTimeAddSergP(p1, p2, p3: pint64);
begin
 p3^:=p1^+p2^;
 p3^:=((((p3^+$8104) xor p1^ xor p2^) and $21040) shr 4 +$6000) and $8104+p3^;
end;


со второй пока думаю


 
SergP ©   (2015-08-17 14:09) [16]

Вторая функция обязана передавать в p3 корректный результат, если ее значение false?


 
SergP ©   (2015-08-17 14:14) [17]

Насчет [16], дело в том, что немного подправил вторую функцию:

function DayTimeSubSergP(p1, p2, p3: pint64): boolean;
var
 tmp: int64;
begin
 result:=p1^>=p2^;
 tmp:=-$8104-p2^;
 DayTimeAddSergP(p1, @tmp, p3);
end;


Но тест все равно ее фейлит таким образом:

0 0 0 0
0 0 0 1
32767 23 59 59
failed


 
Sha ©   (2015-08-17 14:14) [18]

> SergP ©   (17.08.15 14:09) [16]

Да, но в этом случае результат должен быть как если бы из p2 вычитали p1.


 
Sha ©   (2015-08-17 14:18) [19]

Sha ©   (17.08.15 14:14) [18]
т.е. если false, то надо получить p3=p2-p1


 
SergP ©   (2015-08-17 14:27) [20]

ну в таком случае получается:

procedure DayTimeAddSergP(p1, p2, p3: pint64);
begin
 p3^:=p1^+p2^;
 p3^:=((((p3^+$8104) xor p1^ xor p2^) and $21040) shr 4 +$6000) and $8104+p3^;
end;

function DayTimeSubSergP(p1, p2, p3: pint64): boolean;
var
 tmp: int64;
begin
 result:=p1^>=p2^;
 tmp:=-$8104-p2^;
 DayTimeAddSergP(p1, @tmp, p3);
 if not result then p3^:=-$8104-p3^;
end;


 
SergP ©   (2015-08-17 14:40) [21]

Ну если не объявлять дополнительную переменную, то можно немного сократить код по количеству строк, хотя количество операторов от этого не изменится:

procedure DayTimeAddSergP(p1, p2, p3: pint64);
begin
 p3^:=p1^+p2^;
 p3^:=((((p3^+$8104) xor p1^ xor p2^) and $21040) shr 4 +$6000) and $8104+p3^;
end;

function DayTimeSubSergP(p1, p2, p3: pint64): boolean;
begin
 result:=p1^>=p2^;
 p2^:=-$8104-p2^;
 DayTimeAddSergP(p1, p2, p3);
 if not result then p3^:=-$8104-p3^;
end;


 
Sha ©   (2015-08-17 14:44) [22]

> SergP ©   (17.08.15 14:27) [20]

Здорово.
А я не додумался до $6000:
const
 dtCarry = $00021040;
 dtRest  = $00008104;

procedure DayTimeAddSha(p1, p2, p3: PDayTime); //p3^:=p1^+p2^
var
 delta: integer;
begin;
 delta:=(p1.Lo xor p2.Lo xor (p1.Lo + p2.Lo + dtRest)) and dtCarry;
 pInt64(p3)^:=(delta shr 4 or delta shr 2) and dtRest + pInt64(p1)^ + pInt64(p2)^;
 end;

function DayTimeSubSha(p1, p2, p3: PDayTime): boolean; //p3^:=abs(p1^-p2^); result:=(p1>=p2)
var
 delta: integer;
begin;
 if pInt64(p1)^ >= pInt64(p2)^ then begin;
   delta:=(p1.Lo xor p2.Lo xor (p1.Lo - p2.Lo)) and dtCarry;
   pInt64(p3)^:=-((delta shr 4 or delta shr 2) and dtRest) + pInt64(p1)^ - pInt64(p2)^;
   Result:=true;
   end
 else begin; //p1^ < p2^
   delta:=(p2.Lo xor p1.Lo xor (p2.Lo - p1.Lo)) and dtCarry;
   pInt64(p3)^:=-((delta shr 4 or delta shr 2) and dtRest) + pInt64(p2)^ - pInt64(p1)^;
   Result:=false;
   end;
 end;


Получилось длиннее, потому что еще старался не потерять эффективность.


 
Sha ©   (2015-08-17 14:46) [23]

> SergP ©   (17.08.15 14:40) [21]

нет, так не надо, испортишь переданные данные


 
Sha ©   (2015-08-17 14:47) [24]

Sha ©   (17.08.15 14:44) [22]

потерял
type
 PDayTime= ^Int64Rec;


 
Sha ©   (2015-08-17 17:06) [25]

В общем, вот что вышло в итоге:

type
 PDayTime= ^Int64Rec;

const
 dtCarry = $00021040;
 dtRest  = $00008104;
 dtSergP = $00006000; //преобразует двухчасовую дельту к восьмичасовой

procedure DayTimeAdd(p1, p2, p3: PDayTime); //p3^:=p1^+p2^
var
 delta: integer;
begin;
 delta:=((p1.Lo xor p2.Lo xor (p1.Lo + p2.Lo + dtRest)) and dtCarry shr 4 + dtSergP) and dtRest;
 pInt64(p3)^:=delta + pInt64(p1)^ + pInt64(p2)^;
 end;

function DayTimeSub(p1, p2, p3: PDayTime): boolean; //p3^:=abs(p1^-p2^); result:=(p1>=p2)
begin;
 if pInt64(p1)^ >= pInt64(p2)^ then begin;
   pInt64(p3)^:=-(((p1.Lo xor p2.Lo xor (p1.Lo - p2.Lo)) and dtCarry shr 4 + dtSergP) and dtRest) + pInt64(p1)^ - pInt64(p2)^;
   Result:=true;
   end
 else begin; //p1^ < p2^
   pInt64(p3)^:=-(((p1.Lo xor p2.Lo xor (p2.Lo - p1.Lo)) and dtCarry shr 4 + dtSergP) and dtRest) + pInt64(p2)^ - pInt64(p1)^;
   Result:=false;
   end;
 end;


Результирующий ассемблерный код получился довольно эффективным.

> Dennis I. Komarov ©   (15.08.15 21:37) [3]
> это еще и валидность значения каждый раз проверять надо...

Зачем проверять? Оно всегда валидно, если не портить.
Для пущей красивости можно добавить функции вроде IncDayTimeBySeconds.


 
SergP ©   (2015-08-17 18:07) [26]


> Результирующий ассемблерный код получился довольно эффективным.


К сожалению почти никогда не интересовался эффективностью кода, который создает компилятор. Посему может и фигню спрошу,
но точки зрения эффективности не будет ли такое лучше: (типа на 1 операцию меньше) ?

procedure DayTimeAdd(p1, p2, p3: PDayTime); //p3^:=p1^+p2^
var
 delta: integer;
begin;
 pInt64(p3)^:= pInt64(p1)^ + pInt64(p2)^;
 delta:=((p1.Lo xor p2.Lo xor (p3.Lo + dtRest)) and dtCarry shr 4 + dtSergP) and dtRest;
 Inc(pInt64(p3)^,delta);
end;


 
Sha ©   (2015-08-17 18:33) [27]

> SergP ©   (17.08.15 18:07) [26]

Думаю, что будет примерно одинаково, т.к. в обоих случаях мы имеем цепочку последовательных зависимых вычислений. Хотя я склоняюсь к первому варианту, т.к. он меньше изменяет память и короче (количество ассемблерных инструкций 11+8<12+10+4).


 
SergP ©   (2015-08-17 19:01) [28]

Хм. А почeму это:
pInt64(p3)^:=delta + pInt64(p1)^ + pInt64(p2)^;    8 инструкций
а
pInt64(p3)^:= pInt64(p1)^ + pInt64(p2)^; 12 инструкций

?


 
NoUser ©   (2015-08-17 19:12) [29]

сложение не прошло тест - пока только вычитание
const
cSm = $3F;
cMm = $0FC0;
cHm = $0001F000;

cSa = $04;
cMa = $0100;
cHa = $8000;

cSx = $3B;
cMx = $0EC0;
cHx = $00017000;

function DayTimeSub(a, b, c :PDayTime) :Boolean;
begin
if ( a^ >= b^ ) then
 begin
  c^ := a^ - b^;
  if ( ((c^ and cSm) > cSx) or ( (a^ and cSm) < (b^ and cSm) ) ) then Dec(c^, cSa);
  if ( ((c^ and cMm) > cMx) or ( (a^ and cMm) < (b^ and cMm) ) ) then Dec(c^, cMa);
  if ( ((c^ and cHm) > cHx) or ( (a^ and cHm) < (b^ and cHm) ) ) then Dec(c^, cHa);
  Result :=  True ;
 end
else Result :=( not DayTimeSub(b, a, c) );
end;


 
Sha ©   (2015-08-17 19:13) [30]

> SergP ©   (17.08.15 19:01) [28]

это оптимизатор чудит, по идее там достаточно 6, а не 12 инструкций


 
Sha ©   (2015-08-17 19:20) [31]

> NoUser ©   (17.08.15 19:12) [29]

а будет ли разность вычислена правильно,
если ее адрес совпадает с адресом уменьшаемого или вычитаемого?


 
Sha ©   (2015-08-17 20:58) [32]

>NoUser ©   (17.08.15 19:12) [29]

усилил тест дополнительными проверками


procedure TForm1.Button4Click(Sender: TObject);
var
 d1, h1, m1, s1: integer;
 d2, h2, m2, s2: integer;
 d3, h3, m3, s3: integer;
 i1, i2: integer;
 t1, t2, t3: integer;
 v1, v2, v3: integer;
 x1, x2, x3: int64;
 error: integer;
 res: boolean;
begin;
 for i1:=0 to $1FFF do begin;
   d1:=i1 shr 12;                               t1:=d1 shl 17;       v1:=     d1 * (60*60*24);
   h1:=i1 shr 8 and 15; h1:=h1 + h1 and 8;      t1:=t1 or h1 shl 12; v1:=v1 + h1 * (60*60);
   m1:=i1 shr 4 and 15; if m1>7 then m1:=m1+44; t1:=t1 or m1 shl 6;  v1:=v1 + m1 * 60;
   s1:=i1       and 15; if s1>7 then s1:=s1+44; t1:=t1 or s1;        v1:=v1 + s1;

   for i2:=0 to $1FFF do begin;
     d2:=i2 shr 12;                               t2:=d2 shl 17;       v2:=     d2 * (60*60*24);
     h2:=i2 shr 8 and 15; h2:=h2 + h2 and 8;      t2:=t2 or h2 shl 12; v2:=v2 + h2 * (60*60);
     m2:=i2 shr 4 and 15; if m2>7 then m2:=m2+44; t2:=t2 or m2 shl 6;  v2:=v2 + m2 * 60;
     s2:=i2       and 15; if s2>7 then s2:=s2+44; t2:=t2 or s2;        v2:=v2 + s2;

     x1:=t1;
     x2:=t2;
     res:=DayTimeSub(@x1, @x2, @x3);
     t3:=x3;

     d3:=t3 shr 17;         v3:=     d3 * (60*60*24);
     h3:=t3 shr 12 and $1f; v3:=v3 + h3 * (60*60);
     m3:=t3 shr 6 and $3f;  v3:=v3 + m3 * 60;
     s3:=t3 and $3f;        v3:=v3 + s3;

     error:=0;
     if (res<>(v1>=v2)) or (v3<>abs(v1-v2)) or (h3>=24) or (m3>=60) or (s3>=60)
     then error:=3
     else begin;
       x1:=t1;
       x2:=t2;
       if (res<>DayTimeSub(@x1, @x2, @x2)) or (x3<>x2) then begin;
         x3:=x2;
         error:=2;
         end
       else begin;
         x1:=t1;
         x2:=t2;
         if (res<>DayTimeSub(@x1, @x2, @x1)) or (x3<>x1) then begin;
           x3:=x1;
           error:=1;
           end;
         end;
       if error<>0 then begin;
         t3:=x3;
         d3:=t3 shr 17;
         h3:=t3 shr 12 and $1f;
         m3:=t3 shr 6 and $3f;
         s3:=t3 and $3f;
         end;
       end;

     if error<>0 then begin;
       Memo1.Lines.Add(Format("%d %d %d %d",[d1,h1,m1,s1]));
       Memo1.Lines.Add(Format("%d %d %d %d",[d2,h2,m2,s2]));
       Memo1.Lines.Add(Format("%d %d %d %d",[d3,h3,m3,s3]));
       Memo1.Lines.Add(Format("failed %d",[error]));
       exit;
       end;

     end;
   end;

 Memo1.Lines.Add("done")
 end;


после этого DayTimeSubNoUser проваливает тест:
0 0 0 1
0 0 0 1
32767 23 59 60
failed 1


 
NoUser ©   (2015-08-17 23:05) [33]

> после этого DayTimeSubNoUser проваливает тест:
Значит DayTimeSubNoUser было тестом для теста ))


 
SergP ©   (2015-08-18 05:10) [34]


> Sha ©   (17.08.15 19:13) [30]
>
> > SergP ©   (17.08.15 19:01) [28]
>
> это оптимизатор чудит, по идее там достаточно 6, а не 12
> инструкций


вот, кстати интересно, а как компилятор соптимизирует такое:

a:=b-c;
if a=0 then ...

по идее после a:=b-c операцию сравнения не нужно делать, ибо флаги и так будут выставленны должным образом...


 
Sha ©   (2015-08-18 10:11) [35]

> SergP ©   (18.08.15 05:10) [34]

насколько знаю, Delphi сравнивает


 
DayGaykin ©   (2015-08-18 16:43) [36]


> вместо замечательного типа TDateTime

Как по моему, так не очень и замечательный.


 
Sha ©   (2015-08-19 01:04) [37]

Нашел один вариант решения:

const
 dtCarry = $00021040;
 dtMagic = 8667136;
 dtDeltas: array[0..7] of integer= (0, $4, $100, $104, $8000, $8004, $8100, $8104);

procedure DayTimeAdd(p1, p2, p3: PDayTime); //p3^:=p1^+p2^
var
 delta: integer;
begin;
 delta:=dtDeltas[(p1.Lo xor p2.Lo xor (p1.Lo + p2.Lo + dtRest)) and dtCarry * dtMagic shr 29];
 pInt64(p3)^:=delta + pInt64(p1)^ + pInt64(p2)^;
 end;


Замечательной особенностью этого варианта является то,
что он годится и для формата времени с миллисекундами,
меняется только магия.


 
SergP ©   (2015-08-20 09:33) [38]


> Sha ©   (19.08.15 01:04) [37]


Угу. Вроде так получается более универсально... Но первоначальному заданию не соответствует:


> Требуется без использования операций деления-умножения написать
> процедуры:


Кстати, давай еще какие-нить задачи-головоломки, а то в последние годы тут как-то скучновато.



Страницы: 1 вся ветка

Форум: "Прочее";
Текущий архив: 2016.05.01;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.57 MB
Время: 0.003 c
15-1440192604
Юрий
2015-08-22 00:30
2016.05.01
С днем рождения ! 22 августа 2015 суббота


15-1439585926
Sha
2015-08-14 23:58
2016.05.01
Головоломка выходного дня.


15-1439244279
Германн
2015-08-11 01:04
2016.05.01
Футы и узлы в современной авиации.


6-1279796725
Буржуй
2010-07-22 15:05
2016.05.01
Работа с XMLDOCUMENT


15-1438978574
Dimka Maslov
2015-08-07 23:16
2016.05.01
Такие вот дела.





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский