在C语言中将二进制分数转换为十进制分数

在C语言中将二进制分数转换为十进制分数,c,bignum,C,Bignum,我实现了对2的平方根的逐位计算。每轮输出一位小数部分,例如 1010101等 我想将此输出转换为十进制数: 414136等 我面临的问题是,这通常是这样的: 1*2^-1+0*2^-2+1*2^-3etc 我希望完全避免使用分数,因为我希望使用整数将二进制转换为十进制。此外,我想打印每一个十进制数字一旦计算出来 转换为十六进制非常简单,因为我只需要等待4位。是否有一种智能的方法可以转换为base10,它只允许观察整个输出的一部分,并且理想地从等式中删除数字,一旦我们确定它不会再改变,即 1

我实现了对2的平方根的逐位计算。每轮输出一位小数部分,例如

1010101

我想将此输出转换为十进制数:

414136

我面临的问题是,这通常是这样的:

1*2^-1+0*2^-2+1*2^-3
etc

我希望完全避免使用分数,因为我希望使用整数将二进制转换为十进制。此外,我想打印每一个十进制数字一旦计算出来

转换为十六进制非常简单,因为我只需要等待4位。是否有一种智能的方法可以转换为base10,它只允许观察整个输出的一部分,并且理想地从等式中删除数字,一旦我们确定它不会再改变,即

1   0
2   0,25
3   0,375
4   0,375
5   0,40625
6   0,40625
7   0,4140625
8   0,4140625

处理完第8位后,我非常确定4是第一个小数位数。因此,我想从等式中完全删除
0.4
,以减少需要处理的位。

您可以使用乘除法来减少浮点运算。
1011

它相当于
1*2^0+0*2^1+2^(-2)+2^(-3)
可以简化为
(1*2^3+0*2^2+1*2^0)/(2^3)
只有除法仍然是浮点算术,其余都是整数算术运算。2的乘法可以通过左移位实现。

您可以使用乘除法来减少浮点运算量。
1011
它相当于
1*2^0+0*2^1+2^(-2)+2^(-3)
可以简化为
(1*2^3+0*2^2+1*2^0)/(2^3)
只有除法仍然是浮点算术,其余都是整数算术运算。2的乘法可以通过左移位实现

是否有一种聪明的方法可以转换为base10,它只允许观察整个输出的一部分,理想情况下,一旦我们确定它不再改变,就可以从方程中删除数字(?)

是的,最终在实践中是这样,但在理论上,在某些情况下不是这样

这类似于

考虑以下接近0.05的值的处理。只要二进制序列是.0001 1001 1001 1001 1001,我们不知道它的十进制等价物是0.0499999。。。或0.05000000…非零

int main(void) {
  double a;
  a = nextafter(0.05, 0);
  printf("%20a %.20f\n", a, a);
  a = 0.05;
  printf("%20a %.20f\n", a, a);
  a = nextafter(0.05, 1);
  printf("%20a %.20f\n", a, a);
  return 0;
}

0x1.9999999999999p-5 0.04999999999999999584
0x1.999999999999ap-5 0.05000000000000000278
0x1.999999999999bp-5 0.05000000000000000971
代码可以分析二进制分数位的输入序列,然后在每一位之后问两个问题:“如果剩余位都是0,那么十进制是什么?”和“如果剩余位都是1,那么十进制是什么?”。在许多情况下,答案将共享共同的前导有效数字。然而如上所示,只要接收到1001,就没有常见的有效十进制数字

通常的“输出”是对将要显示的小数位数有一个上限。在这种情况下,代码仅给出一个舍入结果,即使二进制输入序列保持1001,也可以在有限时间内推导出该结果

是否有一种聪明的方法可以转换为base10,它只允许观察整个输出的一部分,理想情况下,一旦我们确定它不再改变,就可以从方程中删除数字(?)

是的,最终在实践中是这样,但在理论上,在某些情况下不是这样

这类似于

考虑以下接近0.05的值的处理。只要二进制序列是.0001 1001 1001 1001 1001,我们不知道它的十进制等价物是0.0499999。。。或0.05000000…非零

int main(void) {
  double a;
  a = nextafter(0.05, 0);
  printf("%20a %.20f\n", a, a);
  a = 0.05;
  printf("%20a %.20f\n", a, a);
  a = nextafter(0.05, 1);
  printf("%20a %.20f\n", a, a);
  return 0;
}

0x1.9999999999999p-5 0.04999999999999999584
0x1.999999999999ap-5 0.05000000000000000278
0x1.999999999999bp-5 0.05000000000000000971
代码可以分析二进制分数位的输入序列,然后在每一位之后问两个问题:“如果剩余位都是0,那么十进制是什么?”和“如果剩余位都是1,那么十进制是什么?”。在许多情况下,答案将共享共同的前导有效数字。然而如上所示,只要接收到1001,就没有常见的有效十进制数字

通常的“输出”是对将要显示的小数位数有一个上限。在这种情况下,代码仅给出一个舍入结果,即使二进制输入序列保持1001,也可以在有限时间内推导出该结果

我面临的问题是,这通常是这样的:

1*2^-1+0*2^-2+1*2^-3等

1/2=5/10和1/4=25/100,依此类推,这意味着你需要5的幂,并将值移动10的幂

因此,假设为01101

[1] 0*5=0

[2] 0*10+1*25=25

[3] 25*10+1*125=375

[4] 375*10+0*625=3750

[5] 3750*10+1*3125=40625

编辑:

是否有一种智能的方法可以转换为base10,它只允许观察整个输出的一部分,并且理想地从等式中删除数字,一旦我们确定它不会再改变

在这种情况下,实际上可能会弹出最重要的数字(MSD)。这将是一个有点长,但请容忍我

考虑X和Y的值:

  • 如果X的位数与Y相同,则MSD将更改
  • 如果Y有一个或多个小于X的数字,则MSD可以更改
  • 因此,第一点是不言自明的,但第二点是什么将允许我们弹出MSD。我们需要知道的第一件事是,我们正在添加的值在每次迭代中都被不断地分成两半。这意味着如果我们只考虑MSD,BASE10中的最大值是9,将产生序列

        9 > 4 > 2 > 1 > 0
    
    如果我们总结这些值,它将等于16,但是如果我们试图考虑下一个数字的值(例如9.9或9.999),该值实际上接近20,但不超过20。这意味着,如果X有n个数字,Y有n-1个数字,那么X的MSD仍然可以改变。但如果X有n个数字,Y有n-2个数字,只要X的n-1个数字小于8,则
        9 > 4 > 2 > 1 > 0
    
     1. If X = 10000 and Y = 9000 then the MSD of X can change.
     2. If X = 10000 and Y =  900 then the MSD of X will not change.
     3. If X = 19000 and Y =  900 then the MSD of X can change.
     4. If X = 18000 and Y =  999 then the MSD of X can change.
     5. If X = 17999 and Y =  999 then the MSD of X will not change.
     6. If X = 19990 and Y =    9 then the MSD of X can change.
    
    i          Out                      X                  Y     flag
    -------------------------------------------------------------------
    1                                   0                  5       0
    2                                  25                 25       1
    3                                 375                125       1
    4                               3,750                625       0
    5                              40,625              3,125       1
    6                             406,250             15,625       0
    7            4                140,625             78,125       1
    8            4              1,406,250            390,625       0
    9            4             14,062,500          1,953,125       0
    10          41             40,625,000          9,765,625       0
    11          41            406,250,000         48,828,125       0
    12          41          4,062,500,000        244,140,625       0
    13          41         41,845,703,125      1,220,703,125       1
    14         414         18,457,031,250      6,103,515,625       0
    15         414        184,570,312,500     30,517,578,125       0
    16         414      1,998,291,015,625    152,587,890,625       1
    17        4142      0,745,849,609,375    762,939,453,125       1