在Python中从数字中提取小数

发布于 2024-08-09 01:02:00 字数 1528 浏览 7 评论 0原文

我正在编写一个函数来从数字中提取小数。忽略异常及其语法,我正在使用 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 时的错误输出:
十进制:0.988
整数:0
小数:9.88
整数:9
小数:98.8
积分:98
十进制:988.0
整数:987
十进制:9880.0
整数:9879
十进制:98800.0
整数:98799
十进制:988000.0
整数:987999
十进制:9880000.0
国际电话:9879999
十进制:98800000.0
国际电话:98799999
十进制:988000000.0
国际电话:987999999
十进制:9880000000.0
国际电话:9879999999
十进制:98800000000.0
国际电话:98799999999
十进制:988000000000.0
国际电话:987999999999
十进制:9.88e+12
国际电话:9879999999999
十进制:9.88e+13
国际电话:98799999999999
十进制:9.88e+14
国际电话:987999999999999
9879999999999998



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

I am writing a function to extract decimals from a number. Ignore the exception and its syntax, I am working on 2.5.2 (default Leopard version). My function does not yet handle 0's. My issue is, the function produces random errors with certain numbers, and I don't understand the reason. I will post an error readout after the code.


Function:

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:

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

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

Here is error output when I input the number 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


I do not know why this error is popping up. Hopefully you guys can help me out.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

烦人精 2024-08-16 01:02:00

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

The problem is that (binary) floating point numbers aren't precisely representable as decimals. See Why can't decimal numbers be represented exactly in binary? for more information.

泪痕残 2024-08-16 01:02:00

正如 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

As Ned Batchelder said, not all decimals are exactly representable as floats. A float is represented by a certain number of binary digits which are used to approximate the decimal as closely as possible. You can never assume a float is exactly equal to a decimal.

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

See http://en.wikipedia.org/wiki/Floating_point for more info on the binary representation of floats.

There are other ways to achieve you goal. Here is one way, using string operations:

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
我不是你的备胎 2024-08-16 01:02:00

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

请使用 Python 的 Decimal 尝试您的程序

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

As others have already pointed out, the issue you are seeing is due to the inexact representation of floating point numbers

Try your program with Python's Decimal

from decimal import Decimal
extractDecimals(Decimal("0.988"))
再浓的妆也掩不了殇 2024-08-16 01:02:00

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

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

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

As has already been said, floating point numbers are not exactly equal to decimals. You can see this by using the modulus operator like so:

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

This gives the remainder of division by 1, or the decimal.

音盲 2024-08-16 01:02:00

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

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

As others have said in their answers, arithmetic with floats doesn't always result in what you expect due to rounding errors. In this case, perhaps converting the float into a string and back is better?

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文