OpenCV и Numpy плохо взаимодействуют

Может ли кто-нибудь объяснить, почему импорт cv и numpy изменит поведение python struct.unpack? Вот что я наблюдаю:

Python 2.7.3 (default, Aug  1 2012, 05:14:39) 
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from struct import pack, unpack
>>> unpack("f",pack("I",31))[0]
4.344025239406933e-44

Это правильно.

>>> import cv
libdc1394 error: Failed to initialize libdc1394
>>> unpack("f",pack("I",31))[0]
4.344025239406933e-44

Все еще хорошо, после импорта cv

>>> import numpy
>>> unpack("f",pack("I",31))[0]
4.344025239406933e-44

И ОК после импорта cv, а затем numpy

Теперь я перезапускаю python:

Python 2.7.3 (default, Aug  1 2012, 05:14:39) 
[GCC 4.6.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from struct import pack, unpack
>>> unpack("f",pack("I",31))[0]
4.344025239406933e-44
>>> import numpy
>>> unpack("f",pack("I",31))[0]
4.344025239406933e-44

До сих пор так хорошо, но теперь я импортирую cv после импорта numpy:

>>> import cv
libdc1394 error: Failed to initialize libdc1394
>>> unpack("f",pack("I",31))[0]
0.0

Я повторял это несколько раз, в том числе на нескольких серверах, и это всегда происходит одинаково. Я также пробовал это с struct.unpack и struct.pack, что тоже не имеет значения.

Я не могу понять, как импорт numpy и cv может вообще иметь какое-либо влияние на вывод struct.unpack(пакет остается тем же, btw).

"libdc1394" - это, я считаю, красная селедка: ошибка ctypes: ошибка libdc1394: не удалось инициализировать libdc1394

Любые идеи?

tl; dr: импортирует numpy, а затем opencv изменяет поведение struct.unpack.

ОБНОВЛЕНИЕ: нижеприведенный ответ Пауло показывает, что это воспроизводимо. Комментарий Seborg предполагает, что это как-то связано с тем, как python обрабатывает субнормальные значения, что звучит правдоподобно. Я рассмотрел Контексты, но это, похоже, не было проблемой, так как контекст был таким же после импорта, как и до них.

Ответы

Ответ 1

Это не ответ, но он слишком большой для комментария. Я немного играл со значениями, чтобы найти пределы.

Без загрузки numpy и cv:

>>> unpack("f", pack("i", 8388608))
(1.1754943508222875e-38,)
>>> unpack("f", pack("i", 8388607))
(1.1754942106924411e-38,)

После загрузки numpy и cv первая строка будет такой же, но вторая:

>>> unpack("f", pack("i", 8388607))
(0.0,)

Вы заметите, что первым результатом является нижний предел для 32-битных поплавков. Затем я попробовал то же самое с d.

Без загрузки библиотек:

>>> unpack("d", pack("xi", 1048576))
(2.2250738585072014e-308,)
>>> unpack("d", pack("xi", 1048575))
(2.2250717365114104e-308,)

И после загрузки библиотек:

>>> unpack("d",pack("xi", 1048575))
(0.0,)

Теперь первым результатом является нижний предел для точности 64-битного float.

Похоже, что по какой-то причине загрузка библиотек numpy и cv в этом порядке ограничивает unpack для использования 32 и 64-битной точности и возвращает 0 для более низких значений.