精确度问题 [英] Precision issue

查看:80
本文介绍了精确度问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Python中输入3.4会产生3.3999999999999999。

我知道这是因为3.4不能用

的2次幂来精确表达。处理底层图层的规则

来自Python,这样3.4收益率3.4?


谢谢,


卡罗伊

解决方案
Ladvánszky卡罗伊写道:
输入3.4在Python产生3.3999999999999999
我知道这是因为3.4不能用2的幂来精确表达。下层的浮点处理规则是否可以从Python设置,以便3.4得到3.4?



从问题来看,似乎你可能没有完全理解

并且掌握了你可以找到的解释:
http://www.python.org/doc/current/tut/节点1 4.html

我引用,特别是:

"""

,无论基数2多少您愿意使用的数字,小数值

0.1不能完全表示为基数2分数。

"""
$由于完全相同的原因,b $ b和3.4相同。只要使用

二进制文件 - 今天的机器不提供选项 - 就是这样。


只有使用十进制或者有效的小数可能是可能的,

和今天的硬件并不真正支持它们,所以你需要在软件中做一切

。如果你不介意由此导致的计算速度大幅下降(许多应用程序实际上并没有做很多计算,所以不需要b $ b呵护)那里网上有不少包,但没有,AFAIK,其中b $ b被认为是可供生产使用。我怀疑,执行Rational

算术的最快方法是使用gmpy(mpq类型) - 但是快速。在旁观者的眼中是

。让我举个例子......:


根据timeit.py,在x = 3.4(原生浮动)之后,int(x * 10)需要

2.46微秒;但是在x = mpq(3.4)[导入了mpq fm gmpy]之后,

int(x * 10)需要9.72微秒!那是'慢了四倍......


另外,mpq(3.4)的默认表示是一个分数,17/5;所以,

您仍需要一些格式化工作才能将其显示为3.4。

Alex


< BLOCKQUOTE>Ladvánszky卡罗伊写道:
输入3.4 Python中产生3.3999999999999999
我知道这是因为这样的事实:3.4不能准确bythe
幂表示。 2.可以从Python设置底层的浮动处理规则,以便3.4得到3.4?




浮点数是浮点数是浮点数;)


例如,可以做的是更改print

语句中的浮点格式。 IIRC在Python中有一些魔力可以在2.x行的某个地方删除
效果。


如果你担心输出,你为什么不明确地说明你的浮动数字?b $ b格式你的浮点数?类似于:

print"%。2f" %3.4



3.40

- Gerhard


Alex Martelli< al *** @ aleax.it>写在

新闻:8l ********************** @ news2.tin.it:

Ladvánszky卡罗利写道:
输入3.4 Python中产生3.3999999999999999
我知道这是因为这样的事实:3.4不能准确
表示。可以通过Python设置底层
图层的浮动处理规则,以便3.4得到3.4?



从问题来看,似乎你可能没有完全理解和掌握你可以找到的解释:
http://www.python.org/doc/current/tut/node14.html
我引用,特别是:




我知道这是一个常见问题解答,但我从未见过的一件事就是解释说明为什么repr(3.4)必须是''3.3999999999999999''比

''3.4''?


当然重要的是,等式eval(repr(x))== x必须为浮点数保持
,并且这对于短的
$ b $同样如此b 3.4与17位版本一样吗?

Microsoft .Net的数字格式为R。做类似的工作。 R

说明符保证转换为

字符串的浮点数值将被解析回相同的数值。它通过

首先尝试使用15位精度的通用格式,然后将

解析回一个数字。如果结果与原始结果不同,那么

会回落到17位数值。没有理由为什么Python不能这样做



def float_repr(x):

s =%。15g %x

如果float(s)== x:return s

return"%。17g" %x


这对语言的新手来说会更友好。


-

Duncan Booth < a href =mailto:du **** @ rcp.co.uk> du **** @ rcp.co.uk

int month(char * p){ return(124864 /((p [0] + p [1] -p [2]& 0x1f)+1)%12)[" \\\\\\\\\\\\\\\ b" \\\\\\\\\\\\;}}}谁说我的代码模糊不清?

Entering 3.4 in Python yields 3.3999999999999999.
I know it is due to the fact that 3.4 can not be precisely expressed by the
powers of 2. Can the float handling rules of the underlying layers be set
from Python so that 3.4 yield 3.4?

Thanks,

Károly

解决方案

Ladvánszky Károly wrote:

Entering 3.4 in Python yields 3.3999999999999999.
I know it is due to the fact that 3.4 can not be precisely expressed by
the powers of 2. Can the float handling rules of the underlying layers be
set from Python so that 3.4 yield 3.4?



It seems, from the question, that you might not have entirely understood
and grasped the explanations you can find at:
http://www.python.org/doc/current/tut/node14.html
and I quote, in particular:
"""
no matter how many base 2 digits you''re willing to use, the decimal value
0.1 cannot be represented exactly as a base 2 fraction.
"""
and the same holds for 3.4 for exactly the same reason. As long as
binary is used -- and today''s machines don''t offer options -- that''s it.

Only by using Decimal or Rational fractional numbers would that be possible,
and today''s hardware doesn''t really support them, so you would need to do
everything in software. If you don''t mind the resulting huge slowdown in
computation speed (many apps don''t really do many computations, so don''t
care) there are quite a few packages on the net, though none, AFAIK, which
is considered "ready for production use". The speediest way to do Rational
arithmetic is, I suspect, with gmpy (the mpq type) -- but "speedy" is in
the eye of the beholder. Let me give you an example...:

according to timeit.py, after x=3.4 (a native float), int(x*10) takes
2.46 microseconds; but after x=mpq(3.4) [having imported mpq fm gmpy],
int(x*10) takes 9.72 microseconds! That''s FOUR times slower...

Also, mpq(3.4)''s default representation is as a fraction, 17/5; so,
you would still need some formatting work to display it as 3.4 instead.
Alex


Ladvánszky Károly wrote:

Entering 3.4 in Python yields 3.3999999999999999.
I know it is due to the fact that 3.4 can not be precisely expressed bythe
powers of 2. Can the float handling rules of the underlying layers be set
from Python so that 3.4 yield 3.4?



A float is a float is a float ;)

What can be done is to change the formatting of floats in print
statements, for example. IIRC there was some magic in Python to that
effect that was removed somewhere in the 2.x line.

If you''re concerned about the output, why don''t you just explicitely
format your float numbers? Something like:

print "%.2f" % 3.4


3.40

-- Gerhard


Alex Martelli <al***@aleax.it> wrote in
news:8l**********************@news2.tin.it:

Ladvánszky Károly wrote:

Entering 3.4 in Python yields 3.3999999999999999.
I know it is due to the fact that 3.4 can not be precisely expressed
by the powers of 2. Can the float handling rules of the underlying
layers be set from Python so that 3.4 yield 3.4?



It seems, from the question, that you might not have entirely
understood and grasped the explanations you can find at:
http://www.python.org/doc/current/tut/node14.html
and I quote, in particular:



I know this is an FAQ, but the one thing I''ve never seen explained
satisfactorily is why repr(3.4) has to be ''3.3999999999999999'' rather than
''3.4''?

Surely the important thing is that the equality eval(repr(x))==x has to
hold for floating point numbers, and that holds just as true for the short
3.4 as it does for the 17 digit version?

Microsoft .Net has a numeric format "R" which does a similar job. The R
specifier guarantees that a floating point numeric value converted to a
string will be parsed back into the same numeric value. It does this by
first trying a general format with 15 digits of precision then parsing that
back to a number. If the result is not the same as the original it then
falls back to the 17 digit value. There''s no reason why Python couldn''t do
the same:

def float_repr(x):
s = "%.15g" % x
if float(s)==x: return s
return "%.17g" % x

This would be MUCH friendlier for newcomers to the language.

--
Duncan Booth du****@rcp.co.uk
int month(char *p){return(124864/((p[0]+p[1]-p[2]&0x1f)+1)%12)["\5\x8\3"
"\6\7\xb\1\x9\xa\2\0\4"];} // Who said my code was obscure?


这篇关于精确度问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆