Numpy: prod, что на самом деле переполнение? - PullRequest
0 голосов
/ 07 марта 2019

Я читаю в следующей документации Python:

https://docs.scipy.org/doc/numpy-1.15.0/reference/generated/numpy.prod.html

Примечания

Арифметика является модульной при использовании целочисленных типов, и ошибка не возникает на переполнении. Это означает, что на 32-битной платформе:

>>> x = np.array([536870910, 536870910, 536870910, 536870910])
>>> np.prod(x)  # random 
16

Может кто-нибудь объяснить, что это значит, что арифметика является модульной при использовании целочисленных типов, и как это относится, если у меня 32- или 64-битная платформа?

1 Ответ

1 голос
/ 08 марта 2019

Страница вики объясняет модульную арифметику, но не имеет отношения к numpy.

numpy целые числа могут быть подписаны или не подписаны с 8, 16, 32 или 64 битами.

         Range signed        Range unsigned
 8 bit   -128 to 127         0 to 255        0 to 2**8-1
16 bit   -32768 to 32767     0 to 65535      0 to 2**16-1
32 bit   -2**31 to 2**31-1   0 to 2**32-1    Decimal 9 digits
64 bit   -2**64 to 2**64-1   0 to 2**64-1    Decimal 18/19 digits

Это проще всеговизуализировать для np.int8.Всего 256 различных возможных значений.

import numpy as np
a=np.arange(256, dtype=np.int8)
print(a)

[   0    1    2    3    4    5    6    7    8    9   10   11   12   13   14
   15   16   17   18   19   20   21   22   23   24   25   26   27   28   29
   30   31   32   33   34   35   36   37   38   39   40   41   42   43   44
   45   46   47   48   49   50   51   52   53   54   55   56   57   58   59
   60   61   62   63   64   65   66   67   68   69   70   71   72   73   74
   75   76   77   78   79   80   81   82   83   84   85   86   87   88   89
   90   91   92   93   94   95   96   97   98   99  100  101  102  103  104
  105  106  107  108  109  110  111  112  113  114  115  116  117  118  119
  120  121  122  123  124  125  126  127 -128 -127 -126 -125 -124 -123 -122
 -121 -120 -119 -118 -117 -116 -115 -114 -113 -112 -111 -110 -109 -108 -107
 -106 -105 -104 -103 -102 -101 -100  -99  -98  -97  -96  -95  -94  -93  -92
  -91  -90  -89  -88  -87  -86  -85  -84  -83  -82  -81  -80  -79  -78  -77
  -76  -75  -74  -73  -72  -71  -70  -69  -68  -67  -66  -65  -64  -63  -62
  -61  -60  -59  -58  -57  -56  -55  -54  -53  -52  -51  -50  -49  -48  -47
  -46  -45  -44  -43  -42  -41  -40  -39  -38  -37  -36  -35  -34  -33  -32
  -31  -30  -29  -28  -27  -26  -25  -24  -23  -22  -21  -20  -19  -18  -17
  -16  -15  -14  -13  -12  -11  -10   -9   -8   -7  -6  -5  -4  -3  -2 -1]

Числа, представленные 8 битами> 127, отображаются как отрицательные.

np.binary_repr(127, 8)
Out[11]: '01111111'

np.binary_repr(-128, 8)
Out[12]: '10000000'

Если установлен бит 7, это указывает на отрицательное целое число.

Используйте np.int8 для игры с некоторыми числами.

np.int8(17*18)   # Out[29]: 50
17*18 % 256      # Out[30]: 50  (17*18=306) Mod 256 = 50

np.int8(17*180) # Out[31]: -12
17*180 % 256    # Out[32]: 244  
np.binary_repr(244, 8)   # Out[33]: '11110100'
np.binary_repr(-12, 8)   # Out[34]: '11110100'

В документации говорится, что если переполнение целочисленной арифметики просто оборачивается вокруг диапазона чисел, оно не вызывает исключения.Замените «обтекание» модульным.

Если переполнение действительно происходит, это просто приводит к неожиданным (и, вероятно, неправильным) результатам.

Это дает быстрый набросок.Используйте np.int8(expr) и np.binary_repr( n, 8), чтобы поиграть и посмотреть, что происходит.

Изменить для объяснения, бит 7

Bit numbers  7 6 5 4 3 2 1 0
     127     0 1 1 1 1 1 1 1  Bit 7 not set 0 +127
    -128     1 0 0 0 0 0 0 0  Bit 7 set     1 -128
      -1     1 1 1 1 1 1 1 1  
...