В gcc 4.7.3
моя функция fegetround()
возвращает FE_TONEAREST
. Согласно справочнику по C++, это означает округление от нуля. По сути, это означает сохранение последнего бита, который был смещен при настройке точности мантиссы после умножения (поскольку она будет в два раза длиннее, чем должна быть). После этого сохраненный бит добавляется к окончательному результату мантиссы.
Например, умножение с плавающей запятой дает следующие результаты:
0x38b7aad5 * 0x38b7aad5 = 0x3203c5af
Мантисса после умножения
1011 0111 1010 1010 1101 0101
x 1011 0111 1010 1010 1101 0101
-------------------------------
1[000 0011 1100 0101 1010 1110] [1]000 0101 1001 0101 0011 1001
Набор [23'b]
содержит значащие цифры, тогда как набор [1'b]
содержит последний сдвинутый бит. Обратите внимание, что мантисса для результата равна
[000 0011 1100 0101 1010 1111]
Последний бит переключился на 1
, потому что набор [1'b1]
был добавлен к объединенной мантиссе (набор [23'b]
) из-за режима округления.
Вот пример, который ставит меня в тупик, потому что мне кажется, что аппаратное обеспечение округляет неправильно.
0x20922800 * 0x20922800 = 0x1a6e34c (check this on your machine)
1010 0110 1110 0011 0100 1101
x 1010 0110 1110 0011 0100 1101
-------------------------------
01[01 0011 0111 0001 1010 0110 0][1]00 0000 0000 0000 0000 0000
Final Mantissas:
Their Result: 01 0011 0111 0001 1010 0110 0
Correct Result(?): 01 0011 0111 0001 1010 0110 1
Я весь день копался в двоичном коде, так что, возможно, я упустил что-то простое. Какой ответ правильный при заданном способе округления?
fegetround()
возвращает0
, что, как я думал, где-то видел, означалоFE_TONEAREST
... Возможно, я ошибаюсь! РЕДАКТИРОВАТЬ: я только что успешноassert(fegetround() == FE_TONEAREST);
ed. - person Suedocode   schedule 07.12.2013