Подтвердить что ты не робот

Когда двойник с целым значением отбрасывается в целое число, гарантируется ли оно "правильно"?

Когда double имеет "точное" целочисленное значение, например:

double x = 1.0;
double y = 123123;
double z = -4.000000;

Гарантируется ли это правильное округление до 1, 123123 и -4 при приведении к целочисленному типу через (int) x, (int) y, (int) z? (И не усекать до 0, 123122 или -5 b/c от странности с плавающей запятой). Я прошу b/c в соответствии с этой страницей (что касается fp в lua, язык, который по умолчанию имеет удвоение в качестве его числового типа), рассказывает о том, как целые операции с двойными точками в соответствии с IEEE 754, но я не уверен, что, при вызове C-функций с параметрами целочисленного типа, мне нужно беспокоиться об удвоении удвоения вручную или об этом заботятся, когда удваиваются точные целочисленные значения.

4b9b3361

Ответ 1

Да, если целочисленное значение соответствует int.

A double может представлять целочисленные значения, которые находятся вне диапазона для вашего типа int. Например, 123123.0 не может быть преобразован в int, если ваш тип int имеет только 16 бит.

Также не гарантировано, что a double может представлять каждое значение, которое может представлять конкретный тип. IEEE 754 использует что-то вроде 52 или 53 бит для мантиссы. Если ваш long имеет 64 бита, то преобразование очень больших long в double и обратно может не дать того же значения.

Ответ 2

Как сказал Даниэль Фишер, если значение целой части двойника (в вашем случае, double точно) представляется в том типе, в который вы конвертируете, результат является точным. Если значение вне диапазона целевого типа, поведение undefined. "Undefined" означает, что стандарт допускает любое поведение: вы можете получить самое близкое представляемое число, вы можете получить нуль, вы можете получить исключение или компьютер может взорваться. (Примечание. Хотя стандарт C позволяет вашему компьютеру взорваться или даже уничтожить вселенную, вероятно, спецификации производителей налагают более строгие ограничения на поведение.)

Ответ 3

Он будет делать это правильно, если это действительно истинное целое число, о котором вы можете быть уверены в некоторых контекстах. Но если значение является результатом предыдущих вычислений с плавающей запятой, вы не могли бы легко это узнать.

Почему бы не явно вычислить значение с помощью функции floor(), как в long value = floor(x + 0.5). Или, что еще лучше, используйте функцию modf() для проверки целочисленного значения.

Ответ 4

Да, он будет содержать точное значение, которое вы ему даете, потому что вы вводите его в код. Иногда в вычислениях это приводило бы, например, к 0.99999999999, но это связано с ошибкой при вычислении с удвоением, а не с его емкостью хранения