На gcc 4.7.3
, мой fegetround()
функция возвращает FE_TONEAREST
. Согласно c++ reference, это означает округление от нуля. По сути, это означает сохранение последнего бит, который был сдвинут при настройке точности мантиссы после умножения (так как он будет в два раза длиннее, чем должен). После этого сохраненный бит добавляется к окончательному результату мантиссы.Неверное округление с плавающей точкой
Например, с плавающей запятой умножения дает следующие результаты:
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]
набор был добавлен к сплайсингу мантиссы (The [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
Я весь день хруст бинарный, так что, возможно, мне не хватает чего-то простого здесь. Какой ответ правильный с заданным режимом округления?
«возвращает FE_TONEAREST. Согласно ссылке C++, это означает округление от нуля "-> Вы уверены? Посмотрите еще раз на имя. –
Я думаю, что всякий раз, когда возникает вопрос «Моя ошибка или Intel», вы можете дать ответ, не прочитав вопрос, и в 99% случаев вы будете правы. –
Если у вас нет Pentium первого поколения. – dan04