Question

Compte tenu de l'article de Wikipédia sur Point de base, comment calculer l'équivalent binaire de 10,1 ou l'équivalent hexadécimal de 17,17 ?Pour le premier, quel est l’équivalent binaire d’un dixième ?Pour ces derniers, la représentation hexadécimale de 17/100 ?

Je recherche plus un algorithme que des solutions à ces deux exemples seulement.

Était-ce utile?

La solution

Pour convertir le nombre décimal 10,1 en binaire, séparez les parties entières et fractionnaires et convertissez chacune séparément.

Pour convertir la partie entière, utilisez une division entière répétée par 2, puis écrivez les restes dans l'ordre inverse :

10/2 = 5 reste 0

5/2 = 2 reste 1

2/2 = 1 reste 0

1/2 = 0 reste 1

Répondre:1010

Pour convertir la partie fractionnaire, utilisez une multiplication répétée par 2, en soustrayant la partie entière à chaque étape.Les parties entières, par ordre de génération, représentent votre nombre binaire :

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

...(le cycle se répète pour toujours)

Donc le nombre décimal 0,1 est binaire 0,000110011001100...

(Pour une explication plus détaillée, voir les routines dec2bin_i() et dec2bin_f() dans mon article http://www.exploringbinary.com/base-conversion-in-php-using-bcmath/ .)

Pour l'hexadécimal, utilisez la même procédure, sauf avec un diviseur/multiplicateur de 16 au lieu de 2.Les restes et les parties entières supérieures à 9 doivent être convertis directement en chiffres hexadécimaux :10 devient A, 11 devient B, ..., 15 devient F.

Autres conseils

Un certain nombre de terminaison (un nombre qui peut être représenté par un nombre fini de chiffres) n 1 dans la base b 1 , peut finir par être un nombre non-terminaison dans un b de base différente 2 . A l'inverse, un nombre non-se terminant par une base b 1 peut se révéler être un numéro de terminaison à base b 2 .

Le nombre 0,1 10 lorsqu'il est converti en binaire est un nombre de non-terminaison, de même que 0,17 10 lorsqu'il est converti en un nombre hexadécimal. Mais le nombre de terminaison 0,1 3 de base 3, lorsqu'il est converti en base 10 est la non-terminaison, le numéro de répétition de 0. (3) 10 (ce qui signifie que le nombre 3 répétitions ). De même, la conversion de 0,1 10 en binaire et 0,17 10 en hexadécimal, on aboutit à la non-terminaison, en répétant les numéros 0.0 (0011) 2 et 0,2 (B851E) 16

En raison de cela, lors de la conversion d'un tel nombre d'une base à une autre, vous pouvez vous retrouver avoir à rapprocher le nombre au lieu d'avoir une représentation qui est tout à fait exact.

L'algorithme est assez simple, mais en pratique, vous pouvez faire beaucoup de réglages à la fois avec des tables de consultation et les journaux pour l'accélérer. Mais pour l'algorithme de base, vous pouvez essayer quelque chose comme ceci:

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

Vous pouvez également mettre un test là-bas pour arrêter l'impression après les chiffres de N pour plus de décimales répéter.

Le 'équivalent binaire' d'un dixième est une moitié, i.e. au lieu de 1/10 ^ 1, est de 1/2 ^ 1.

Chaque chiffre représente une puissance de deux. Les chiffres derrière le point de radix sont les mêmes, il est juste qu'ils représentent 1 sur la puissance de deux:

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

Donc, pour 10.1, vous avez besoin de toute évidence un « 8 » et « 2 » pour faire la partie 10. 1/2 (0,5) est trop, 1/4 (0,25) est trop, 1/8 (0,125) est trop. Nous avons besoin 1/16 (0,0625), ce qui nous laissera 0,0375. 1/32 est 0,03125, donc nous pouvons prendre aussi. Jusqu'à présent, nous avons:

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

Avec une erreur de 0,00625. 1/64 (0,015625) et 1/128 (0,0078125) sont tous deux trop, 1/256 (0,00390625) fonctionnera:

 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

Avec une erreur de 0,00234375.

Le .1 ne peut pas être exprimé exactement en binaire (comme un tiers ne peut pas être exprimé exactement en décimal). Selon l'endroit où vous mettez votre radix, vous avez fini par arrêter, probablement ronde, et accepter l'erreur.

Avant Tripotez ce à la lumière de ma bibliothèque GMP, voici où je suis arrivé à essayer de faire le code PHP de Rick Regan générique pour toute base de 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
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top