在python中将浮点数转换为整数的最安全方法?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3387655/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Safest way to convert float to integer in python?
提问by Boaz
Python's math module contain handy functions like floor& ceil. These functions take a floating point number and return the nearest integer below or above it. However these functions return the answer as a floating point number. For example:
Python 的 math 模块包含方便的函数,例如floor& ceil。这些函数采用浮点数并返回其下方或上方最接近的整数。然而,这些函数将答案作为浮点数返回。例如:
import math
f=math.floor(2.3)
Now freturns:
现在f返回:
2.0
What is the safest way to get an integer out of this float, without running the risk of rounding errors (for example if the float is the equivalent of 1.99999) or perhaps I should use another function altogether?
从这个浮点数中获取整数的最安全方法是什么,而不会冒舍入错误的风险(例如,如果浮点数等于 1.99999),或者我应该完全使用另一个函数?
采纳答案by Philipp
All integers that can be represented by floating point numbers have an exact representation. So you can safely use inton the result. Inexact representations occur only if you are trying to represent a rational number with a denominator that is not a power of two.
所有可以用浮点数表示的整数都有一个精确的表示。所以你可以安全地使用int结果。只有当您试图用不是 2 的幂的分母来表示有理数时,才会出现不精确的表示。
That this works is not trivial at all! It's a property of the IEEE floating point representation that int°floor = ??? if the magnitude of the numbers in question is small enough, but different representations are possible where int(floor(2.3)) might be 1.
这一点都不重要!这是 IEEE 浮点表示的一个属性,即 int°floor = ??? 如果所讨论的数字的大小足够小,但在 int(floor(2.3)) 可能是 1 的情况下,可能会有不同的表示。
To quote from Wikipedia,
引自维基百科,
Any integer with absolute value less than or equal to 224can be exactly represented in the single precision format, and any integer with absolute value less than or equal to 253can be exactly represented in the double precision format.
任何绝对值小于或等于2 24 的整数都可以用单精度格式精确表示,任何绝对值小于或等于2 53 的整数都可以用双精度格式精确表示。
回答by Boaz
math.floorwill always return an integer number and thus int(math.floor(some_float))will never introduce rounding errors.
math.floor将始终返回一个整数,因此int(math.floor(some_float))永远不会引入舍入错误。
The rounding error might already be introduced in math.floor(some_large_float), though, or even when storing a large number in a float in the first place. (Large numbers may lose precision when stored in floats.)
但是,舍入误差可能已经在 中引入math.floor(some_large_float),甚至在首先将大量数字存储在浮点数中时也引入了。(大数字存储在浮点数中时可能会失去精度。)
回答by Wade73
You could use the round function. If you use no second parameter (# of significant digits) then I think you will get the behavior you want.
你可以使用round函数。如果您不使用第二个参数(有效数字的#),那么我认为您将获得所需的行为。
IDLE output.
空闲输出。
>>> round(2.99999999999)
3
>>> round(2.6)
3
>>> round(2.5)
3
>>> round(2.4)
2
回答by srodriguex
Use int(your non integer number)will nail it.
使用int(your non integer number)将钉它。
print int(2.3) # "2"
print int(math.sqrt(5)) # "2"
回答by phant0m
That this works is not trivial at all! It's a property of the IEEE floating point representation that int°floor = ??? if the magnitude of the numbers in question is small enough, but different representations are possible where int(floor(2.3)) might be 1.
这一点都不重要!这是 IEEE 浮点表示的一个属性,即 int°floor = ??? 如果所讨论的数字的大小足够小,但在 int(floor(2.3)) 可能是 1 的情况下,可能会有不同的表示。
This post explains why it works in that range.
这篇文章解释了为什么它在那个范围内工作。
In a double, you can represent 32bit integers without any problems. There cannotbe any rounding issues. More precisely, doubles can represent allintegers between and including 253and -253.
在 double 中,您可以毫无问题地表示 32 位整数。有不能是任何四舍五入问题。更准确地说,双精度数可以表示2 53和-2 53之间(包括在内)的所有整数。
Short explanation: A double can store up to 53 binary digits. When you require more, the number is padded with zeroes on the right.
简短说明:double 最多可以存储 53 个二进制数字。当您需要更多时,数字在右侧用零填充。
It follows that 53 ones is the largest number that can be stored without padding. Naturally, all (integer) numbers requiring less digits can be stored accurately.
因此,53 是无需填充即可存储的最大数字。自然,所有需要较少位数的(整数)数字都可以准确存储。
Adding one to 111(omitted)111(53 ones) yields 100...000, (53 zeroes). As we know, we can store 53 digits, that makes the rightmost zero padding.
向111(省略)111(53 个)加 1 产生 100...000,(53 个零)。我们知道,我们可以存储 53 位数字,这就是最右边的零填充。
This is where 253comes from.
这就是 2 53 的来源。
More detail:We need to consider how IEEE-754 floating point works.
更多细节:我们需要考虑 IEEE-754 浮点数是如何工作的。
1 bit 11 / 8 52 / 23 # bits double/single precision
[ sign | exponent | mantissa ]
The number is then calculated as follows (excluding special cases that are irrelevant here):
然后按如下方式计算该数字(不包括与此处无关的特殊情况):
-1sign× 1.mantissa ×2exponent - bias
-1符号× 1.尾数 ×2指数 - 偏差
where bias = 2exponent - 1- 1, i.e. 1023 and 127 for double/single precision respectively.
其中偏差 = 2 exponent - 1- 1,即双精度/单精度分别为 1023 和 127。
Knowing that multiplying by 2Xsimply shifts all bits Xplaces to the left, it's easy to see that any integer must have all bits in the mantissa that end up right of the decimal point to zero.
知道乘以2 X只是将所有位向左移动X位,很容易看出任何整数必须将尾数中的所有位都放在小数点右侧为零。
Any integer except zero has the following form in binary:
除零以外的任何整数都具有以下二进制形式:
1x...xwhere the x-es represent the bits to the right of the MSB (most significant bit).
1x...x其中x-es 代表 MSB 右侧的位(最高有效位)。
Because we excluded zero, there will alwaysbe a MSB that is one—which is why it's not stored. To store the integer, we must bring it into the aforementioned form: -1sign× 1.mantissa ×2exponent - bias.
因为我们排除了零,所以总会有一个 MSB 为 1——这就是它没有被存储的原因。要存储整数,我们必须将其转化为上述形式:-1符号× 1.尾数 ×2指数 - 偏差。
That's saying the same as shifting the bits over the decimal point until there's only the MSB towards the left of the MSB. All the bits right of the decimal point are then stored in the mantissa.
这与在小数点上移动位直到 MSB 左侧只有 MSB 相同。然后将小数点右边的所有位存储在尾数中。
From this, we can see that we can store at most 52 binary digits apart from the MSB.
从中我们可以看出,除了 MSB 之外,我们最多可以存储 52 个二进制数字。
It follows that the highest number where all bits are explicitly stored is
因此,显式存储所有位的最高数字是
111(omitted)111. that's 53 ones (52 + implicit 1) in the case of doubles.
For this, we need to set the exponent, such that the decimal point will be shifted 52 places. If we were to increase the exponent by one, we cannot know the digit right to the left after the decimal point.
为此,我们需要设置指数,使小数点移动 52 位。如果我们将指数增加一,我们将无法知道小数点后左边的数字。
111(omitted)111x.
By convention, it's 0. Setting the entire mantissa to zero, we receive the following number:
按照惯例,它是 0。将整个尾数设置为零,我们会收到以下数字:
100(omitted)00x. = 100(omitted)000.
That's a 1 followed by 53 zeroes, 52 stored and 1 added due to the exponent.
这是一个 1 后跟 53 个零,52 个存储和 1 由于指数添加。
It represents 253, which marks the boundary (both negative and positive) between which we can accurately represent all integers. If we wanted to add one to 253, we would have to set the implicit zero (denoted by the x) to one, but that's impossible.
它代表2 53,它标志着我们可以准确地表示所有整数之间的边界(负数和正数)。如果我们想在2 53上加 1 ,我们必须将隐式零(由 表示x)设置为 1,但这是不可能的。
回答by user3763109
Combining two of the previous results, we have:
结合之前的两个结果,我们有:
int(round(some_float))
This converts a float to an integer fairly dependably.
这相当可靠地将浮点数转换为整数。
回答by mrichey56
Another code sample to convert a real/float to an integer using variables. "vel" is a real/float number and converted to the next highest INTEGER, "newvel".
另一个使用变量将实数/浮点数转换为整数的代码示例。“vel”是一个实数/浮点数并转换为下一个最高整数“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))
回答by brandonbanks
If you need to convert a string float to an int you can use this method.
如果您需要将字符串 float 转换为 int 您可以使用此方法。
Example: '38.0'to 38
示例:'38.0'到38
In order to convert this to an int you can cast it as a float then an int. This will also work for float strings or integer strings.
为了将其转换为 int,您可以将其转换为浮点数然后转换为 int。这也适用于浮点字符串或整数字符串。
>>> int(float('38.0'))
38
>>> int(float('38'))
38
Note: This will strip any numbers after the decimal.
注意:这将去除小数点后的任何数字。
>>> int(float('38.2'))
38
回答by Troy H
Since you're asking for the 'safest' way, I'll provide another answer other than the top answer.
由于您要求“最安全”的方式,因此我将提供除最佳答案之外的另一个答案。
An easy way to make sure you don't lose any precision is to check if the values would be equal after you convert them.
确保不会丢失任何精度的一种简单方法是检查转换后的值是否相等。
if int(some_value) == some_value:
some_value = int(some_value)
If the float is 1.0 for example, 1.0 is equal to 1. So the conversion to int will execute. And if the float is 1.1, int(1.1) equates to 1, and 1.1 != 1. So the value will remain a float and you won't lose any precision.
例如,如果浮点数为 1.0,则 1.0 等于 1。因此将执行到 int 的转换。如果浮点数为 1.1,则 int(1.1) 等于 1,并且 1.1 != 1。因此该值将保持为浮点数并且不会丢失任何精度。
回答by Niruttara
df['Column_Name']=df['Column_Name'].astype(int)
df['Column_Name']=df['Column_Name'].astype(int)

