Мастера DELPHI, Delphi programming community Рейтинг@Mail.ru Титульная страница Поиск, карта сайта Написать письмо 
| Новости |
Новости сайта
Поиск |
Поиск по лучшим сайтам о Delphi
FAQ |
Огромная база часто задаваемых вопросов и, конечно же, ответы к ним ;)
Статьи |
Подборка статей на самые разные темы. Все о DELPHI
Книги |
Новинки книжного рынка
Новости VCL
Обзор свежих компонент со всего мира, по-русски!
|
| Форумы
Здесь вы можете задать свой вопрос и наверняка получите ответ
| ЧАТ |
Место для общения :)
Орешник |
Коллекция курьезных вопросов из форумов
KOL и MCK |
KOL и MCK - Компактные программы на Delphi
Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / rsdn.org

 
Чтобы не потерять эту дискуссию, сделайте закладку « предыдущая ветвь | форум | следующая ветвь »

Max int64 и double


dmk ©   (23.02.17 15:18

Привет всем!

Есть такая функция.
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]

Все верно:
$7FFFFFFFFFFFFC00

http://stackoverflow.com/questions/17782425/unsigned-64-bit-integers-which-cannot-map-onto-a-double


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]

Вопрос закрыт.


версия для печати

Написать ответ

Ваше имя (регистрация  E-mail 







Разрешается использование тегов форматирования текста:
<b>жирный</b> <i>наклонный</i> <u>подчеркнутый</u>,
а для выделения текста программ, используйте <code> ... </code>
и не забывайте закрывать теги! </b></i></u></code> :)


Наверх

  Рейтинг@Mail.ru     Титульная страница Поиск, карта сайта Написать письмо