3

正如(希望)你们大多数人都知道,浮点运算不同于实数运算。对于初学者来说,这是不精确的。许多数字,尤其是小数 (0.1, 0.3) 无法表示,导致这样的问题。可以在此处找到更详尽的列表。

有没有内置支持更接近实数算术的通用语言?如果没有,有什么好的库支持这个?

编辑:任意精度decimal 数据类型不是我想要的。我希望能够表示数字,如1/3,sqrt(3)1 + 2i

4

12 回答 12

2

虽然我不想这么说,Fortran。它广泛支持任意精度算术和大量支持大数计算。它既古老又粗俗,但它完成了工作。

于 2010-09-17T16:56:45.543 回答
2

您的示例中使用的所有数字都是代数数,并且可以有限地表示为具有整数系数的多项式的根。

对于一般的实数则不能这样说,当人们认为实数不可数时很容易看出这一点,但计算机程序的集合是可数的。因此,大多数实数在代码中不会有有限表示。

于 2010-09-17T17:18:16.317 回答
1

您正在寻找的是符号计算(MATLAB 和其他用于数学和工程的工具都擅长它)。

如果您想要一种通用语言,我认为 C# 中的表达式树是一个很好的起点。本质上,存储表达式的能力(而不是将表达式计算为实数值)是能够执行符号计算的关键。注意表达式树不提供符号计算,它只提供支持符号计算的数据结构。

于 2010-09-17T17:26:46.397 回答
1

这个问题很有趣,但也引发了一些问题。首先,出于基数的原因,您将永远无法使用(甚至理论上无限的)计算机来表示所有实数。

您正在寻找的是“符号数字”数据类型。您可以想象某种表达式树,具有预定义的常量、算术运算,也许还有代数(多项式的根)和超越(exp、sin、cos、log 等)函数。

现在故事的有趣部分:你找不到一个算法来判断两个这样的树是否代表相同的数字(或等效地,它测试这样的树是否为零)。我不会说任何精确的东西,但作为一个提示,这类似于停止问题(对于计算机科学家)或哥德尔不完全定理(对于数学家)。

这使得这样的类非常无用。

对于实数的某些子域,您有规范形式,例如有理数的 a/b,或有理数的有限代数扩展(复数有理数的 a/b + ic/d,a/b + sqrt(2) * a/ b 代表 Q[sqrt(2)] 等)。这些可用于表示某些特定的代数数集。

实际上,这是您需要的最复杂的事情。如果您有特殊需要,例如浮点数范围(为了证明某些结果在指定区间内,这可能是您可以获得的最接近实数)或任意精度数,您可以在任何地方免费使用类。谷歌boost::range前者,gmp后者。

于 2010-09-17T17:43:21.387 回答
1

有几种语言支持有理数和复数。例如, Scheme支持任意精确的有理数,以及具有有理数、浮点数或整数系数的复数:

> (+ 1/2 1/3)
5/6
> (* 3 1+1/2i)
3+3/2i
> (+ 1/2 .5)
1.0

如果您想超越有理数或具有有理系数的复数,进入诸如e之类的代数sqrt(2)或封闭形式的数字,您可能不得不超越通用编程语言,并使用特殊用途的数学语言,如 Mathematica 或千里马。

于 2010-09-17T19:08:14.523 回答
0

爪哇:java.math.BigDecimal

C#:decimal

于 2010-09-17T16:58:51.503 回答
0

很多语言都支持这一点:Java 有BigDecimal,Perl 有Math::BigFloatMath::BigRatHaskell 有,维基百科Integer中列出了很多库和语言。

于 2010-09-17T17:01:13.043 回答
0

Ada 原生支持定点数学和浮点数。只要数字的指数保持在范围内,定点就可以比浮点更精确。

如果您需要浮点,但比 IEEE 提供的精度更高,那么几乎每种语言都有 bignum 包。

我认为这是你能做的最好的事情。这两种方案都不能准确地表示重复的小数(如 1/3)。可能会提出一个可行的方案,但我知道没有一种语言支持这种内置类型的东西。即使这样对无理数(如 pi 和 e)也无济于事。我相信甚至有一个定理说总会有不可表示的数字,无论你想出什么方案。

于 2010-09-17T17:03:23.380 回答
0

编辑:任意精度十进制数据类型不是我要找的。我也希望能够表示 1/3、sqrt(3) 或 1 + 2i 等数字。

Ruby 有一个 Rational 类,所以 1/3 可以精确地表示为 Rational(1,3)。它还有一个 Complex 类。

于 2010-09-17T17:24:44.157 回答
0

要以任何风格覆盖实数,您需要一个符号包。

C++ 项目 Boost 有一个Rational库,但这只是故事的一部分。

您有各种形式的无理数(pi、自然对数的底、平方根和立方根、尚珀诺讷常数,仅举几例)。我所知道的处理算术运算的唯一方法是一个符号包,它对所有这些数字之间的关系具有智能。假设你可以表达 e^pi,你会怎么加一个呢?还是取它的平方根?

Mathematica 可能会处理这些情况。

于 2010-09-17T17:35:15.287 回答
0

Scheme定义了有理数、大数、浮点数和复数。不需要实现来支持所有这些,但如果它们存在,您可以混合它们,它们将“正确”。

于 2010-09-17T17:35:58.553 回答
-1

虽然它不是“内置的”,但我认为 C++(也许是 C#)是你最好的选择。为此目的编写了一些课程。

http://www.oonumerics.org/oon/

于 2010-09-17T17:04:10.540 回答