问题描述
这是ipython3中的执行
In [81]: r2
Out[81]:
array([-1.2997805,-1.4251276,-1.3047135,...,-2.0358603,-1.9741256,-1.6412157],dtype=float32)
In [82]: r2.astype(np.uint8)
Out[82]: array([255,255,254,255],dtype=uint8)
-1.2997805如何转换为255?
ADD:从下面的评论(谢谢)中,我进行了这样的测试。看起来浮点数已转换为int,并且完成了255模(将其读取为unsigned int8)。
is first convereted to int. and the it is cut using modulo(%).
In [98]: b
Out[98]: array([-1.,0.,1.])
In [99]: b.astype(np.uint8)
Out[99]: array([255,1],dtype=uint8)
解决方法
您已转换为unsigned int 8,其中-1对应于255,-2对应于254等。 如果要获得-1,则必须使用np.int8将其转换为-2,将其转换为带符号的int8:
>>> np.float32(-2.0358603).astype(np.uint8)
254
>>> np.float32(-2.0358603).astype(np.int8)
-2
,
根据astype
上的numpy文档,这是“不安全的转换”,表示“可能会进行任何数据转换”。他们没有说明转换是如何完成的,我也没有在文档的快速搜索中找到它,因此它可能取决于实现。
我的猜测如下:首先将32位浮点强制转换为8位有符号整数,默认情况下默认为向零截断,例如。 -1.3变为-1。然后将无符号的8位整数转换为8位的无符号整数,得到255的值。
float x = -1.2997805; # Assume float is 32-bit
(uint8_t)(int8_t)x;
这与使用(uint8_t)x
直接转换为8位无符号整数不同,后者至少在我测试的平台(godbolt的x86-64 gcc)上为0。
这种事情是very confusing,甚至可能取决于平台(可能取决于操作系统,numpy版本,FP硬件决定做什么或处理器是否使用2s补码等),因此不要在没有确切知道要在哪个平台上运行代码的情况下,总是依赖于此行为,并且这仍然是不良的编码实践。令人惊讶的是,我找不到有关numpy的强制转换规则如何工作的参考。