• dmk © (23.02.17 15:18) [0]
    Привет всем!

    Есть такая функция.
    function DoubleToInt64(F: double): int64;
    asm
     .NOFRAME
     cvtsd2si rax, xmm0
    end;



    Если вставить в параметр максимальное число int64 - 9223372036854775807,
    то получается Exception Invalid Floating point operation.
    Если в системную функцию это число поместить, то получается тоже самое. Максимальный размер double превышает int64или нет?
  • dmk © (23.02.17 15:19) [1]
    Нужно знать какое максимальное число можно поместить в данную функцию.
  • Rouse_ © (23.02.17 15:28) [2]
    Да вроде нормально конвертит

    program Project2;

    {$APPTYPE CONSOLE}

    {$R *.res}

    uses
     System.SysUtils;

    function DoubleToInt64(F: double): int64;
    asm
    .NOFRAME
    cvtsd2si rax, xmm0
    end;

    var
     I: int64;
    begin
     try
       I := DoubleToInt64(-9223372036854775807);
       Writeln(I);
     except
       on E: Exception do
         Writeln(E.ClassName, ': ', E.Message);
     end;
     Readln;
    end.


    выхлоп:
    -9223372036854775808 (в точности потеряли мальца, но...)
  • dmk © (23.02.17 17:06) [3]
    Правильное число без знака: 9223372036854775807
  • dmk © (23.02.17 17:16) [4]
    Максимальное число которок он без ошибки принимает: 9223372036854775200, но возвращается значение 9223372036854774784, а потом неожиданно откуда то 9223372036854775200. Вот тут я вообще ничего не понимаю.
  • Rouse_ © (23.02.17 17:20) [5]
    а, все - понял, вот тебе максимальное: 9223372036854775295 которое конвертируется без проблем
  • Rouse_ © (23.02.17 17:22) [6]
  • dmk © (23.02.17 17:23) [7]
    Вот. Разница 512 почему то. Получается, что проверять на максимум надо.
  • Rouse_ © (23.02.17 17:24) [8]
    Ну там по ссылке как раз и описание причины
  • dmk © (23.02.17 17:55) [9]
    Ясно. Дело не в int64, а в Double.
    Получается новый тип: DoubleInt64
    Ему куча разрядов для знака нужна.
    Вот так вроде нормально считает.

    program TestInt64;

    {$APPTYPE CONSOLE}

    {$R *.res}

    uses
     System.SysUtils;

    function DoubleToInt64(F: double): int64;
    asm
     .NOFRAME
     cvtsd2si rax, xmm0
    end;

    var
     i, d: int64;

    type DoubleInt64 = -4503599627370496..4503599627370496; //-2^52..//2^52

    const
     MaxDoubleToInt64: int64 = High(DoubleInt64);

    begin
     try
       i := MaxDoubleToInt64;
       while i >= (MaxDoubleToInt64 - 10) do
       begin
         d := DoubleToInt64(i);
         Writeln(d);
         Dec(i);
       end;
     except
       on E: Exception do
         Writeln(E.ClassName, ': ', E.Message);
     end;
     Readln;
    end.
  • dmk © (23.02.17 18:14) [10]
    Хотя 2^53 тоже нормально считает и конвертирует.

    program TestInt64;

    {$APPTYPE CONSOLE}

    {$R *.res}

    uses
     System.SysUtils;

    function DoubleToInt64(F: double): int64;
    asm
     .NOFRAME
     cvtsd2si rax, xmm0
    end;

    var
     i, d: int64;

    //type DoubleInt64 = -4503599627370496..4503599627370496; //-2^52..2^52
    type DoubleInt64 = -9007199254740992..9007199254740992; //-2^53..2^53

    const
     MaxDoubleToInt64: int64 = High(DoubleInt64);
     MinDoubleToInt64: int64 = Low(DoubleInt64);

    begin
     try
       i := MaxDoubleToInt64;
       while i >= (MaxDoubleToInt64 - 100) do
       begin
         d := DoubleToInt64(i);
         Writeln(d);
         Dec(i);
       end;

       Readln;

       i := MinDoubleToInt64;
       while i < (MinDoubleToInt64 + 100) do
       begin
         d := DoubleToInt64(i);
         Writeln(d);
         Inc(i);
       end;

     except
       on E: Exception do
         Writeln(E.ClassName, ': ', E.Message);
     end;

     Readln;
    end.
  • dmk © (23.02.17 18:17) [11]
    А вот в 2^54 уже через степень двойки прыгать начинает.
  • NoUser © (24.02.17 01:22) [12]
    > Ему куча разрядов для знака нужна.

    Почему куча, - для знаков только два. Это ж не ПДД, это IEEE 745 ))
  • dmk © (25.02.17 20:20) [13]
    Вопрос закрыт.
Есть новые Нет новых   [118621   +7][b:0][p:0.001]