Math 什么';在计算中保持有效数字的最佳方法是什么?

Math 什么';在计算中保持有效数字的最佳方法是什么?,math,Math,假设要从度转换为弧度: radians = degrees * (pi / 180) 如果在该计算中pi被视为常数,则所得弧度值的有效位数应与初始度数相同。即 -32.39 degrees = -0.5653 radians # 4 significant digits -32.38795 degrees = -0.5652763 radians # 7 significant digits 我很惊讶,我找不到任何语言的例子来说明如何执行这个看似简单的操作 我的第一个想法是

假设要从度转换为弧度:

radians =  degrees * (pi / 180)
如果在该计算中pi被视为常数,则所得弧度值的有效位数应与初始度数相同。即

-32.39    degrees = -0.5653 radians     # 4 significant digits
-32.38795 degrees = -0.5652763 radians  # 7 significant digits
我很惊讶,我找不到任何语言的例子来说明如何执行这个看似简单的操作

我的第一个想法是:

degrees_str = degrees
# remove any non-significant leading zeros from degrees_str
# degree_digits = count the remaining digit characters in degrees_str
# radian_int_digits = count the digits in integer portion of the radians
# round radians to (degree_digits - radian_int_digits) digits after the decimal point

这是执行这种一般类型的计算(不特定于度/弧度)的最有效方式吗?

有效数字的概念在计算中没有太大价值,因为计算机不使用十进制数字。有可能-32.39的值以某种方式存储在内部,使其更接近-32.389999999999,而不是-32.39000000000000。

有效数字的概念在计算中没有多大价值,因为计算机不使用十进制数字。值-32.39的内部存储方式可能使其更接近-32.389999999999,而不是-32.39000000000000。

请查看

通常,当应用于计算时,假设所有操作都会导致间隔在最后一个位置扩大一个单位,因此给出了一个悲观的结果

可以根据输入的已知精度设置间隔-如果pi=3.142,则可以使pi恒定于间隔[3.1415,3.1425]

可以根据输入的已知精度设置间隔-如果pi=3.142,则可以使pi恒定于间隔

假设8个sig图用于间隔-间隔的精度比值的精度更高

pi = [3.1415000, 3.1425000].  // pi to 4sf

angle = [-32.385000, -32.395000]. // angle to 4sf

degs_to_rads = pi / 180 // exact constant 180
  = [0.017452776, 0.017458334]. // truncated and widened from [0.0174527778,0.0174583333]

rads = pi * angle / 180 
   = [-0.56556274,-0.56520814] // truncated and widened from [-0.56556273,-0.565208151]

width(rads) = abs(-0.56556274 - (-0.56520814)) = -0.0003546
因此,如果要将RAD格式化为整数sig fig,请选择有效数字,以便间隔上的错误不可见;在这种情况下

sf  min             max
8   -0.56556274     -0.56520814
5   -0.56556        -0.56521 
4   -0.5656         -0.5652
3   -0.566          -0.565
2   -0.57           -0.57
因此,尽管对于已知四位有效数字的输入来说,区间非常小,但结果仅精确到两位

这类似于将结果引用到比所用输入更少的有效数字的常见做法,而不是您给出的假设完美精度的示例。

请看一看

通常,当应用于计算时,假设所有操作都会导致间隔在最后一个位置扩大一个单位,因此给出了一个悲观的结果

可以根据输入的已知精度设置间隔-如果pi=3.142,则可以使pi恒定于间隔[3.1415,3.1425]

可以根据输入的已知精度设置间隔-如果pi=3.142,则可以使pi恒定于间隔

假设8个sig图用于间隔-间隔的精度比值的精度更高

pi = [3.1415000, 3.1425000].  // pi to 4sf

angle = [-32.385000, -32.395000]. // angle to 4sf

degs_to_rads = pi / 180 // exact constant 180
  = [0.017452776, 0.017458334]. // truncated and widened from [0.0174527778,0.0174583333]

rads = pi * angle / 180 
   = [-0.56556274,-0.56520814] // truncated and widened from [-0.56556273,-0.565208151]

width(rads) = abs(-0.56556274 - (-0.56520814)) = -0.0003546
因此,如果要将RAD格式化为整数sig fig,请选择有效数字,以便间隔上的错误不可见;在这种情况下

sf  min             max
8   -0.56556274     -0.56520814
5   -0.56556        -0.56521 
4   -0.5656         -0.5652
3   -0.566          -0.565
2   -0.57           -0.57
因此,尽管对于已知四位有效数字的输入来说,区间非常小,但结果仅精确到两位


这类似于将结果引用到比所用输入更少的有效数字的常见做法,而不是您给出的假设完美精度的示例。

正如Mark Ransom的回答所指出的那样,浮点运算非常复杂。如果您正在编写科学或数学代码,请确保完全理解浮点运算。确保您完全理解IEEE格式,包括非规范化数字,以及精度损失的常见来源。例如取消错误和IEEE数字四舍五入的时间/地点。。。还有机器ε的概念。在我的大学里就有一整门课。。。我敢肯定,这个领域要比这深得多

基本上,IEEE双精度数在尾数中存储53位,这有点像15.9位精度。。。但事实并非如此,因为尾数是以2为基数的,而表示“15.9个有效数字”意味着以10为基数。(log(2^53)约为15.9)总的来说,有效数字的概念在使用IEEE浮点数时根本没有用处。如果你想保持精度,最好对浮点运算有充分的了解


如果您真的需要实现有效数字,请帮自己一个忙,避免使用双精度数字。而是将它们存储为整数。您可能有机会使用以10为基数的IEEE数字,但只有C++0x提到了它们(我还不知道有任何其他编程语言支持小数64位)

正如Mark Ransom的回答所指出的那样,浮点运算很复杂。如果您正在编写科学或数学代码,请确保完全理解浮点运算。确保您完全理解IEEE格式,包括非规范化数字,以及精度损失的常见来源。例如取消错误和IEEE数字四舍五入的时间/地点。。。还有机器ε的概念。在我的大学里就有一整门课。。。我敢肯定,这个领域要比这深得多

基本上,IEEE双精度数在尾数中存储53位,这有点像15.9位精度。。。但事实并非如此,因为尾数是以2为基数的,而表示“15.9个有效数字”意味着以10为基数。(log(2^53)约为15.9)总的来说,有效数字的概念在使用IEEE浮点数时根本没有用处。如果你想保持精度,最好对浮点运算有充分的了解

如果您真的需要实现有效数字,请帮自己一个忙,避免使用双精度数字。而是将它们存储为整数。您可能有机会了解以10为基数的IEEE数字,但只有C++0x提到它们(我不知道还有其他任何支持deci的编程语言)