Math Python.1-.1=带负指数的极小数字?

Math Python.1-.1=带负指数的极小数字?,math,python-2.7,Math,Python 2.7,这一定是一个很好的旅行。定义以下函数foo(): 所以,我知道整数和浮点数的数学可能会有点奇怪。只要输入3-2.9就可以得到这样的答案: >>> 3 - 2.9 0.10000000000000009 所以,公平地说,这并没有引起我正在讨论的剧本中的问题。但这肯定会蔓延并咬到那些实际上会受到像1.3877778e-16这样的天文数字影响的人。为了避免因为这个奇怪的小数字而出现问题,我在控制器的底部放了一块宝石: if (x < .1 and x > 0) or x

这一定是一个很好的旅行。定义以下函数
foo()

所以,我知道整数和浮点数的数学可能会有点奇怪。只要输入
3-2.9
就可以得到这样的答案:

>>> 3 - 2.9
0.10000000000000009
所以,公平地说,这并没有引起我正在讨论的剧本中的问题。但这肯定会蔓延并咬到那些实际上会受到像
1.3877778e-16
这样的天文数字影响的人。为了避免因为这个奇怪的小数字而出现问题,我在控制器的底部放了一块宝石:

if (x < .1 and x > 0) or x < 0:
    x = 0
如果(x<0.1和x>0)或x<0:
x=0

那不可能是解决办法。。。除非完全是这样。所以它是?如果没有,这里的诀窍是什么?

你没有抓住要点-这不是你想要解决的问题。只要相信VM,并假设它完成了所有应该完成的计算

你要做的是格式化你的号码。找出值与其表示形式之间的差异

>>> x = 0.9
>>> while x>0.1:
...     x -= 0.1
... 
>>> x
1.3877787807814457e-16
>>> "{:.2f}".format(x)
'0.00'
这里有一个用2个小数点显示值的示例。更多关于格式(数字格式)的信息,你会发现这肯定会“爬上去咬人”,通常是在人们试图比较浮动时:

>>> a = 1 / 10
>>> b = 0.6 - 0.5
>>> a == b
False
因此,通常使用公差来比较浮动:

>>> tolerance = 0.000001
>>> abs(a - b) < tolerance
True
公差=0.000001 >>>abs(a-b)<公差 符合事实的 此程序:

def foo():
    x = 1
    while x != 0:
        x -= .1
        if x < 0:
            x = 0
        print '%.20f' % x
foo()

您没有以足够的精度打印出数字,以查看实际发生的情况。当您显式地将
x
设置为
0.9
0.8
等时,请将此与打印“%.20f”%x的输出进行比较。您可能需要特别注意
0.5

的结果。不,这不是负数。。。号码的前面没有负号。这是一个“非常小的数字”(实际上是0),然后减去
0.1
…呃。我也知道。这是一个糟糕的标题,我提出了我的问题。负数!=负指数可能使用-引用该页:
“在十进制浮点中,0.1+0.1+0.1-0.3正好等于零。在二进制浮点中,结果是5.5511151231257827e-017。”
就像分数
1/3
不能精确表示为十进制数一样,分数
1/10
不能精确地表示为二进制数——它们都是无限重复的。因此,如果你天真地把数字加起来,你的结果可能是不精确的。如果你“假设它做了所有应该做的计算”,你就生活在罪恶的状态中;浮点数不是实数,将它们视为实数将导致精度低下和类似的问题。您必须了解浮点是如何实现的,以便编写使用它们的合格代码。这条建议完全是错误的。我有一种感觉,“计算机没有出问题,你是”——但我不知道我是否接受这样的观点,即我应该暗中相信计算机所说的一切。哇,我没想到。我有没有说过,它对实数进行过计算?对于您提出的问题,您得到了完全正确的答案—您显式地使用了浮点,所以在浮点操作之后得到了浮点结果。理解你在做什么,并假设在这个领域中,这些计算是正确的——这就是我的意思。计算机并没有欺骗你们——他是一个完全没有创造性的天才,他会根据自己的知识来回答。当你在不理解它的语言的情况下谈论它时,你是在欺骗自己。而且,我发现它很丑陋,试图“修复”结果,仅仅因为你期望一些价值。计算机完成了它的工作,你们应该以可读的形式向用户展示这些结果。现在我想我已经把我的想法解释得很清楚了。再一次,相信虚拟机做了正确的计算意味着不理解它们是如何工作的,而且几乎可以肯定的是,如果你采取更具防御性的工作,那么计算的精度会大大降低。
>>> tolerance = 0.000001
>>> abs(a - b) < tolerance
True
def foo():
    x = 1
    while x != 0:
        x -= .1
        if x < 0:
            x = 0
        print '%.20f' % x
foo()
0.90000000000000002220
0.80000000000000004441
0.70000000000000006661
0.60000000000000008882
0.50000000000000011102
0.40000000000000013323
0.30000000000000015543
0.20000000000000014988
0.10000000000000014433
0.00000000000000013878
0.00000000000000000000