2009-10-25 2 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() 


Exception Класс:

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

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


Здесь выводится ошибка белый ан вход I число 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

1

Как сказал Нед Батчелдер, не все десятичные числа точно представлены как поплавки. Поплавок представлен определенным количеством двоичных цифр, которые используются для приближения десятичного знака как можно ближе. Вы никогда не можете предположить, что float точно равен десятичной.

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

Как уже сказал в своих ответах, арифметика с плавающей точкой не всегда приводят то, что вы ожидаете, из-за ошибок округления. В этом случае, возможно, лучше конвертировать поплавок в строку и обратно?

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

Как и другие уже указывал, вопрос вы видите из-за неточное представление чисел с плавающей точкой

Попробуйте программу с Пайтоном 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 или десятичную.

 Смежные вопросы

  • Нет связанных вопросов^_^