1

我正在编写一个从数字中提取小数的函数。忽略异常及其语法,我正在使用 2.5.2(默认 Leopard 版本)。我的函数还不能处理 0。我的问题是,该函数会产生具有某些数字的随机错误,我不明白原因。我将在代码之后发布错误读数。


功能:

def extractDecimals(num):
    try:
        if(num > int(num)):
            decimals = num - int(num)
            while(decimals > int(decimals)):
                print 'decimal: ' + str(decimals)
                print 'int: ' + str(int(decimals))
                decimals *= 10
            decimals = int(decimals)
            return decimals
        else:
            raise DecimalError(num)
    except DecimalError, e:
        e.printErrorMessage()


异常类:

class DecimalError(Exception):
    def __init__(self, value):
        self.value = value

    def printErrorMessage(self):
        print 'The number, ' + str(self.value) + ', is not a decimal.'


这是我输入数字 1.988 时的错误输出:
decimal: 0.988
int: 0
decimal: 9.88
int: 9
decimal: 98.8
int: 98
decimal: 988.0
int: 987
decimal: 9880.0
int: 9879
decimal: 98800.0
int: 98799
decimal: 988000.0
int: 987999
decimal: 9880000.0
int: 9879999
decimal: 98800000.0
int: 98799999
decimal: 988000000.0
int: 987999999
decimal: 9880000000.0
int: 9879999999
decimal: 98800000000.0
int: 98799999999
decimal: 988000000000.0
int: 987999999999
decimal: 9.88e+12
int: 9879999999999
decimal: 9.88e+13
int: 98799999999999
decimal: 9.88e+14
int: 987999999999999
9879999999999998



我不知道为什么会弹出这个错误。希望你们能帮助我。

4

5 回答 5

5

问题是(二进制)浮点数不能精确地表示为小数。请参阅为什么不能用二进制精确表示十进制数?了解更多信息。

于 2009-10-25T02:58:02.180 回答
1

正如 Ned Batchelder 所说,并非所有小数都可以精确地表示为浮点数。浮点数由一定数量的二进制数字表示,这些数字用于尽可能接近十进制。您永远不能假设浮点数完全等于小数。

In [49]: num
Out[49]: 1.988

In [50]: decimals=num - int(num)

In [51]: decimals
Out[51]: 0.98799999999999999

In [52]: print decimals   # Notice that print rounds the result, masking the inaccuracy.
0.988

有关浮点数的二进制表示的更多信息,请参见http://en.wikipedia.org/wiki/Floating_point

还有其他方法可以实现您的目标。这是一种使用字符串操作的方法:

def extractDecimals(num):
    try:
        numstr=str(num)
        return int(numstr[numstr.find('.')+1:])
    except ValueError, e:
        print 'The number, %s is not a decimal.'%num
于 2009-10-25T03:07:43.550 回答
1

正如其他人已经指出的那样,您看到的问题是由于浮点数的不精确表示

用 Python 试试你的程序Decimal

from decimal import Decimal
extractDecimals(Decimal("0.988"))
于 2009-10-25T03:24:10.240 回答
1

正如已经说过的,浮点数并不完全等于小数。您可以通过使用模数运算符来看到这一点,如下所示:

>>> 0.988 % 1
0.98799999999999999
>>> 9.88 % 1
0.88000000000000078
>>> 98.8 % 1
0.79999999999999716

这给出了除以 1 或小数的余数。

于 2009-10-25T03:31:02.347 回答
0

正如其他人在回答中所说的那样,由于舍入误差,浮点算术并不总是会产生您所期望的结果。在这种情况下,也许将浮点数转换为字符串并返回更好?

In [1]: num = 1.988

In [2]: num_str = str(num)

In [3]: decimal = num_str.split('.')[1]

In [4]: decimal = int(decimal)

In [5]: decimal
Out[5]: 988
于 2009-10-25T03:23:31.847 回答