将C中的二进制小数转换为小数

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

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

1 0 1 1 0 1 0 1等。>

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

4 1 4 2 1 3 6等。>

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

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

我想完全避免使用小数,因为我想使用整数从二进制转换为十进制。我也想在计算完每个十进制数字后立即打印。

转换为十六进制是微不足道的,因为我只需要等待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补余项,以减少我需要注意的位。

我实现了对平方根2的逐位计算。每回合它将输出小数部分的一位,例如1 0 1 1 0 1 0 1等。我想将此输出转换为十进制...

是否有一种聪明的方法可以转换为以10为基数,一旦我们确定它不会再改变了,它便只能观察整个输出的一部分,并且理想地从等式中除去数字(?]

是的,最终在实践中,但是从理论上讲,在某些情况下没有。

类似于Table-maker's dilemma

考虑以下处理,将其接近0.05。只要二进制序列是.0001 1001 1001 1001 1001 ...,我们就不能知道十进制等效值为0.04999999 ...或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,就没有通用的有效十进制数字。

通常的“输出”是要显示ever

的十进制数字的上限。在这种情况下,即使二进制输入序列保持为1001,代码也只能给出rounded
结果,并且可以在有限的时间内得出结果。ad nauseam

您可以使用乘除法来减少浮点运算。1 0 1 1等效于1*2^0+0*2^1+2^(-2)+2^(-3)可以简化为(1*2^3+0*2^2+1*2^1+1*2^0)/(2^3),只剩下除法浮点算术,其余都是整数算术运算。乘以2可以通过左移来实现。

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

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

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

给定0 1 1 0 1

[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

c bignum
2个回答
2
投票

是否有一种聪明的方法可以转换为以10为基数,一旦我们确定它不会再改变了,它便只能观察整个输出的一部分,并且理想地从等式中除去数字(?]


0
投票

您可以使用乘除法来减少浮点运算。1 0 1 1等效于1*2^0+0*2^1+2^(-2)+2^(-3)可以简化为(1*2^3+0*2^2+1*2^1+1*2^0)/(2^3),只剩下除法浮点算术,其余都是整数算术运算。乘以2可以通过左移来实现。


0
投票

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

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

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