最安全的方法来将浮点数转换为整数在Python中?

Python的math模块包含一些方便的function,如floorceil 。 这些函数采用浮点数并返回最接近的整数。 但是,这些函数以浮点数forms返回答案。 例如:

 import math f=math.floor(2.3) 

现在f返回:

 2.0 

什么是从这个浮点数获得一个整数的最安全的方法,而不会有舍入误差的风险(例如,如果float等于1.99999),或者我应该使用另一个函数?

所有可以用浮点数表示的整数都有一个确切的表示。 所以你可以安全地在结果上使用int 。 只有当你试图用一个不是二的幂的分母来表示一个有理数时才会发生不精确的表示。

这工作不是微不足道的! 它是IEEE浮点表示的一个属性,如果所讨论的数字的幅度足够小,但int(floor(2.3))可能是1,则可能有不同的表示。

引用维基百科 ,

任何绝对值小于或等于2 24的整数都可以精确地以单精度格式表示,绝对值小于或等于2 53的任何整数都可以用双精度格式精确表示。

使用int(your non integer number)将钉住它。

 print int(2.3) # "2" print int(math.sqrt(5)) # "2" 

你可以使用轮function。 如果你不使用第二个参数(有效位数),那么我认为你会得到你想要的行为。

IDLE输出。

 >>> round(2.99999999999) 3 >>> round(2.6) 3 >>> round(2.5) 3 >>> round(2.4) 2 

结合以前的两个结果,我们有:

 int(round(some_float)) 

这相当可靠地将浮点数转换为整数。

这工作不是微不足道的! 它是IEEE浮点表示的一个属性,如果所讨论的数字的幅度足够小,但int(floor(2.3))可能是1,则可能有不同的表示。

这篇文章解释了为什么它在这个范围内工作

在double中,你可以代表32位整数,没有任何问题。 不能有任何舍入问题。 更确切地说,双打可以代表2 53-2 53之间的所有整数。

简短说明 :一个double可以存储多达53个二进制数字。 当你需要更多的时候,这个数字在右边填零。

因此,53个是最大的可以存储没有填充的数字。 自然地,所有需要较less数字的(整数)数字都可以被精确地存储。

加一个111(省略)111 (53个)产生100 … 000(53个零)。 正如我们所知,我们可以存储53位数字,这使得最右边的零填充。

这是2 53来自哪里。


更多细节:我们需要考虑IEEE-754浮点如何工作。

  1 bit 11 / 8 52 / 23 # bits double/single precision [ sign | exponent | mantissa ] 

然后计算如下(不包括与此无关的特殊情况):

-1 符号 ×1.mantissa×2 指数 – 偏差

其中bias = 2 指数 – 1 – 1 ,即1023和127分别为双精度/单精度。

知道乘以2 X只是简单地将所有位X位移到左边,很容易看出任何整数都必须在尾数的小数点右边的所有位都为零。

除零以外的任何整数在二进制中具有以下forms:

1x … x其中x -es表示MSB右边的位(最高有效位)。

因为我们排除了零, 总是会有一个MSB,这就是为什么它没有被存储。 要存储整数,我们必须把它带入前面的forms: -1 符号 ×1.mantissa×2 指数 – 偏差

这就像移位小数点一样,直到只有最高位在MSB的左边。 然后将所有小数点右边的位存储在尾数中。

由此我们可以看到,我们最多可以存储52位二进制数字。

由此可见,所有比特被明确存储的最高数字是

 111(omitted)111. that's 53 ones (52 + implicit 1) in the case of doubles. 

为此,我们需要设置指数,使得小数点将被移位52位。 如果我们要将指数增加1,我们就不能知道小数点后面的数字。

 111(omitted)111x. 

按照惯例,它是0.设置整个尾数为零,我们收到以下数字:

 100(omitted)00x. = 100(omitted)000. 

这是一个1,其次是53个零,52个存储和1个由于指数增加。

它代表2 53 ,它标志着我们可以准确地表示所有整数的边界(包括正面和负面)。 如果我们想把1加到2 53 ,我们必须将隐含的零(用x表示)设置为1,但这是不可能的。

math.floor将始终返回一个整数,因此int(math.floor(some_float))将不会引入舍入错误。

舍入错误可能已经在math.floor(some_large_float)引入,或者甚至在首先将大量数据存储在浮点数中。 (大量数字可能会丢失精度,当存储在浮动。)

另一个代码示例使用variables将实数/浮点数转换为整数。 “vel”是一个实数/浮点数,并转换为下一个最高的INTEGER“newvel”。

 import arcpy.math, os, sys, arcpy.da . . with arcpy.da.SearchCursor(densifybkp,[floseg,vel,Length]) as cursor: for row in cursor: curvel = float(row[1]) newvel = int(math.ceil(curvel))