任意精度的数

当对任意精度的数进行计算时,Wolfram 语言在各处都保持对精度的跟踪. 一般,Wolfram 语言将尽力给出可能的最高精度,给出用户的输入具有的精度.

Wolfram 语言把任意精度数处理为量的值,这个量的某些位是已知的,某些位是未知的. 一般,任意精度数 x 的由Precision[x] 给出的位数是已知的,后面的无穷位是完全不知道的.

这里计算 ,尽力得到10位精度.
In[1]:=
Click for copyable input
Out[1]=
在某一点之后,所有数位都未定.
In[2]:=
Click for copyable input
Out[2]=

当用户进行计算的时候,Wolfram 语言记录在用户的结果中任何可能受到输入中未知数位影响的数位. 它设置了结果的精度,以使任何被影响的数位不被包括在内. 这个过程确保由 Wolfram 语言返回的数字是正确的,无论未知数位的取值如何.

这里计算 ,尽力得到30位精度.
In[3]:=
Click for copyable input
Out[3]=
在上述情况下,结果有准确的30位精度.
In[4]:=
Click for copyable input
Out[4]=
如果输入只有很小的精度,那么 Wolfram 语言不能给出那样高精度的输出.
In[5]:=
Click for copyable input
Out[5]=
如果想要 Wolfram 语言假定参数是精确 ,那么必须明确表示它.
In[6]:=
Click for copyable input
Out[6]=

在许多计算中所得结果的精度因舍入误差而降低. 一个典型的情况是两个很接近的数进行相减,所得结果依赖于每个数的高阶位. 并且结果的精度比原来数的精度低的多.

两个输入数都有20位的精度,但结果的精度低的多.
In[7]:=
Click for copyable input
Out[7]=
在一个数中添加一些位而另一个数中不添加,这样不能使添加的位在结果中表现出来.
In[8]:=
Click for copyable input
Out[8]=

函数输出的精度以一个复杂的方式依赖于输入的精度. 变化得快的函数,其输出精度较低,这是因为与输入中的不确定性有关的输出变化是更大的. 而接近于常数的函数给出的输出其精度比输入的更高.

像Sin这样的变化很快的函数,其输出的精度比其输入的精度低.
In[9]:=
Click for copyable input
Out[9]=
这是计算到20位精度的 .
In[10]:=
Click for copyable input
Out[10]=
所得结果与整数 相加,给出更高的精度.
In[11]:=
Click for copyable input
Out[11]=

值得注意,以不同方式进行同一运算所得结果的精度是不大相同的. 通常,在计算中,一旦损失了精度,它是不可能恢复的. 精度的损失就是有关信息的丢失.

这是接近于1的40位数.
In[12]:=
Click for copyable input
Out[12]=
其与 相加得出另一个40位数.
In[13]:=
Click for copyable input
Out[13]=
最初的精度一直被保持.
In[14]:=
Click for copyable input
Out[14]=
这种方式计算 将损失精度.
In[15]:=
Click for copyable input
Out[15]=
这种方式得出的结果精度相当低.
In[16]:=
Click for copyable input
Out[16]=

以不同方式进行同一运算所得结果的精度不同意味着,其中包括两个近似实数间的比较必须谨慎处理. 在测试两个实数是否相等时,Wolfram 语言先求出二者之差,并检测结果是否在给定的精度内与0一致.

这两个数在给定的精度内是相等的.
In[17]:=
Click for copyable input
Out[17]=

Wolfram 语言用于计算数学函数的内部算法被设计来保持尽可能高的精度. 大多数情况下,Wolfram 语言内部函数给出结果的精度与输入的精度很接近. 但在有些情况下,做不到这一点,Wolfram 语言将给出较低精度的结果. 如果输入的精度较高,Wolfram 语言在内部计算中将使用较高的精度. 并且通常能给出较高精度的结果.

N[expr]计算 expr ,给出机器精度的结果
N[expr,n]数值计算 expr ,得到 n 位精度的结果

数值计算.

如果表达式仅包含整数和精确数值量,那么 N[expr,n] 在所有情况下都给出 n 位精度的结果. 应该认识到,要做到这一点,Wolfram 语言有时必须执行更高精度的内部中间运算.

全局变量 $MaxExtraPrecision 指定在中间计算中,允许多少额外的数位.

变量
默认值
$MaxExtraPrecision50使用的最大额外精度

控制中间计算的精度.

为了得到正确答案,Wolfram 语言自动增加内部运算的精度.
In[18]:=
Click for copyable input
Out[18]=
使用默认设置 $MaxExtraPrecision=50,Wolfram 语言不能得到正确答案.
In[19]:=
Click for copyable input
Out[19]=
告诉 Wolfram 语言在内部计算中用更多的位.
In[20]:=
Click for copyable input
Out[20]=
现在得到了正确答案.
In[21]:=
Click for copyable input
Out[21]=
$MaxExtraPrecision 重新设置为默认值.
In[22]:=
Click for copyable input
Out[22]=

甚至在做给出精确结果的计算时,Wolfram 语言仍然偶尔使用某些内部运算中的近似数,以使 $MaxExtraPrecision 的值能发挥作用.

在近似数的精度内,Wolfram 语言求出结果.
In[23]:=
Click for copyable input
Out[23]=
$MaxExtraPrecision 的默认值下,Wolfram 语言不能给出此式的结果.
In[24]:=
Click for copyable input
Out[24]=
重设 $MaxExtraPrecision,使 Wolfram 语言得出结果.
In[25]:=
Click for copyable input
Out[25]=

在进行降低精度的计算中, 我们有可能最终得到不具有任何有效数位的数字. 但即使在这种情况下,Wolfram 语言仍然保持数字的准确度信息. 给出一个不具有有效数位但具有准确度a 的数字,Wolfram 语言仍然可以告诉我们该数的实际值一定位于区间 之间. 默认情况下,Wolfram 语言以 的形式显示该这样的数.

这是一个计算到20位精度的数.
In[26]:=
Click for copyable input
Out[26]=
这里没有留下任何有效数位.
In[27]:=
Click for copyable input
Out[27]=
但是 Wolfram 语言仍然保持结果的准确度.
In[28]:=
Click for copyable input
Out[28]=
对结果加上精确的 将生成具有相当高精度的数.
In[29]:=
Click for copyable input
Out[29]=

用数字的精度为特征的一个微妙之处在于任何与零一致的数都必须被视为具有零精度. 这样做的理由是这样一个数没有任何可以被视为有效位的数位,因为它所有已知的数位刚好是零.

这里给出一个值一致为零的数.     
In[30]:=
Click for copyable input
Out[30]=
该数没有可识别的有效精度.
In[31]:=
Click for copyable input
Out[31]=
但它仍具有一定的准确性,刻画了它的不确定性的特点.
In[32]:=
Click for copyable input
Out[32]=

如果您的计算结果很可能接近零,可以方便地指定用户想获得的准确度,而不是精度.

N[expr,p]计算 expr,得到 p 位精度的结果
N[expr,{p,a}]计算 expr,得到最多 p 位精度和 a 位准确度的结果
N[expr,{Infinity,a}]计算 expr,得到任意精度和 a 位准确度的结果

指定准确度以及精度.

下面是一个符号表示的表达式.
In[33]:=
Click for copyable input
Out[33]=
这里表明该表达式等于零.
In[34]:=
Click for copyable input
Out[34]=
N 不能确保获得精度为20的结果.
In[35]:=
Click for copyable input
Out[35]=
但是它能获得准确度为20的结果.
In[36]:=
Click for copyable input
Out[36]=

当 Wolfram 语言在任意精度的未知位的潜在影响下工作时,它缺省地假定这些位在不同的数中是完全无关的. 但这个假定不可能产生很高的精度,它能导致不必要的精度损失.

特别,在一个计算中,如果两个数以同样的方式生成时,它们的一些未知位可能是相等的. 那么当二者相减时,未知位可以相消. 但是在未知位总是无关的假定下,Wolfram 语言将丢失这样的相消.

这是一个计算到20位精度的数.
In[37]:=
Click for copyable input
Out[37]=
有34位精度.
In[38]:=
Click for copyable input
Out[38]=
这个量具有较低的精度,因为 Wolfram 语言假定每个 中的未知位是无关的.
In[39]:=
Click for copyable input
Out[39]=

数值计算有时依赖不同数的未知位间的相消而产生较高精度的结果. 如果能确定未知位最终相消,那么用户可以明显地在未知位处引入任意数字,在整个运算中使用这些任意数字,然后将它们消去,并得到更高精度的结果.

SetPrecision[x,n]产生具有 n 位精度的十进制数,如果有必要的话,使用二进制的零填充
SetAccuracy[x,n]产生具有 n 位准确度的十进制数

用来修改精度和准确度的函数.

这里给 增加了10个任意的数字.
In[40]:=
Click for copyable input
Out[40]=
这里增加的位数被消去.
In[41]:=
Click for copyable input
Out[41]=
现在,结果的精度是44位,而不是34位.
In[42]:=
Click for copyable input
Out[42]=

SetPrecision 通过在二进制添加0来增加精度. 有时,Wolfram 语言在任意精度数中存贮的位数多于显示出来的位数,此时,SetPrecision 将在使用完这些额外的位数后再添加零.

设置一个数具有40位精度. 额外的位来自二进制到10进制进行的换算.
In[43]:=
Click for copyable input
Out[43]=
变量
默认值
$MaxPrecisionInfinity使用的最大总精度
$MinPrecision0使用的最小精度

全局精度控制参数.

给出全局赋值 $MinPrecision=n,用户能在计算的每步有效地使用 SetPrecision[expr,n]. 这意味着既使任意精度数种的正确位数变得低于n,该数将总是被添加到 n 位精度.

如果设置 $MaxPrecision=n 以及 $MinPrecision=n,那么能迫使所有的任意精度数有固定的 n 位精度. 结果,这使 Wolfram 语言像处理机器精度数一样处理任意精度数,但是有更高的精度.

固定精度计算使某些计算效率更高. 但是如果不仔细分析,将不能确定所得结果有多少位是正确的.

这是具有20位精度的很小的数.
In[44]:=
Click for copyable input
Out[44]=
在 Wolfram 语言通常的算法下,此式能被很好的计算.
In[45]:=
Click for copyable input
Out[45]=
这里让 Wolfram 语言使用固定精度算法.
In[46]:=
Click for copyable input
Out[46]=
结果的前几位是正确的,但其余的是错误的.
In[47]:=
Click for copyable input
Out[47]=