用 GMP 解析十进制值?
Posted
技术标签:
【中文标题】用 GMP 解析十进制值?【英文标题】:Parsing decimal values with GMP? 【发布时间】:2013-03-11 05:15:28 【问题描述】:如何准确解析十进制值?也就是说,我有一个值字符串,比如“43.879”,我希望得到一个准确的 GMP 值。我从文档中不清楚如何,或者这是否真的可能。它似乎不适合整数/有理数/浮点值类型——尽管也许可以玩弄有理数。
我的目的是在加减法等运算中保留精确的小数,但在除法或指数等运算中切换到高精度浮点数。
【问题讨论】:
【参考方案1】:大多数库都可以为您提供任意大的精度,包括 GMP。然而,即使精度很高,也有一些数字不能用二进制格式精确表示,就像你不能用十进制表示 1/3 一样。对于许多应用程序,将精度设置为较高的数字,如 10,进行计算,然后将结果四舍五入回到所需的精度,如 3 作品。它不适合你吗?看到这个 - Is there a C++ equivalent to Java's BigDecimal?
你也可以使用http://software.intel.com/en-us/articles/intel-decimal-floating-point-math-library
********* 编辑
二进制浮点数中不存在许多数字的精确表示;大多数当前浮点库提供的那种。无论精度如何,像 0.1 这样的数字都不能表示为二进制数。
为了能够执行您建议的操作,图书馆必须执行相当于“手动加法”、“手动除法”的操作 - 您在铅笔和纸上添加两个十进制数的那种操作。例如为了存储 0.1,库可能选择将其表示为字符串本身,然后对字符串进行添加。不用说,一个幼稚的实现会使这个过程变得非常缓慢——慢几个数量级。要添加 0.1 + 0.1,它必须解析字符串、添加 1+1、记住进位、记住小数位等。这就是计算机微代码在几个 CPU 周期(或一条指令)内为您所做的事情.您的软件库最终会占用大约 100 个 CPU 周期/指令,而不是单条指令。
如果它试图将 0.1 转换为数字,则返回到平方 1 - 0.1 不能是二进制数字。
但是,人们确实认识到准确表示 0.1 的必要性。只是二进制数表示不会这样做。这就是更新的浮点标准出现的地方,也是英特尔小数点库的发展方向。
重复我之前的示例,假设您有一台可以计算 10 个基数的 10 个基数的计算机。该计算机无法将 1/3 存储为“普通”浮点数。它必须存储数字为 1/3 的表示。相当于它是如何写在纸上的。尝试在纸上写下 1/3 作为基数为 10 的浮点数。
另见Why can't decimal numbers be represented exactly in binary?
【讨论】:
是的,我明白这一点。我只想准确地表示从十进制形式的字符串中解析的数字。保证必须存在精确的表示形式,可以是有理数,也可以是整数乘以十的幂。我只是想知道如何在 GMP 中解析该数字(因为理性没有公开这样的解析器)。 二进制浮点中不存在许多数字的精确表示;大多数当前浮点库提供的那种。无论精度如何,像 0.1 这样的数字都不能表示为二进制数。然而,人们确实认识到准确表示 0.1 的必要性。只是二进制数表示不会这样做。这就是更新的浮点标准出现的地方,也是英特尔小数点库的发展方向。 GMP 有一个“有理”类,其中 0.1 可以精确地表示为 1/10。我正在寻找一种将十进制数解析为该形式的标准方法(假设有理是正确的形式)。 那你为什么不直接从输入字符串中删除小数点,“记住”小数点在哪里,然后从中创建一个有理数呢? 1.23 = 123/100。 10-15行代码。但如果你做理性,你就会变得理性。您将获得 0.1 的 1/10。当你试图从 1/10 中得到 0.1 时,你又回到了开始的地方。重复——你可以在纸上写下 1/3。但是,例如你不能把 1/3 美元还给别人;你不能——不能不四舍五入;即使您有无限的进一步细分,也不会。 Dollar 正在以 10 为基数工作,以 10 为基数没有任何内容可以代表 1/3。以上是关于用 GMP 解析十进制值?的主要内容,如果未能解决你的问题,请参考以下文章
无法解析在 Windows Phone 上使用非英文键盘输入的十进制数