![[personal profile]](https://www.dreamwidth.org/img/silk/identity/user.png)
Знаете ли вы, что Интеловские процессоры врут при округлении? Попробуйте умножить 3.00000000000000044 на 1.00000000000000022 - пентиум даёт 3.00000000000000089. А между тем правильный ответ 3.00000000000000133. Компилятор не виноват, он честно включает аппаратное округление к ближайшему числу.
То же самое при делении: 1 / 0.99999999999999989 должно давать 1.00000000000000022, а не 1.
Вывод: покупайте процессоры MIPS. :)
Upd: выяснилось, что баг проявляется только на Intel Xeon (W3520 и W3530) и Pentium 4. Core Duo, Core2 Duo, i5 и AMD Opteron работают правильно.
То же самое при делении: 1 / 0.99999999999999989 должно давать 1.00000000000000022, а не 1.
Вывод: покупайте процессоры MIPS. :)
Upd: выяснилось, что баг проявляется только на Intel Xeon (W3520 и W3530) и Pentium 4. Core Duo, Core2 Duo, i5 и AMD Opteron работают правильно.
no subject
Date: 2011-09-07 03:56 (UTC)А на Intel(R) Xeon(R) W3530 безбожно глючит.
no subject
Date: 2011-09-07 04:27 (UTC)популярно, для невежд. Округление по умолчанию делается tie break to even. Если промежуточные вычисления делаются в long double, то 2*ε2 оказываются за пределами разрядной сетки, 5*ε после нормализации выглядит как 2.5*ε, и округление делается вниз, к 2*ε.Если промежуточные вычисления делаются в quad, то ничьей не оказывается, и получается честное округление к ближайшему, т.е. 3*ε.
И это не баг, а естественное ограничение конкретных реализаций FPU.
no subject
Date: 2011-09-07 04:51 (UTC)no subject
Date: 2011-09-07 05:16 (UTC)no subject
Date: 2011-09-07 05:22 (UTC)no subject
Date: 2011-09-07 05:33 (UTC)no subject
Date: 2011-09-07 05:39 (UTC)no subject
Date: 2011-09-07 06:26 (UTC)Говорил же, режимы нужно правильно ставить
Date: 2011-09-07 23:15 (UTC)void
set_fpu (unsigned int mode)
{
asm ("fldcw %0" : : "m" (*&mode));
}
int main(int ac, char **av) {
volatile double a = 3.00000000000000044;
volatile double b = 1.00000000000000022;
set_fpu(0x27F);
printf("%.17f\n", a * b);
}
Результат умножения будет немедленно, до попадания в регистр FPU округляться до double, и будет правильно на всех процессорах.
no subject
Date: 2011-09-07 23:23 (UTC)Я пробовал fesetround(FE_TONEAREST) - не помогает.
no subject
Date: 2011-09-07 23:41 (UTC)Я вот чего не пойму:
Xeon:
FPU mode 7f: 3.00000000000000000
FPU mode 17f: 3.00000000000000089
FPU mode 27f: 3.00000000000000133
FPU mode 37f: 3.00000000000000089
Core:
FPU mode 7f: 3.00000000000000133
FPU mode 17f: 3.00000000000000133
FPU mode 27f: 3.00000000000000133
FPU mode 37f: 3.00000000000000133
Что у них extended precision разная - понятно, но почему single precision так нагло игнорируется?
no subject
Date: 2011-09-08 00:31 (UTC)no subject
Date: 2011-09-08 00:36 (UTC)no subject
Date: 2011-09-08 00:46 (UTC)no subject
Date: 2011-09-08 00:38 (UTC)no subject
Date: 2011-09-08 00:51 (UTC)