我必须将欧元(字符串)转换为欧分(整数):
例子:
'12,1'=> 1210
'14,51'=> 1451
我使用以下python函数:
int(round(float(amount.replace(',', '.')), 2) * 100)
但是,用这个数量“ 1229,84”,结果是:122983
更新资料
我使用Wim的解决方案,因为我在Python / Jinja和javascript中都使用整数来表示货币。另请参阅Chepner的答案。
int(round(100 * float(amout.replace(',', '.')), 2))
我的问题由我先生回答,他解释了上述结果。
请您参考如下方法:
Docs说了些什么,并有一个简单的解释
我尝试了一下,并对这种情况感到惊讶。所以我转向documentation,里面有一个小字条。
注意float的round()行为可能令人惊讶:for
例如,round(2.675,2)给出2.67,而不是预期的2.68。这个
不是错误:这是由于大多数十进制小数
不能完全表示为浮点数。
现在,这意味着什么,大多数十进制小数不能表示为浮点数。好的文档后面跟着一个很好的link来解释这一点,但是由于您可能没有来这里阅读一个讨厌的技术文档,所以让我总结一下正在发生的事情。
Python使用IEEE-754浮点标准来表示浮点数。该标准损害了速度的准确性。有些数字无法准确表示。例如,.1实际上表示为0.1000000000000000055511151231257827021181583404541015625。有趣的是,二进制中的.1实际上是一个无限重复的数字,就像1/3是无限重复的.333333一样。
幕后案例研究
现在开始处理您的特殊情况。这很有趣,这就是我发现的。
首先让我们简化您尝试做的事情
>>> amount = '1229,84'
>>> int(round(float(amount.replace(',', '.')), 2) * 100)
>>> 122983
至
>>>int(1229.84 * 100)
>>> 122983
有时,Python1无法100%准确地显示二进制浮点数,出于同样的原因,我们无法将分数1/3显示为小数。发生这种情况时,Python将隐藏任何多余的数字。
.1实际上存储为
-0.10000000000000009 2,但是如果您在控制台中键入
int(1.1) - 1.1,Python会将其显示为.1。通过执行
int(myNum) - myNum 3,我们可以看到那些多余的数字。我们可以将此
1229.84公式应用于大多数浮点数,以查看它们后面的多余隐藏数字。4。在您的情况下,我们将执行以下操作。
>>> int(1229.84) - 1229.84
-0.8399999999999181
1229.8399999999999181实际上是
122983.99999999999。继续5
>>> 1229.84, 2) * 100
122983.99999999999 #there's all of our hidden digits showing up.
现在进入最后一步。这是我们关注的部分。将其更改回整数。
>>> int(122983.99999999999)
122983
它向下取整,而不是向上取整,但是,如果我们从未将其乘以100,则最后还有2个9,Python将取整。
>>> int(122983.9999999999999)
122984
???现在发生了什么。为什么Python将
122983.9999999999999向下取整,而将
122983.9999999999999向上取整?好吧,每当Python将浮点数转换为整数时,它都会四舍五入。但是,您必须记住,对于Python
122984.0,末尾多两个99是与
122983.9999999999999相同的。
>>> 122983.9999999999999
122984.0
>>> a = 122983.9999999999999
>>> int(a) - a
0.0
并且最后没有两个额外的99。
>>> 122983.99999999999
122983.99999999999
>>> a=122983.99999999999
>>> int(a) - a
-0.9999999999854481
Python肯定会将
122984.0视为
122983.99999999999,而不是
122983.99999999999。现在回到将
122984转换为整数。因为我们创建了一个小于
122984的小数部分,Python认为这是一个与
122983分开的数字,并且由于强制转换为整数总是会导致Python舍入,因此得到
myFloat.hex()。
ew。要经历很多事情,但是我确实写了很多东西,希望您能做到。所有这些的解决方案是使用 decimal数字而不是浮点数,这会影响精度的速度。
四舍五入怎么办?最初的问题也有一些四舍五入-没有用。见附录6。
解决方案
a)最简单的解决方案是使用 decimal module而不是浮点数。这是在任何财务或会计程序中的首选处理方式。
该文档还提到了我总结的以下解决方案。
b)确切的值可以通过
float.fromhex(myHex)和
myFloat.as_integer_ratio()以十六进制形式表示和检索
c)也可以通过
int(1.1) - 1.1将精确值作为分数检索
d)文档简要提到使用SciPy进行浮点算术运算,但是此 SO question提到SciPy的NumPy浮点数仅是内置浮点类型的别名。 decimal module是更好的解决方案。
附录
1-尽管我经常提到Python的行为,但我所谈论的内容是IEEE-754浮点标准的一部分,这是主流编程语言为其浮点数使用的标准。
2-
-0.10000000000000009给我
0.1000000000000000055511151231257827021181583404541015625,但是根据
documentation .1确实是
int(1.1) - 1.1
3-我们使用
int(.1) - .1而不是
int(.1) - .1,因为
int(someNum) -someNum不会给我们隐藏的数字,但是根据文档,它们仍应存在.1,因此我说
int(myNum) - myNum大部分时间都可以工作,但并非始终如此。
4-当我们使用公式
int(3.9)时,发生的事情是将数字转换为整数将使数字向下取整,因此
3变为3,当我们从
3.9减去
-.9时,剩下的是
5-这并不会真正影响我们的分析结果,但是当乘以100时,隐藏的数字也会变化一点,而不是将隐藏的数字移动两位小数。
>>> a = 1229.84
>>> int(a) - a
-0.8399999999999181
>>> a = round(1229.84, 2) * 100
>>> int(a) - a
-0.9999999999854481 #I expected -0.9999999999918100?
6 - It may seem like we can get rid of all those extra digits by rounding to two decimal places.
>>> round(1229.84, 2) # which is really round(1229.8399999999999181, 2)
1229.84
但是,当我们使用
int(someNum) - someNum公式查看隐藏的数字时,它们仍然存在。
>>> a = round(1229.84, 2)
>>> int(a) - a
-0.8399999999999181
这是因为Python无法将1229.84存储为二进制浮点数。不能做所以...舍入1229.84绝对没有任何作用。
