Python 和/或 C/C++ 中的高精度算术?

1 投票
2 回答
1224 浏览
提问于 2025-04-16 10:28

摘要:哪个Python包或C语言库最适合进行高精度的数学运算?

我有一些函数,可以把小数形式的天数(0.0-0.99999..)转换成我们能理解的格式(小时、分钟、秒;更重要的是:毫秒、微秒、纳秒)。

这些函数负责进行转换:

(注意,我还没有实现时区的修正)

d = lambda x: decimal.Decimal(str(x))
cdef object fractional2hms(double fractional, double timezone):
    cdef object total, hms, ms_mult
    cdef int i
    hms = [0,0,0,0,0,0]
    ms_mult = (d(3600000000000), d(60000000000), d(1000000000), d(1000000), d(1000), d(1))
    # hms = [0,0,0,0,0]

    total = d(fractional) * d(86400000000000)
    for i in range(len(ms_mult)):
        hms[i] = (total - (total % ms_mult[i])) / ms_mult[i]
        total = d(total % ms_mult[i])

    return ([int(x) for x in hms])

还有从小数转换回去:

def to_fractional(self):
        output = (self.hour / d(24.0)) + (self.minute / d(1440.0))
        output += (self.second / d(86400.0)) + (self.millisecond / d(86400000.0))
        output += self.microsecond / d(86400000000.0)
        output += self.nanosecond * (d(8.64) * d(10)**d(-9))
        return output

不过,我的前后转换结果并不准确:

jdatetime.DayTime.fromfractional(d(0.567784356873)).to_fractional()
Decimal('0.56779150214342592592592592592592592592592592592592592592592592592592592592592592592592592592592592592592592592592')
# Difference in-out: Decimal('0.000007145270')

当我把d()改成返回普通的Python浮点数时:

# Difference in-out: 7.1452704258900823e-06 (same)

所以,我的问题是:哪个Python包或C语言库能更准确地完成这个任务?

2 个回答

2

在这里按CTRL-F搜索“Libraries”:任意精度算术

编辑:从链接中提取出只适用于C++和Python的库(并去掉一些只处理整数而不处理浮点数的库)

Python

1) mpmath


C++

1) apfloat

2) 基础数字类

3) bigfloat

4) lidia

5) mapm

6) MIRACL

7) NTL

8) ttmath

4

这个问题的原因是你代码里的一个错误,而不是因为精度的问题。那行代码

output += self.nanosecond * (d(8.64) * d(10)**d(-9))

应该改成类似这样的

output += self.nanosecond / d(86400000000000)

而且,直接在代码中使用浮点数(小数)并把它们转换成Decimal是个坏主意。这样做会先把这个小数四舍五入到浮点数的精度。之后再转换成Decimal时,已经失去的精度是无法恢复的。所以,试着

d = decimal.Decimal

只使用整数(也就是把.0部分去掉)。

撰写回答