-
Привет всем! Есть такая функция. function DoubleToInt64(F: double): int64;
asm
.NOFRAME
cvtsd2si rax, xmm0
end;
Если вставить в параметр максимальное число int64 - 9223372036854775807, то получается Exception Invalid Floating point operation. Если в системную функцию это число поместить, то получается тоже самое. Максимальный размер double превышает int64или нет?
-
Нужно знать какое максимальное число можно поместить в данную функцию.
-
Да вроде нормально конвертит
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 (в точности потеряли мальца, но...)
-
Правильное число без знака: 9223372036854775807
-
Максимальное число которок он без ошибки принимает: 9223372036854775200, но возвращается значение 9223372036854774784, а потом неожиданно откуда то 9223372036854775200. Вот тут я вообще ничего не понимаю.
-
а, все - понял, вот тебе максимальное: 9223372036854775295 которое конвертируется без проблем
-
-
Вот. Разница 512 почему то. Получается, что проверять на максимум надо.
-
Ну там по ссылке как раз и описание причины
-
Ясно. Дело не в 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.
-
Хотя 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.
-
А вот в 2^54 уже через степень двойки прыгать начинает.
-
> Ему куча разрядов для знака нужна.
Почему куча, - для знаков только два. Это ж не ПДД, это IEEE 745 ))
-
Вопрос закрыт.
|