【问题标题】:High precision arithmetric in Python and/or C/C++?Python和/或C/C++中的高精度算术?
【发布时间】:2011-06-14 00:03:03
【问题描述】:

摘要:哪个 Python 包或 C-Library 是非常高精度算术运算的最佳选择?

我有一些函数可以将小数天 (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 库能够更准确地做到这一点?

【问题讨论】:

  • 这是什么语言? cdef object fractional2hms(...): 在我看来不像 Python。但无论如何:你为什么从双精度开始,然后才将其转换为十进制?如果精度是一个问题,你应该从小数开始,永远不要离开那个领域。
  • @Tim:是的,它是 Cython www.cython.org

标签: c++ python c math precision


【解决方案1】:

CTRL-F "库" 那里:Arbitrary-precision_arithmetic

编辑:仅从 c++ 和 python 的链接库中提取(并删除一些没有浮点数,但只有整数)

蟒蛇

1)mpmath


c++

1) apfloat

2)base one number class

3)bigfloat

4)lidia

5)mapm

6)MIRACL

7) NTL

8) ttmath

【讨论】:

  • @Izz add-Din Ruhulessin,答案可能很有用,你不这么认为吗?如果没有人推荐某个特定的库或说哪个更好,那么您要么随机选择,要么更精确地寻找链接。
  • 嗨,Max,感谢您的回答。重新阅读我的评论,我得出结论,它比我预期的更具敌意。如果我以任何方式冒犯了您,我深表歉意。但是,我将它放在您的编辑之前;您编辑的答案缩小了搜索范围。
【解决方案2】:

差异是由于您的代码中的错误,而不是由于任何准确性问题。线

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

应该是这样的

output += self.nanosecond / d(86400000000000)

此外,在代码中使用浮点文字并将其转换为Decimal 是一个坏主意。这将首先将文字数字四舍五入到浮点精度。后期转换为Decimal 无法恢复丢失的精度。试试

d = decimal.Decimal

并仅使用整数文字(只需删除 .0 部分)。

【讨论】:

  • 谢谢!当然应该是 8.64*10**9。事实上,为此使用整数是一个更明智的解决方案。
猜你喜欢
  • 1970-01-01
  • 2012-08-23
  • 2012-04-01
  • 1970-01-01
  • 1970-01-01
  • 2013-12-28
  • 2010-12-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多