Когда двойник с целым значением отбрасывается в целое число, гарантируется ли оно "правильно"?
Когда 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-функций с параметрами целочисленного типа, мне нужно беспокоиться об удвоении удвоения вручную или об этом заботятся, когда удваиваются точные целочисленные значения.
Ответы
Ответ 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, но это связано с ошибкой при вычислении с удвоением, а не с его емкостью хранения