为什么System.Math和例如MathNet.Numerics基于double?

Svi*_*ish 7 c# math double decimal

System.Math中的所有方法都double作为参数并返回参数.常量也是类型double.我检查了MathNet.Numerics,在那里似乎也是如此.

为什么是这样?特别是对于常数.不decimal应该更准确吗?在进行计算时,这通常不会有用吗?

Joh*_*zen 16

这是一种经典的速度与准确性权衡.

但是,请记住,对于PI,例如,您需要的最多数字是41.

你需要的pi的最大位数是41.要计算宇宙的周长,误差小于质子的直径,你需要41位数的pi†.对于您可能遇到的任何圆测量问题,41个数字在pi中的准确度是足够的,这似乎是安全的.因此,在2002年计算的超过一万亿个数字的pi中,超过41个的所有数字都没有实际价值.

另外,decimal和double的内部存储结构略有不同.十进制设计用于存储基数为10的数据,其中使用双精度数(和浮点数)来保存二进制数据.在二进制机器上(就像现有的每台计算机一样),当在其范围内存储任何数字时,double将减少浪费的比特.

还要考虑:

System.Double      8 bytes    Approximately ±5.0e-324 to ±1.7e308 with 15 or 16 significant figures
System.Decimal    12 bytes    Approximately ±1.0e-28 to ±7.9e28 with 28 or 29 significant figures

如您所见,decimal的范围较小,但精度较高.

  • 对圆周率数字的有趣分析,但恰恰相反:如果我想要测量的不是绕宇宙一圈所需的质子数,而是填充宇宙体积所需的夸克数,该怎么办?宇宙?宇宙正在膨胀,那么我们需要多长时间才能需要 42 位数字呢? (2认同)

Cha*_*ana 5

不, - 小数并不比双打更“精确”,或者就此而言,任何类型。“精确性”的概念(当谈到计算机中的数字表示时)是错误的。任何类型在表示某些数字时绝对 100% 准确。无符号字节在表示从 0 到 255 的整数时 100% 准确。但它们不适用于分数或范围外的负数或整数。

小数在表示一组特定的以10底的值时100% 准确。doubles(因为它们使用二进制IEEE 指数表示存储它们的值)精确地表示一组二进制数。一般来说,两者都不比另一个更精确,它们只是用于不同的目的。

进一步详细说明,因为我对某些读者来说似乎不够清楚......

如果你取每一个可表示为小数的数,并将它们中的每一个都标记在数轴上,那么在它们的对相邻对之间都有一个额外的无穷大实数,它们不能表示为小数。对于可以表示为双精度数的数字,可以做出完全相同的声明。如果您将数轴上的每个小数标记为蓝色,将每个双精度数标记为红色,除了整数,将很少有地方用两种颜色标记相同的值。一般来说,对于 99.99999% 的分数,(请不要挑剔我的百分比)蓝色组(小数)与红色组(双打)完全不同。

这是因为根据我们对蓝色集合的定义,它是一个以 10 为底的尾数/指数表示,而 double 是一个以 2 为底的尾数/指数表示。任何表示为以 2 为底的尾数和指数(1.00110101001 x 2 ^ (-11101001101001)的值,意味着取尾数值 ( 1.00110101001) 并将其乘以 2 的指数次方(当指数为负时,这相当于除以 2 的绝对值的次方)指数)。这意味着当指数为负时(或尾数的任何部分是二进制小数部分),该数字不能表示为十进制尾数和指数,反之亦然。

对于任何随机落在实数轴上的任意实数,它要么更接近蓝色小数之一,要么更接近红色双精度数之一。

  • 这不是学究周杰伦。这低于您*需要*理解的最小值,以便准确有效地进行浮点数学运算。doubles 的目的是实现物理量的快速计算,其中表示误差远小于测量误差;理解这一点至关重要。 (7认同)
  • @布鲁诺。这根本不是废话。如果你把每一个可表示为小数的数都取到它们的每一对相邻的对之间,就会有无穷多个不能表示为小数的实数。双打也是如此。但这些是完全不同的数字集。对于随机落在实数轴上的任意实数,它要么更接近一位小数,要么更接近一位双打。 (5认同)
  • @Jay,在数学上,确实有确切的数字。在现实世界中,我们只能“测量”到一定精度的真实事物。然而,一旦有人开始谈论准确性,您所测量的任何事物的实际价值就会发挥作用。并且“真实”用户不使用十进制值,他们测量真实的事物。真实的东西不是十进制或二进制的。它们具有真正的价值。无论真实值是什么,最接近的二进制表示形式或最接近的十进制表示形式是否更接近实际真实值,这是一个折腾。 (3认同)
  • @Charles:“对于任何随机落在实数线上的任意实数,它要么更接近蓝色小数之一,要么更接近红色双打之一。” 嗯,实际上没有。任何可以精确表示为二进制分数的数字也可以精确表示为十进制分数,但反之则不然。将每个表示为素数的乘积:2=2(足够简单),10=2*5。取任何二进制分数,表示为 x/2^n,乘以 5^n/5^n 即可转换为十进制分数。但是如果十进制小数的分子... (3认同)
  • @Charles:我没有说“数学中”没有确切的数字。我说没有“精确的测量”。如果你问我,“你办公桌上的抽屉里有多少图钉?” 我可以给你一个确切的答案,因为这是计数而不是测量。但是如果你问我这些图钉有多少重量,我只能给出一定程度的精确度。更好的量表可以给出更精确的答案。如果我说它们的重量是 232.7 克,那么更好的秤可能会说它更接近 232.749 克,等等。这显然不是正确的计数:(继续......) (2认同)
  • (续)不能被 5^n 整除。因此,例如二进制 .1 = 十进制 .5、二进制 .01 = 十进制 .25、二进制、二进制 .001 = 十进制 .125 等。但是十进制 .1 ... 马上就没有确切的二进制等效项。如果您比较两个相对质数的碱基,例如基数 10 和基数 3,那么您的陈述将是正确的。 (2认同)