在python中将float转换为整数的最安全方法?

Boa*_*oaz 192 python math integer python-2.x

Python的数学模块包含像floor&这样的便捷函数ceil.这些函数采用浮点数并返回低于或高于它的最接近的整数.但是,这些函数将答案作为浮点数返回.例如:

import math
f=math.floor(2.3)
Run Code Online (Sandbox Code Playgroud)

现在f返回:

2.0
Run Code Online (Sandbox Code Playgroud)

从这个浮点数中获取整数的最安全的方法是什么,而不存在舍入错误的风险(例如,如果浮点数相当于1.99999),或者我应该完全使用另一个函数?

Phi*_*ipp 167

可由浮点数表示的所有整数都具有精确表示.所以你可以安全地使用int结果.只有当您尝试使用不是2的幂的分母来表示有理数时,才会出现不精确的表示.

这项工作并非微不足道!它是IEEE浮点表示的一个属性,如果所讨论的数字的大小足够小,则int∘floor=⌊⋅⌋,但int(floor(2.3))可能为1时可能有不同的表示.

引用维基百科,

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

  • +1更深入.您还可以简要解释原因:http://en.wikipedia.org/wiki/Floating_point:D (7认同)

sro*_*uex 101

使用int(your non integer number)将指甲.

print int(2.3) # "2"
print int(math.sqrt(5)) # "2"
Run Code Online (Sandbox Code Playgroud)

  • 我同意,`int(-2.3)`给出了'-2`,因为它向'0`舍入,*即*在这种情况下向上.相比之下,最初的问题使用了`math.floor`,它总是向下舍入:`math.floor(-2.3)`给出`-3.0`. (5认同)
  • 这对负数不起作用:`floor`向下舍入而`int`向0舍入. (4认同)
  • 你有没看过这个问题?他知道**int()**函数,但问过你是否会遇到1.9999而不是2.0的问题.你的答案根本就没有答案,你错过了重点...... (4认同)
  • 这并不是真正的问题。OP只想从“math.floor”的结果中得到一个整数,这个答案展示了如何将浮点数转换为整数。从 `math.floor` 中获取浮点并将其通过 `int` 进行管道传输,问题解决:`int(math.floor(2.3))` (2认同)

Wad*_*e73 44

你可以使用圆函数.如果你没有使用第二个参数(有效数字的数量),那么我认为你会得到你想要的行为.

IDLE输出.

>>> round(2.99999999999)
3
>>> round(2.6)
3
>>> round(2.5)
3
>>> round(2.4)
2
Run Code Online (Sandbox Code Playgroud)

  • `round`也返回一个浮点数,至少在Python 2.6中. (27认同)
  • 在Python 3.1.2中,round返回一个int. (7认同)
  • 所以也许`int(round(2.65))` (4认同)
  • 确实,round和floor在Python 3.x中都返回整数。所以我想这个问题与Python 2.x有关。 (2认同)

小智 39

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

int(round(some_float))
Run Code Online (Sandbox Code Playgroud)

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


pha*_*t0m 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 ]
Run Code Online (Sandbox Code Playgroud)

然后按如下方式计算该数字(不包括此处无关的特殊情况):

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

其中偏压= 2 指数- 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.
Run Code Online (Sandbox Code Playgroud)

为此,我们需要设置指数,使小数点移动52位.如果我们将指数增加1,我们就不能知道小数点后左边的数字.

111(omitted)111x.
Run Code Online (Sandbox Code Playgroud)

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

100(omitted)00x. = 100(omitted)000.
Run Code Online (Sandbox Code Playgroud)

这是1,然后是53个零,52个存储,1个由于指数而添加.

它代表2 53,它标志着我们可以准确表示所有整数的边界(正面和正面).如果我们想要添加1到2 53,我们必须将隐式零(由the表示x)设置为1,但这是不可能的.


小智 7

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

math.floor(some_large_float)但是,可能已经引入了舍入误差,或者甚至在第一个地方将一个大数字存储在浮点数中时.(存放在花车中时,大数字可能会失去精度.)

  • 来自:http://docs.python.org/2/library/math.html - math.floor(x) - 将x的底限作为float返回,最大整数值小于或等于x. (7认同)
  • @Alex:当然,“int”和“floor”对于负数返回不同的值。 (2认同)

bra*_*nks 6

如果需要将字符串float转换为int,则可以使用此方法。

例如:'38.0'38

为了将其转换为int,可以将其转换为float,然后转换为int。这也适用于浮点字符串或整数字符串。

>>> int(float('38.0'))
38
>>> int(float('38'))
38
Run Code Online (Sandbox Code Playgroud)

注意:这将删除小数点后的所有数字。

>>> int(float('38.2'))
38
Run Code Online (Sandbox Code Playgroud)