正如(希望)大多数人所知,浮点运算与实数运算不同。这对初学者来说是不精确的。许多数字,特别是小数(0.1,0.3)无法表示,导致像this这样的问题。可以找到更全面的列表here。
是否有任何通用语言内置支持更接近实数运算的东西?如果没有,那么支持这个的好库是什么?
编辑:任意精度
decimal
数据类型不我正在寻找什么 对于。我希望能够代表 也可以是1/3
,sqrt(3)
或1 + 2i
等数字。
答案 0 :(得分:2)
虽然我讨厌这样说,但Fortran。它广泛支持任意精度算术和大数量计算的大量支持。这是古老而粗俗的,但它完成了工作。
答案 1 :(得分:2)
您的示例中使用的所有数字均为algebraic numbers,并且可以表示 有限地作为具有整数系数的多项式的根。
一般来说,实际数字也不能说同样的,这在一个时很容易看出 认为实数是不可数的,但计算机程序集是 可数。因此,大多数实数在代码中没有有限的表示。
答案 2 :(得分:1)
您正在寻找的是符号计算(MATLAB和数学和工程中使用的其他工具都很擅长)。
如果你想要一个通用的语言,我认为C#中的表达式树是一个很好的开始。从本质上讲,存储表达式(而不是将表达式计算为实际值)的能力是能够执行符号计算的关键。请注意,表达式树不提供符号计算,它只提供支持符号计算的数据结构。
答案 3 :(得分:1)
这个问题很有意思,但提出了一些问题。首先,出于基数原因,您永远无法使用(甚至理论上无限的)计算机来表示所有实数。
您正在寻找的是“符号数字”数据类型。您可以想象某种表达式树,具有预定义的常量,算术运算,以及可能的代数(多项式的根)和超越(exp,sin,cos,log等)函数。
现在是这个故事的有趣部分:你找不到一个算法来判断两个这样的树是否代表相同的数字(或等价地,它测试这样的树是否为零)。我不会说任何精确的,但作为暗示,这类似于停机问题(计算机科学家)或哥德尔不完全性定理(数学家)。
这使得这样的课程变得毫无用处。
对于实数的某些子域,你有规范形式,如有理数的a / b,或有理数的有限代数扩展(a / b + ic / d用于复数有理数,a / b + sqrt(2)* a / b表示Q [sqrt(2)]等。这些可以用来表示一些特定的代数数集。
在实践中,这是您需要的最复杂的事情。如果您有特殊需要,例如浮点数范围(要证明某些结果在指定的时间间隔内,这可能是您最接近实数),或任意精度数,你到处都有免费的课程。 Google boost::range
代表前者,gmp
代表后者。
答案 4 :(得分:1)
有几种语言支持合理和复杂的数字。例如,Scheme支持任意精确的有理数,以及具有有理,浮点或积分系数的复数:
> (+ 1/2 1/3)
5/6
> (* 3 1+1/2i)
3+3/2i
> (+ 1/2 .5)
1.0
如果你想超越有理数的有理数或复数,对sqrt(2)
数字,如{{1}}或封闭式数字如 e ,你可能会必须超越通用编程语言,并使用像Mathematica或Maxima这样的特殊用途数学语言。
答案 5 :(得分:0)
Java:java.math.BigDecimal
C#:decimal
答案 6 :(得分:0)
许多语言都支持:Java有BigDecimal
,Perl有Math::BigFloat
和Math::BigRat
,Haskell有Integer
,列出了很多库和语言在wikipedia。
答案 7 :(得分:0)
Ada本身支持fixed-point数学和浮点数。只要数字的指数保持在范围内,定点就可以比浮点更精确。
如果您需要浮点数,但比IEEE提供的精度更高,那么几乎所有语言都有bignum包。
我认为这是你能做的最好的事情。这两种方案都不能精确地表示重复小数(如1/3)。它可能有可能提出一个方案,但我知道没有语言支持这种内置类型的东西。即使这样也无法帮助你处理无理数(比如pi和e)。我相信甚至有一个定理说,无论你提出什么方案,都会有无法代表的数字。
答案 8 :(得分:0)
编辑:任意精度十进制 数据类型不是我想要的 对于。我希望能够代表 数字,如1/3,sqrt(3)或1 + 2i 同样。
Ruby有一个Rational类,因此1/3可以完全表示为Rational(1,3)。它还有一个Complex类。
答案 9 :(得分:0)
要以任何天赋覆盖实际数字,您需要一个符号包。
Boost,C ++项目,有一个Rational库,但这只是故事的一部分。
你有各种形式的无理数(pi,自然对数的基数,方形和立方根,Champernowne constant,仅举几例)。我知道处理算术运算的唯一方法是一个符号包,其中包含所有这些数字之间关系的智能。假设你可以表达e ^ pi,你会如何添加一个?或者拿它的平方根?
Mathematica可能会处理这些案件。
答案 10 :(得分:0)
Scheme定义有理数,bignums,浮点数和复数。一个实现不需要支持它们,但如果它们存在,你可以混合它们,它们将是“正确的东西”。
答案 11 :(得分:-1)
虽然它不是“内置”,但我认为C ++(也许是C#)是你最好的选择。那里有为此目的编写的课程。