Округление с плавающей запятой до целого числа на x86 против x86_64C++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 Округление с плавающей запятой до целого числа на x86 против x86_64

Сообщение Anonymous »

Я наткнулся на неудачный модульный тест, который включает преобразование чисел типа double в целые числа.
Фактическое число, которое преобразуется, составляет 1,234 * 1000., и в основном код сводится к следующему:
#include
#include

int64_t deltatime(double numSeconds) {
return (int64_t) (numSeconds * 1000.0);
}

int main() {
double s = 1.234;
int64_t ms = deltatime(s);
printf("%fs -> %dms\n", s, ms);
return 0;
}

Теперь компилируя это для x86-64, я получаю:
$ gcc test.c && ./test
1.234000s -> 1234ms

При компиляции для x86-32 я получаю:
$ gcc -m32 test.c && ./test
1.234000s -> 1233ms

(Это с
$ gcc --version
gcc (Debian 14.2.0-7) 14.2.0

)
Теперь я понимаю, что число 1,234 не может быть точно представлено в IEEE-754,
например. в формате с плавающей запятой одинарной точности это действительно 1,2339999675750732421875, и аналогично в случае с плавающей точкой двойной точности это 1,23399999999999999857891452848.
Теперь умножаем фактические значения на 1000,0 > (который может быть представлен точно), всегда должен давать мне 1233,9999..., и приведение этого значения к int64_t на самом деле будет 1233 (а не наивно ожидаемым 1234 ).
Но почему-почему я получаю 1234 на x86-64 (без указания каких-либо параметров округления для компилятора)?
Правильно ли просто добавить 0,5 к сумме (перед приведением к int64_t)?
int64_t deltatime(double numSeconds) {
return (int64_t) (numSeconds * 1000.0 + 0.5);
}


Подробнее здесь: https://stackoverflow.com/questions/791 ... -vs-x86-64
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»