类似于Numpy astype rounding to wrong value,但这似乎是相反的问题,实际上是我想要的(截断)。在我的真实的例子中,我正在做各种计算,其中一些值可以非常非常接近下一个整数,然后转换为整数。我 * 希望 * 数字被截断,我希望它等价于floor
操作。最后我把结果作为索引。但是,当我执行.astype(np.int32)
时,它似乎是四舍五入。这是怎么回事
In [2]: import numpy as np
...
In [49]: np.array([4319.9997], dtype=np.float32).astype(np.int32)
Out[49]: array([4319], dtype=int32)
In [50]: np.array([4319.9998], dtype=np.float32).astype(np.int32)
Out[50]: array([4320], dtype=int32)
我理解32位浮点精度和64位浮点精度,但我不理解astype
在这里做什么的内部操作。
1条答案
按热度按时间vdgimpew1#
重复评论中所说的话。32位版本的“4319.9997”实际上更接近于“4319.9995”。当numpy/Python/C试图将“4319.9998”从64位浮点数转换为32位浮点数时,只有两个选项是“4319.9995”或“4320.0”,而“4320.0”更接近,因此它会向上舍入。我不能说这是怎么回事,但它使一些意义给我。
原始答案:
我不能说我完全理解我要回答的问题,但有些是有道理的。我认为这可以归结为Python(或C或其他东西)如何将字符串字面量转换为32位浮点数。
二进制打印函数来自:
https://stackoverflow.com/a/16444778/433202
并使用它将数字打印为32位IEEE浮点数:
因此,0表示符号,10001011表示指数部分,00001101111..表示小数有效位部分。
所以当我输入的字符串字面量被转换成双精度数时,它达到了某个阈值,小数部分被加了一个1,这将所有的位都滚到了有效数的整数部分。
对我来说,这整件事的最大误解/误解是,当我被告知将浮点数转换为int将“截断”数字的小数部分时,我假设它是在以10为基数进行的,但它(C?)实际上是在基数2中进行的。这是显而易见的道理,但我从来没有想过,直到这个问题。
我仍然不明白的部分是,为什么从我输入的浮点字符串字面量“4319.9998”转换到下一个数字(+1)。为什么不接受精度问题并将其保持为与“4319.9997”相同的值?我做了一个64位(双精度)版本的二进制函数,当我打印出这两个版本的数字时:
如果你对64位浮点表示的位数进行计数并将其分开,两个值在正负号的“整数”部分之后都有很多1(在将
.
移位到指数位之后),所以我不确定为什么一个会被舍入而另一个不会。