【问题标题】:Number Of Digits in Fractional Portion of Float/DoubleFloat/Double 小数部分的位数
【发布时间】:2013-01-06 04:19:56
【问题描述】:

我正在尝试实现http://www.exploringbinary.com/correct-decimal-to-floating-point-using-big-integers/

我已经读了好几遍了,感觉很舒服。第一步是假设值是字符串格式。我的实现是假设值是双精度格式。

是否可以获得构成 float/double 小数部分的位数?

例如值 3.24325(我希望不能用二进制精确表示,因为我只是随机选择的)。我想知道小数部分是 5 位长,以便我可以继续使用上面链接中的算法。

使用modf 之类的东西乍一看似乎是正确的小数值,但实际上是四舍五入的(假设小数部分不能以二进制精确表示)。从原始值中减去原始值的类型转换 int 会导致相同的四舍五入的小数。使用 sprintf 将值记录在字符串中会导致类似的问题(我相信),但我没有足够的时间来确认 - 我刚刚开始使用它。

上面链接中算法的第1步有解决方案吗?

谢谢。

【问题讨论】:

  • 您可能对this answer感兴趣。
  • 如您所知,双精度值不能为 3.24325。最接近的通常是 3.243250000000000188293824976426549255847930908203125。当给定这个值时,你希望你的程序做什么?它是否应该认为所有数字都是正确的,它被赋予了它应该工作的确切值?或者它是否应该认为应该只使用前十位数字,给出的值应该四舍五入到小数点后 10 位(从小数点开始计算)或可能到 11 位有效数字(从第一位数字开始计算)或其他?
  • 我不明白。如果您的输入已经是双精度,为什么还需要使用“转换为双精度”算法?
  • @RickRegan 我试图将此算法用作从双精度格式转换为不同双精度格式的指南。从那以后,我意识到这种方法太过分了,对我所做的事情来说是不必要的。

标签: c floating-point floating-accuracy ieee-754


【解决方案1】:

一种选择是使用sprintfstrchr。下面是一个例子:

int main() {
    double d = 3.24325;
    char str[20];
    sprintf(str, "%.10f", d); 
    puts(str); 
    int digits = strchr(str, '0') - strchr(str, '.') - 1;
    printf("%d", digits);
}

输出

3.2432500000
5

在上面的代码中,strchr搜索.和(首尾)0的位置,并据此计算位数。为简单起见,我在%.10f 后面附加了一些额外的0s。您可以通过比较 strchr 是否返回指向字符串末尾的指针来调整没有尾随 0 的情况的计算。

【讨论】:

    【解决方案2】:

    以下是解决问题的幼稚方法。在大多数情况下,这是可行的,但浮点整数表示可能会导致错误。

    #include <stdio.h>
    #include <math.h>
        #define eps 0.000001
        int main(){
    
            double inp=3.12456789;
    
            int fdigits=0;
            while(fabs(round(inp)-inp)>eps){
                printf("dif %f\n",fabs(round(inp)-inp));
                inp=inp*10;
                fdigits++;
    
            }
            printf("%d",fdigits);
        return 0;
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-10-13
      • 1970-01-01
      • 2013-09-25
      • 1970-01-01
      • 2019-08-05
      • 2017-12-31
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多