Я наткнулся на неудачный модульный тест, который включает преобразование чисел типа 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
Округление с плавающей запятой до целого числа на x86 против x86_64 ⇐ C++
Программы на C++. Форум разработчиков
-
Anonymous
1730059991
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);
}
Подробнее здесь: [url]https://stackoverflow.com/questions/79131400/rounding-floats-to-int-on-x86-vs-x86-64[/url]
Ответить
1 сообщение
• Страница 1 из 1
Перейти
- Кемерово-IT
- ↳ Javascript
- ↳ C#
- ↳ JAVA
- ↳ Elasticsearch aggregation
- ↳ Python
- ↳ Php
- ↳ Android
- ↳ Html
- ↳ Jquery
- ↳ C++
- ↳ IOS
- ↳ CSS
- ↳ Excel
- ↳ Linux
- ↳ Apache
- ↳ MySql
- Детский мир
- Для души
- ↳ Музыкальные инструменты даром
- ↳ Печатная продукция даром
- Внешняя красота и здоровье
- ↳ Одежда и обувь для взрослых даром
- ↳ Товары для здоровья
- ↳ Физкультура и спорт
- Техника - даром!
- ↳ Автомобилистам
- ↳ Компьютерная техника
- ↳ Плиты: газовые и электрические
- ↳ Холодильники
- ↳ Стиральные машины
- ↳ Телевизоры
- ↳ Телефоны, смартфоны, плашеты
- ↳ Швейные машинки
- ↳ Прочая электроника и техника
- ↳ Фототехника
- Ремонт и интерьер
- ↳ Стройматериалы, инструмент
- ↳ Мебель и предметы интерьера даром
- ↳ Cантехника
- Другие темы
- ↳ Разное даром
- ↳ Давай меняться!
- ↳ Отдам\возьму за копеечку
- ↳ Работа и подработка в Кемерове
- ↳ Давай с тобой поговорим...
Мобильная версия