Python的数学模块包含方便的函数,如floor
& ceil
。这些函数采用浮点数并返回低于或高于它的最接近的整数。但是,这些函数将答案作为浮点数返回。例如:
import math
f=math.floor(2.3)
现在f
返回:
2.0
从这个浮点数中获取整数的最安全的方法是什么,而不存在舍入错误的风险(例如,如果浮点数相当于1.99999),或者我应该完全使用另一个函数?
答案 0 :(得分:154)
可以用浮点数表示的所有整数都有精确的表示。因此,您可以安全地在结果上使用int
。仅当您尝试使用不是2的幂的分母来表示有理数时,才会出现不精确的表示。
这项工作并非微不足道!它是IEEE浮点表示的一个属性,如果所讨论的数字的大小足够小,则int∘floor=⌊⋅⌋,但int(floor(2.3))可能为1时可能有不同的表示。
引用Wikipedia,
绝对值小于或等于2 24 的任何整数都可以用单精度格式精确表示,绝对值小于或等于2 53的任何整数可以用双精度格式精确表示。
答案 1 :(得分:94)
使用int(your non integer number)
会钉它。
print int(2.3) # "2"
print int(math.sqrt(5)) # "2"
答案 2 :(得分:44)
您可以使用圆形功能。如果你没有使用第二个参数(有效数字的数量),那么我认为你会得到你想要的行为。
IDLE输出。
>>> round(2.99999999999)
3
>>> round(2.6)
3
>>> round(2.5)
3
>>> round(2.4)
2
答案 3 :(得分:38)
结合前两个结果,我们有:
int(round(some_float))
这可以相当可靠地将浮点数转换为整数。
答案 4 :(得分:18)
这项工作并非微不足道!它是IEEE浮点表示的一个属性,如果所讨论的数字的大小足够小,则int∘floor=⌊⋅⌋,但int(floor(2.3))可能为1时可能有不同的表示。
这篇文章解释了为什么它在该范围内起作用。
在double中,您可以毫无问题地表示32位整数。 不能是任何舍入问题。更确切地说,双精度可以表示 2 53 和 -2 之间的 所有 整数53
简短说明:双精度数最多可存储53个二进制数字。当您需要更多时,数字会在右边用零填充。
接下来,53个是没有填充可以存储的最大数字。当然,所有需要较少数字的(整数)数字都可以准确存储。
在 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 sign ×1.mantissa×2 指数 - 偏差
其中 bias = 2 exponent - 1 - 1 ,即1023和127分别为双精度/单精度。
知道乘以 2 X 只需将所有位 X 位置移到左侧,很容易看出任何整数都必须全部尾数中以小数点右边结束的位为零。
除零之外的任何整数都具有以下二进制形式:
1x ... x 其中 x -es表示MSB右侧的位(最高位)。
因为我们排除了零,所以总是是一个MSB,这就是为什么它没有存储。要存储整数,我们必须将其变为上述形式: -1 sign ×1.mantissa×2 exponent - bias 。
这就像将位移到小数点上一样,直到只有MSB左侧的MSB。然后将小数点右侧的所有位存储在尾数中。
由此可以看出,除了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 ,它标记了我们可以准确表示所有整数的边界(正面和正面)。如果我们想在 2 53 中添加一个,我们必须将隐式零(由x
表示)设置为1,但这是不可能的。< / p>
答案 5 :(得分:6)
math.floor
将始终返回一个整数,因此int(math.floor(some_float))
将永远不会引入舍入错误。
但是,math.floor(some_large_float)
中可能已经引入了舍入错误,或者甚至在首先将大数字存储在浮点数中时也是如此。 (存放在花车中时,大数字可能会失去精度。)
答案 6 :(得分:5)
如果需要将字符串float转换为int,则可以使用此方法。
示例:'38.0'
到38
为了将其转换为int,您可以将其转换为float,然后转换为int。这也适用于浮点字符串或整数字符串。
>>> int(float('38.0'))
38
>>> int(float('38'))
38
注意:这将删除小数点后的任何数字。
>>> int(float('38.2'))
38
答案 7 :(得分:1)
使用变量将real / float转换为整数的另一个代码示例。 “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))
答案 8 :(得分:0)
由于您正在寻求“最安全”的方式,因此我将提供除最佳答案之外的另一个答案。
确保不损失任何精度的一种简单方法是在转换后检查值是否相等。
if int(some_value) == some_value:
some_value = int(some_value)
例如,如果float为1.0,则1.0等于1。因此将执行向int的转换。并且如果float为1.1,则int(1.1)等于1,并且1.1!=1。因此,该值将保持为float,并且不会损失任何精度。
答案 9 :(得分:0)
df ['Column_Name'] = df ['Column_Name']。astype(int)