vak: (Default)
[personal profile] vak
Соорудил список всех "интересных" чисел с плавающей точкой (32-битных). Вдруг кому пригодится.

floats.txt

Некоторые выдающиеся экземпляры:
Знак
| Экспонента      Мантисса
0 00000000 00000000000000000000000 = 0.0
1 00000000 00000000000000000000000 = -0.0
0 00000000 00000000000000000000001 = 1.40129846e-45 денормализованное
0 00000000 10000000000000000000000 = 5.87747175e-39 денормализованное
0 00000000 11111111111111111111111 = 1.17549421e-38 денормализованное
0 00000001 00000000000000000000000 = 1.17549435e-38
0 01111111 00000000000000000000000 = 1.0
0 01111111 00000000000000000000001 = 1.00000012
0 01111111 10000000000000000000000 = 1.5
0 01111111 11111111111111111111111 = 1.99999988
0 10000000 00000000000000000000000 = 2.0
0 10000000 00000000000000000000001 = 2.00000024
0 10000000 10000000000000000000000 = 3.0
0 10000000 11111111111111111111111 = 3.99999976
0 11111110 00000000000000000000000 = 1.70141183e+38
0 11111110 11111111111111111111111 = 3.40282347e+38
0 11111111 00000000000000000000000 = inf
1 11111111 00000000000000000000000 = -inf
0 11111111 00000000000000000000001 = nan
0 11111111 10000000000000000000000 = nan
0 11111111 11111111111111111111111 = nan

Date: 2022-08-05 03:38 (UTC)
spamsink: (Default)
From: [personal profile] spamsink
Причём не простая бабушка, а чешская. Собственно, по здравом размышлении, ничего особо секретного в этой математике нет: команда ВЧАБ нужна просто для сортировки чисел по абсолютной величине, а уж этому найдётся много применений.

Date: 2022-08-05 03:58 (UTC)
spamsink: (Default)
From: [personal profile] spamsink
Кстати говоря, получается круто. Если тупо складывать числа 1/1001, 2/1001, ... , 1000/1001 в произвольном порядке, то очень быстро текущий порядок суммы начнёт сильно отличаться от порядка очередного слагаемого, и ошибка будет накапливаться. А вот что получается с помощью алгоритма:
F O R E X   ИПM AH CCCP           BEPCИЯ  2.02 OT  15.07.80

                 1       PROGRAM MAIN                                                                  1
                 2       S = 0.                                                                        2
                 3       SS = 0.                                                                       3
                 4       C = 0.                                                                        4
                 5       DO 10 I = 1,1000                                                              5
                 6       D = MOD(I*137, 1001)/1001.0                                                   6
                 7       SS = SS + D                                                                   7
                 8       T = S + D                                                                     8
                 9       C = (S - T) + D + C                                                           9
                10       S = T                                                                        10
                11    10 CONTINUE                                                                     11
                12       S = S + C                                                                    12
                13       PRINT 1, S, SS                                                               13
                14    1  FORMAT(1XF20.15)                                                             14
                15       END                                                                          15

           *EXECUTE
  500.000000000000000
  499.999999848194420


Несмотря на известную несимметричность округления при делении, её оказалось недостаточно, чтобы испортить правильно подсчитанную сумму даже в последнем знаке. А тупое сложение успело потерять бит 17-18 точности.

Date: 2022-08-05 06:41 (UTC)
spamsink: (Default)
From: [personal profile] spamsink
Это не совсем то - это вычитание unsigned из unsigned (зачем в этом случае говорить two's complement - неясно).