Грядет новая арифметика!
Mar. 21st, 2017 08:55 amВ недрах специалистов по вычислительной математике растет недовольство существующими порядками вычислений с плавающей точкой.
Постепенно назревает революционная ситуация, вот уже и программные (pun not intended) документы появляются (презентация 1.5 часа).
Настолько вкратце, насколько это возможно: предлагаются два принципиально разных представления чисел: одно - с явным битом, означающим округленность и с плавающим распределением бит на мантиссу и экспоненту; второе - проективное (бесконечность одна), обеспечивающее взаимную однозначность операций изменения знака и вычисления обратного значения, но с ограниченной разрядностью, поскольку работает по таблице.
Интересно, кто и когда сделает первый коммерческий процессор, реализующий эту арифметику вместо (или наряду с) IEEE 754.
Даже если не понимать в деталях, посмотрите красивые картинки про погрешность операций, начиная со стр. 31 слайдов.
Развлекайтесь!
Постепенно назревает революционная ситуация, вот уже и программные (pun not intended) документы появляются (презентация 1.5 часа).
Настолько вкратце, насколько это возможно: предлагаются два принципиально разных представления чисел: одно - с явным битом, означающим округленность и с плавающим распределением бит на мантиссу и экспоненту; второе - проективное (бесконечность одна), обеспечивающее взаимную однозначность операций изменения знака и вычисления обратного значения, но с ограниченной разрядностью, поскольку работает по таблице.
Интересно, кто и когда сделает первый коммерческий процессор, реализующий эту арифметику вместо (или наряду с) IEEE 754.
Даже если не понимать в деталях, посмотрите красивые картинки про погрешность операций, начиная со стр. 31 слайдов.
Развлекайтесь!
no subject
Date: 2017-03-21 04:50 pm (UTC)no subject
Date: 2017-03-21 05:04 pm (UTC)no subject
Date: 2017-03-21 05:26 pm (UTC)perl -e '$a =3.2e7*4.0e7 ; +$b =1.*1.; $c = (-1.)*(-1.); $d = 8.0e7*(-1.6e7); $x = $a + $b; $x = $x + $c; $x = $x + $d; print $x'
Впрочем, будучи записано на Си через float действительно получается 0. Через double - уже правильно 2. Причем я не поленился заставить его сложить значение в память, чтоб оно урезалось до 64 бит:
#define FTYPE double FTYPE sum(FTYPE a, FTYPE b, FTYPE c, FTYPE d); FTYPE sum2(FTYPE a, FTYPE b); main() { FTYPE a = 3.2e7*4.0e7; FTYPE b = 1.*1.; FTYPE c = (-1.)*(-1.); FTYPE d = 8.0e7*(-1.6e7); printf("%f\n", sum(a, b, c, d)); } FTYPE sum(FTYPE a, FTYPE b, FTYPE c, FTYPE d) { return sum2(sum2(sum2(a, b), c), d); } FTYPE sum2(FTYPE a, FTYPE b) { volatile FTYPE r = a + b; printf("&r=%p\n", &r); return r; }Переупорядочивание чтоб оно шло от меньшего по модулю к большему b+c+a+d ничего не поменяло.
no subject
Date: 2017-03-21 10:29 pm (UTC)no subject
Date: 2017-03-22 05:38 pm (UTC)no subject
Date: 2017-03-21 06:08 pm (UTC)no subject
Date: 2017-03-21 10:43 pm (UTC)Современные double вычисления производятся с внутренней 64-битной мантиссой, так что полноразрядное представление числа оказывается длиной 80 бит (long double), а слайд про 119 бит, которых хватает для получения такой точности, которая в IEEE достижима только на 256 битах - это просто выпендреж.
В реальной жизни ни inexact bit, предусмотренный в IEEE, не используется, ни значения информационного поля NaN (кроме, НЯМС, демонстрационных целей, как бы их можно было выпендриться используючи), а только флаг quiet/signaling NaN. Ну так в предлагаемой реализации NaN будет появляться реже, а когда будет, то будет всегда signaling.
no subject
Date: 2017-03-21 07:54 pm (UTC)no subject
Date: 2017-03-21 10:45 pm (UTC)no subject
Date: 2017-03-21 09:14 pm (UTC)no subject
Date: 2017-03-21 10:45 pm (UTC)My thoughts exactly. ;)
no subject
Date: 2017-03-22 03:44 am (UTC)no subject
Date: 2017-03-22 04:20 am (UTC)