2009-10-25 47 views
1

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


功能:

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.' 


这里是误差输出WH恩我输入数字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



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

回答

5

问题是(二进制)浮点数不能精确地表示为小数。有关更多信息,请参阅Why can't decimal numbers be represented exactly in binary?

+0

感谢所有人的帮助。正如你们所指出的那样,我可以更好地完成这个项目,但是我对结果并不感兴趣,并且对我一路上学到的东西更感兴趣。这就是为什么我不使用Python的所有内置功能的原因之一。感谢您的答案。 – dbmikus 2009-10-25 16:25:15

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 
0

正如其他人在他们的回答说,算术花车并不总是导致你期望由于舍入误差。在这种情况下,可能将float转换为字符串并返回更好?

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 
1

正如其他人已经指出,你所看到的问题是由于浮点数

的不精确表示

与Python的Decimal

from decimal import Decimal 
extractDecimals(Decimal("0.988")) 
1

试试你的程序前面已经说,浮点数不完全等于小数。你可以通过使用如下的模数运算符来看到这一点:

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

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