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

我需要找出双精度数的十进制指数.

我一直在研究如何做到这一点,我找到了各种方法.

例如,要估计指数,微软的STL使用interesting lookup table:

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

  // 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位一起扔掉,这似乎是一种浪费.

推荐答案

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

考虑使用IEEE-754二进制64("双精度").设Value为0.09999999999999999167332731531132594682276248931884765625=9.999999999999999167332731531132594682276248931884765625•10−2,,这是一个可表示的值.

0.09999999999999999167332731531132594682276248931884765625的日志(log)10约为?−1.000000000000000036162279995748268157562864421389843161585017393347605917054938808868324457086236340.这个数字不能用二进制64表示;最接近的表示值是−1.

因此,一个好的log10实现将为输入0.09999999999999999167332731531132594682276248931884765625.返回−1

然后,floor((log10(fabs(Value))))会生成−1,但正确的结果应该是−2.

C++相关问答推荐

变量的const视图是否定义良好?

常数函数指针优化

以前版本的tty_ldisc_ops.ioctl()是否也需要文件参数?

ESP32在vTaskDelay上崩溃

在CLANG中调试预处理器宏

理解C版宏(看起来像未声明的变量?)

编译器如何处理具有更复杂值的枚举?

获取前2个连续1比特的索引的有效方法

按长度对argv中的单词进行排序

Wcstok导致分段故障

如果格式字符串的内存与printf的一个参数共享,会发生什么情况?

当我用scanf(&Q;%S%S%S&Q;,单词0,单词1,单词2)输入多个单词时,除了最后一个单词外,每个单词的第一个字符都丢失了

Fscanf打印除退出C代码为1的程序外的所有内容

C编译和运行

在C中打印指针本身

GCC认为这是一个VLA是对的吗?

通过修改c中的合并排序对数组的偶数索引进行排序

10 个字节对于这个 C 程序返回后跳行的能力有什么意义

在 C23 之前如何对空指针使用nullptr?

我如何(合规地)从 tmpfile() 读取?