快速准确地计算double的小数指数

问题描述 投票:0回答:1

编辑:澄清一下,“双精度数的十进制指数”是指值的大小或值的以 10 为底的指数。例如 3456.7 -> 3.4567E3 -> 科学指数 = 3

我需要找到双精度数的十进制指数。

我一直在研究实现此目的的方法,并且找到了各种方法。

例如,为了估计指数,Microsoft 的 STL 使用一个有趣的查找表

但是,我想出的方法似乎是最简单的:

  // v -> value
  // x -> ScientificExponent
  // 10^x <= v < 10^(x+1)
  // x <= log(v) < x+1

  ScientificExponent = (Value == 0) ? 1 : floor((log10(fabs(Value))));

我想知道为什么不使用它。有没有这种方法不起作用的情况?这是否被认为太慢了?

是否有任何我没有考虑的边缘/角落情况(可能次正常值太小而无法获得准确的对数计算)?

我很感激人们能够提供的任何见解。

另外,如果这是一个好方法,那么有没有一个好方法只计算 log10 的整数部分?将日志计算到许多小数位然后将其与

floor
一起丢弃似乎是一种浪费。

c performance math double
1个回答
1
投票

floor((log10(fabs(Value))))
不足以计算数字的十进制指数。

考虑使用 IEEE-754 二进制 64(“双精度”)。设

Value
为 0.09999999999999999167332731531132594682276248931884765625 = 9.999999999999999916733273153113259468227624893188 4765625•10−2,这是一个可表示的值。

0.09999999999999999167332731531132594682276248931884765625 的

log10 大约为 ?−1.000000000000000036162279995748268157562864 421389843161585017393347605917054938808868324457086236340。这个数字不能用binary64表示;最接近的可表示值为−1。

因此,一个好的

log10
实现将为输入0.099999999999999999167332731531132594682276248931884765625返回−1。

然后

floor((log10(fabs(Value))))
产生 -1,但正确的结果将是 -2。

© www.soinside.com 2019 - 2024. All rights reserved.