Pregunta

Dado el artículo de Wikipedia sobre Punto de base, ¿cómo se calcularía el equivalente binario de 10,1 o el equivalente hexadecimal de 17,17?Para el primero, ¿cuál es el equivalente binario de un décimo?Para este último, ¿la representación hexadecimal de 17/100?

Estoy buscando más un algoritmo que soluciones solo para esos dos ejemplos.

¿Fue útil?

Solución

Para convertir el decimal 10.1 a binario, separe las partes entera y fraccionaria y convierta cada una por separado.

Para convertir la parte entera, use la división entera repetida por 2 y luego escriba los restos en orden inverso:

10/2 = 5 resto 0

5/2 = 2 resto 1

2/2 = 1 resto 0

1/2 = 0 resto 1

Respuesta:1010

Para convertir la parte fraccionaria, usa la multiplicación repetida por 2, restando la parte entera en cada paso.Las partes enteras, en orden de generación, representan su número binario:

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

...(el ciclo se repite para siempre)

Entonces el decimal 0,1 es el binario 0,000110011001100...

(Para una explicación más detallada vea las rutinas dec2bin_i() y dec2bin_f() en mi artículo http://www.exploringbinary.com/base-conversion-in-php-using-bcmath/ .)

Para hexadecimal, utilice el mismo procedimiento, excepto con un divisor/multiplicador de 16 en lugar de 2.Los restos y las partes enteras mayores que 9 deben convertirse directamente a dígitos hexadecimales:10 se convierte en A, 11 se convierte en B, ..., 15 se convierte en F.

Otros consejos

Un número de terminación (un número que puede ser representado por un número finito de dígitos) n 1 en base b 1 , puede llegar a ser un número no termina en una base diferente b 2 . A la inversa, un número no termina en una base b 1 puede llegar a ser un número de terminación en base b 2 .

El número 0.1 10 cuando se convierte a binario es un número no termina, como es 0.17 10 cuando se convierte a un número hexadecimal. Pero el número de terminación 0.1 3 en la base 3, cuando se convierte a la base 10 es la no terminación, repitiendo número 0. (3) 10 (que significa que el número 3 repeticiones ). Del mismo modo, la conversión de 0,1 10 a binario y 0,17 10 a hexadecimal, uno termina con la no terminación, números 0.0 (0011) repetir 2 y 0,2 (B851E) 16

Debido a esto, al convertir un número tal de una base a otra, se puede notar que tiene para aproximar el número en lugar de tener una representación que es completamente exacta.

El algoritmo es bastante simple, pero en la práctica se puede hacer un montón de ajustes tanto con tablas de búsqueda y los registros para acelerarlo. Pero para el algoritmo básico, puede intentar algo como esto:

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

También se puede poner una prueba en la que hay que parar la impresión después de n dígitos durante más tiempo decimales periódicos.

El 'equivalente binario' de un décimo es una media, es decir en lugar de 1/10 ^ 1, que es 1/2 ^ 1.

Cada dígito representa una potencia de dos. Los dígitos detrás de la coma de la base son los mismos, es sólo que ellos representan 1 sobre la potencia de dos:

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

Así que para 10.1, es obvio que necesita un '8' y '2' para hacer que la parte 10. Un medio (0,5) es demasiado, 1/4 (0,25) es demasiado, 1/8 (0,125) es demasiado. Necesitamos 1/16 (0,0625), lo que nos dejará con 0,0375. 1/32 es 0,03125, así que puede tomar eso también. Hasta el momento tenemos:

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

Con un error de 0,00625. 1/64 (0.015625) y 1/128 (0,0078125) son a la vez demasiado, 1/256 (0,00390625) funcionará:

 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

Con un error de 0,00234375.

El 0.1 no se puede expresar exactamente en binario (al igual que 1/3 no se puede expresar exactamente en decimal). Dependiendo de donde usted pone su raíz, que finalmente tiene que parar, probablemente redonda, y aceptar el error.

Antes de girar con esto a la luz de mi librería GMP, aquí es donde tengo que tratar de hacer que el código PHP de Rick Regan genérico para cualquier base de 2 a 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
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top