鉴于维基百科的文章 小数点, ,如何计算 10.1 的二进制等值或 17.17 的十六进制等值?对于前者,十分之一的二进制相当于多少?对于后者,17/100 的十六进制表示?

我更多地寻找一种算法,而不是这两个例子的解决方案。

有帮助吗?

解决方案

要将十进制 10.1 转换为二进制,请将整数部分和小数部分分开并分别进行转换。

要转换整数部分,请使用重复的整数除以 2,然后以相反的顺序写入余数:

10/2 = 5 余数 0

5/2 = 2 余 1

2/2 = 1 余数 0

1/2 = 0 余数 1

回答:1010

要转换小数部分,请重复乘以 2,并在每一步减去整数部分。整数部分按生成顺序表示您的二进制数:

0.1 * 2 = 0.2

0.2 * 2 = 0.4

0.4 * 2 = 0.8

0.8 * 2 = 1.6

0.6 * 2 = 1.2

0.2 * 2 = 0.4

0.4 * 2 = 0.8

...(循环永远重复)

所以十进制 0.1 是二进制 0.000110011001100...

(有关更详细的解释,请参阅我的文章中的例程 dec2bin_i() 和 dec2bin_f() http://www.exploringbinary.com/base-conversion-in-php-using-bcmath/ .)

对于十六进制,请使用相同的过程,只不过除数/乘数为 16 而不是 2。余数和大于 9 的整数部分必须直接转换为十六进制数字:10 变为 A,11 变为 B,..., 15 变为 F。

其他提示

一终止数字(一些这可以由有限数量的数字)n1 在基b1, 可能是一个非终止的数量在不同的基b2.相反,一个非终止的数量在一个基b1 可以变成是一个终止的数量在基b2.

数0.110 当转换为是二进制的一个非终止的数量,为的是0.1710 当转换为一个进制数字。但是终端数量为0.13 在基3,当转换为基10是非终止,重复数量为0。(3)10 (标志着数3重复).同样,将0.110 二进制和0.1710 到十六、一个结束了非终止、重复的数字0.0(0011)2 和0.2(B851E)16

因此,当将这样一个数字从一个到另一个基地,您可能发现自己具有近似数,而不是具有代表性,这是完全准确。

该算法很简单,但实际上,你可以做很多事情都与查找表和日志的调整来加快速度。 但对于基本的算法,您可以尝试是这样的:

shift=0;

while v>=base,  v=v/base, shift=shift+1;  

Next digit: 
if v<1.0 && shift==0, output the decimal point
else 
   D=floor(v)
   output D
   v=v-D
v=v*base
shift = shift-1
if (v==0) exit;
goto Next Digit

您还可以将一个测试中有N个数位后停止打印更长循环小数。

十分之一的 '二进制等效' 是二分之一,即代替1- / 10 ^ 1,它的1/2 ^ 1

每个数字表示的二的幂。小数点后面的数字是相同的,只是它们所代表1以上的两个功率:

 8 4 2 1 . 1/2 1/4 1/8 1/16 

因此,对于10.1,则显然需要一个“8”和“2”,使10部分。 1/2(0.5)过多,四分之一(0.25)过多,1/8(0.125)是太多了。我们需要1/16(0.0625),这将使我们能够对0.0375。 1/32为0.03125,所以我们可以利用这一点。到目前为止,我们有:

 8 4 2 1 . 1/2 1/4 1/8 1/16 1/32
 1 0 1 0    0   0   0   1     1

使用的0.00625错误。 1/64(0.015625)和1/128(0.0078125)均过多,1/256(0.00390625)将工作:

 8 4 2 1 . 1/2 1/4 1/8 1/16 1/32 1/64 1/128 1/256
 1 0 1 0    0   0   0   1     1    0   0     1

使用的0.00234375错误。

在0.1不能被精确以二进制(正如1/3不能精确十进制来表示)来表示。这取决于你把你的基数,你最终不得不停止,可能是圆的,并接受错误。

在我在GMP库的光这个玩弄,这里的地方我一定要努力让里克·里根的PHP代码一般从2任何基高达36。

Function dec2base_f(ByVal ddecimal As Double, ByVal nBase As Long, ByVal dscale As Long) As String
    Const BASES = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" 'up to base 36
    Dim digitCount As Long
    Dim wholeNumber As Double
    Dim digit As String * 1
    digitCount = 0
    dscale = max(dscale, Len(CStr(ddecimal)) - Len("0."))
    Dim baseary_f As String
    baseary_f = "0."
    Do While ddecimal > 0 And digitCount < dscale
        ddecimal = ddecimal * nBase
        digit = Mid$(BASES, Fix(ddecimal) + 1)
        baseary_f = baseary_f & digit '"1"
        ddecimal = ddecimal - Fix(ddecimal)
        digitCount = digitCount + 1
    Loop
    dec2base_f = baseary_f
End Function

Function base2dec_f(ByVal baseary_f As String, nBase As Double) As Double
    Const BASES As String = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    Dim decimal_f As Double
    Dim i As Long
    Dim c As Long
    For i = Len(baseary_f) To Len("0.") + 1 Step -1
        c = InStr(BASES, Mid$(baseary_f, i, 1)) - 1
        decimal_f = decimal_f + c
        decimal_f = decimal_f / nBase
    Next
    base2dec_f = decimal_f
End Function

Debug.Print base2dec_f(dec2base_f(0.09, 2, 200), 2) --> 0.09
Debug.Print base2dec_f(dec2base_f(0.09, 8, 200), 8) --> 0.09
Debug.Print base2dec_f(dec2base_f(0.09, 16, 200), 16) --> 0.09
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top