Почему побитовый сдвиг влево из numpy дает разные результаты в разных системах?

#python #numpy #bitwise-operators #bit-shift

#python #numpy #побитовые операторы #битовый сдвиг

Вопрос:

Я использую побитовые операции из numpy в двух разных системах и получаю разные / противоречивые результаты. После небольшого расследования я выяснил, что left_shift вызывает проблему. Если я сделаю следующее:

 xs = [i for i in range(100)]
np.left_shift(xs, xs)
 

В первой системе, которую я получаю:

 array([                   0,                    2,                    8,
                         24,                   64,                  160,
                        384,                  896,                 2048,
                       4608,                10240,                22528,
                      49152,               106496,               229376,
                     491520,              1048576,              2228224,
                    4718592,              9961472,             20971520,
                   44040192,             92274688,            192937984,
                  402653184,            838860800,           1744830464,
                 3623878656,           7516192768,          15569256448,
                32212254720,          66571993088,         137438953472,
               283467841536,         584115552256,        1202590842880,
              2473901162496,        5085241278464,       10445360463872,
             21440476741632,       43980465111040,       90159953477632,
            184717953466368,      378231999954944,      774056185954304,
           1583296743997440,     3236962232172544,     6614661952700416,
          13510798882111488,    27584547717644288,    56294995342131200,
         114841790497947648,   234187180623265792,   477381560501272576,
         972777519512027136,  1981583836043018240,  4035225266123964416,
        8214565720323784704, -1729382256910270464, -2882303761517117440,
       -4611686018427387904, -6917529027641081856, -9223372036854775808,
       -9223372036854775808,                   64,                  130,
                        264,                  536,                 1088,
                       2208,                 4480,                 9088,
                      18432,                37376,                75776,
                     153600,               311296,               630784,
                    1277952,              2588672,              5242880,
                   10616832,             21495808,             43515904,
                   88080384,            178257920,            360710144,
                  729808896,           1476395008,           2986344448,
                 6039797760,          12213813248,          24696061952,
                49928994816,         100931731456,         204010946560,
               412316860416,         833223655424,        1683627180032,
              3401614098432])
 

И во второй системе я получаю:

 array([                   0,                    2,                    8,
                         24,                   64,                  160,
                        384,                  896,                 2048,
                       4608,                10240,                22528,
                      49152,               106496,               229376,
                     491520,              1048576,              2228224,
                    4718592,              9961472,             20971520,
                   44040192,             92274688,            192937984,
                  402653184,            838860800,           1744830464,
                 3623878656,           7516192768,          15569256448,
                32212254720,          66571993088,         137438953472,
               283467841536,         584115552256,        1202590842880,
              2473901162496,        5085241278464,       10445360463872,
             21440476741632,       43980465111040,       90159953477632,
            184717953466368,      378231999954944,      774056185954304,
           1583296743997440,     3236962232172544,     6614661952700416,
          13510798882111488,    27584547717644288,    56294995342131200,
         114841790497947648,   234187180623265792,   477381560501272576,
         972777519512027136,  1981583836043018240,  4035225266123964416,
        8214565720323784704, -1729382256910270464, -2882303761517117440,
       -4611686018427387904, -6917529027641081856, -9223372036854775808,
       -9223372036854775808,                    0,                    0,
                          0,                    0,                    0,
                          0,                    0,                    0,
                          0,                    0,                    0,
                          0,                    0,                    0,
                          0,                    0,                    0,
                          0,                    0,                    0,
                          0,                    0,                    0,
                          0,                    0,                    0,
                          0,                    0,                    0,
                          0,                    0,                    0,
                          0,                    0,                    0,
                          0])
 

Итак, как вы можете видеть, до определенного момента результаты становятся противоречивыми. Кто-нибудь знает, что может быть причиной этого?

ДОБАВЛЕНО

Под «разными системами» я подразумеваю разные компьютеры. На первом компьютере установлен numpy 1.15.1, а на втором 1.15.2.

Комментарии:

1. Что здесь означает «разные системы»? Numpy 1.19 против Numpy 1.21? Win против Linux? Python2 против Python3? Dell против HP?

2. Кстати, я получаю второй результат Numpy 1.19.4, Python 3.8.

3. @Mr.T. Я получаю разные результаты на разных компьютерах. Версии numpy также отличаются. Первая имеет версию 1.15.1, а вторая 1.15.2.

4. @Roman Я только что попробовал numpy 1.19 и 1.15.1 — получил те же результаты (номер 2). Может быть, это зависит от машины? Я просмотрел микрофункции numpy, но не нашел подсказки, почему это может происходить. Может быть, если вы предоставите спецификации машины (и битовую ширину ОС), это может дать некоторый намек?

5. С помощью Numpy 1.15.1 в той же среде я получаю результат, который не является ни вашим первым, ни вторым (заканчивается на 792).

Ответ №1:

Старые версии NumPy не определяют, что делают операторы сдвига, если вы пытаетесь сдвинуть на величину> = ширину типа. Они в основном просто делегируют семантику операторам сдвига C, для которых это неопределенное поведение. В зависимости от аппаратных средств и деталей компилятора может произойти практически все, что угодно (теоретически, вплоть до сбоев, проблем с безопасностью и произвольного другого неправильного поведения).

Это было изменено в 1.18, но ваши версии NumPy старше этого.

Если вам нужно определенное поведение, не пытайтесь делать подобные сдвиги.