![[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 02:12 (UTC)% perl -e 'printf "%.30f", 3.00000000000000044 * 1.00000000000000022, chr(10);'
3.000000000000001332267629550188
Режимы процессора надо правильно ставить, вот и всё.
no subject
Date: 2011-09-07 02:30 (UTC)no subject
Date: 2011-09-07 02:33 (UTC)no subject
Date: 2011-09-07 02:34 (UTC)Для простоты можно переформулировать в шестнадцатеричном виде, чтобы все разряды были видны.
Умножаем 0x1.8000000000001p+1 на 0x1.0000000000001p+0.
В терминах эпсилон это 3+2э на 1+э. В идеале должны получить 3+5э+2э2. Но в разрядную сетку помещается только 3+4э или 3+6э. Пентиум выдает первый вариант, хотя второй ближе к идеалу.
no subject
Date: 2011-09-07 02:38 (UTC)no subject
Date: 2011-09-07 03:21 (UTC)no subject
Date: 2011-09-07 04:28 (UTC)no subject
Date: 2011-09-07 04:30 (UTC)no subject
Date: 2011-09-07 04:33 (UTC)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)no subject
Date: 2011-09-07 02:39 (UTC)Понятно теперь, что интеловский процессор не виноват?
no subject
Date: 2011-09-07 03:17 (UTC)$ cat c.c
#include <stdio.h>
#include <stdlib.h>
int main(int ac, char **av) {
printf("%.17f\n", atof(av[1]));
printf("%.17f\n", atof(av[2]));
printf("%.17f\n", atof(av[1]) * atof(av[2]));
}
$ cc -o c c.c && ./c 3.00000000000000044 1.00000000000000022
3.00000000000000044
1.00000000000000022
3.00000000000000089
no subject
Date: 2011-09-07 03:24 (UTC)no subject
Date: 2011-09-07 03:58 (UTC)А на Intel(R) Xeon(R) W3530 безбожно глючит.
Вот и верь после этого Интелу.
no subject
Date: 2011-09-07 04:31 (UTC)no subject
Date: 2011-09-07 08:40 (UTC)no subject
Date: 2011-09-07 14:45 (UTC)no subject
Date: 2011-09-07 04:03 (UTC)no subject
Date: 2011-09-07 04:51 (UTC)Я, кстати, однажды благодаря багу в expedia получил место в business классе на билет в экономическом. Это было вскоре после того как они ввели интерактивный выбор места. Я выбрал место в начале самолёта, меня туда и посадили.
no subject
Date: 2011-09-07 05:01 (UTC)no subject
Date: 2011-09-07 06:48 (UTC)меня интересует возможность поговорить с теми, кто asm под MIPS c листа читает =)
no subject
Date: 2011-09-11 20:19 (UTC)В QEMU -- linux usermode test и куски монитора Malta - моё поделие.
no subject
Date: 2011-09-11 20:48 (UTC)Вы не в курсе, нынешний QEMU умеет MIPS64? Типа 5Kf на мальте.
no subject
Date: 2011-09-11 22:37 (UTC)тем более, что надо у автора поста узнать что думает про самостийные форумы сам MIPS!
но сделать свое - почему бы и нет!