如何计算和存储科学计数法中的数字?

4
我将使用Python来建模统计物理,因此我需要处理小数。例如,
a = 2.22e-300, b = 3e-200

我希望你能计算

a * b = 6.66e-500.

在Python 3中,输出的结果为0.0。
我在考虑设计一个数据类型:第一部分用于存储浮点数,这里是6.66,而第二部分用于存储幂,这里是-500。
请问如何实现?还是有更好的方法处理科学计数法?
2个回答

3

我强烈建议您使用内置的decimal模块,并将其精度提高到您所需的水平。例如:

>>> from decimal import *
>>> getcontext().prec = 100
>>> a = Decimal("2.22e-300")
>>> b = Decimal("3e-200")
>>> a
Decimal('2.22E-300')
>>> b
Decimal('3E-200')
>>> a*b
Decimal('6.66E-500')

请注意,为了保险起见,我使用像“3e-200”这样的字符串创建ab,以便让decimal模块正确解析它们。如果不这样做,它将首先将它们转换为Python的不精确浮点数,然后在将它们传递给Decimal对象之前将它们搞砸。
在上面的代码中,我们将精度设置为100。

3
创建一个类:
class Sci_note:
    def __init__(self, base, exp):
        self.base = base
        self.exp = exp
    def __mul__(self, other):
        return Sci_note(self.base * other.base,
                        self.exp + other.exp)
    def __str__(self):
        return str(self.base) + 'e' + str(self.exp)

它的功能就像你所期望的那样:

>>> a = Sci_note(2.22, -300)
>>> b = Sci_note(3, -200)
>>> c = a * b
>>> c.base
6.66
>>> c.exp
-500

更新

我添加了一个__str__方法(如上),这样打印时它们就能正确显示:

>>> print(a)
2.22e-300

当然,我这里只实现了乘法方法,但是如果需要其他的方法,我会留给你自己去实现。也许你只需要乘法,如果我现在写出其他的方法,那就浪费大家的时间了!

此外,在这里创建一个__float__处理程序也没有用,因为Python无法处理指数为^-300的浮点数,所以将它们返回是无意义的,我们得到的结果只会是0


很棒,你的类比“decimal”库更准确。 - kabanus
@csl 这个程序并没有直接处理诸如“2.22 ^ -300”这样的微小浮点数,它将底数和指数分别存储以避免精度损失。 - Joe Iddon
1
虽然这段代码很整洁,但我不建议任何人编写自己的fixnum类,除非他们有极其特定的需求。 - csl
@kabanus 请详细说明...需要进行什么类型的转换? - Joe Iddon
@csl 这是你的 DV 吗?因为你说你的观点在这里不适用。 - Joe Iddon
显示剩余8条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接