2010-08-25 10 views
14

tengo este valor:Convertir doble al hexágono en C#

double headingAngle = 135.34375; 

me gustaría convertirlo en HEX e imprimir el HEX a la consola. Ya he convertido una cadena e int en sus respectivos valores HEX, pero un doble parece ser mucho más complicado. ¿Alguien me puede apuntar en la dirección correcta?

+1

Una razón por la que no hay una función preconfigurada para esto es porque es completamente inútil. ¿Quién puede (y quiere) leer un doble como hex? –

+0

de acuerdo con Henk. @rross: me muero por saber, ¿por qué necesitas hacer esto? – tenfour

+2

@Henk No hay nada inherentemente menos útil en representar un valor no entero en hex que en decimal o cualquier otra base. Estamos más acostumbrados a los decimales. –

Respuesta

12

Bueno, buscado en Google durante un minuto o dos, y de acuerdo con this aquí es una solución bastante ellegant

double d = 12.09; 
    Console.WriteLine("Double value: " + d.ToString()); 
    byte[] bytes = BitConverter.GetBytes(d); 
    Console.WriteLine("Byte array value:"); 
    Console.WriteLine(BitConverter.ToString(bytes)); 
+5

Sé que esta pregunta es bastante antigua, pero probablemente valga la pena señalar que este código no convertirá el valor del doble en su representación hexadecimal. Más bien, escribirá la representación hexadecimal de los bits que se usan para almacenar el número internamente. Para un número de punto flotante, ¡las dos son cosas diferentes! –

+1

Punto tomado. Aunque no escuché ningún estándar de notación hexadecimal para la representación de valores de coma flotante. Por supuesto, es importante recordar acerca de las especificaciones de hardware y todas las cosas de big/low endian. Sin embargo, el estándar IEEE 754 es muy popular y ampliamente utilizado. Asi que.. – Bart

4

Puede convertir la base 10 en base 16 multiplicando continuamente la fracción por 16, eliminando el número "entero" y repitiendo con el resto.

Así que para convertir de decimal a 0,1 Hex

0.1 * 16 
= 1.6 

Así 1 se convierte en el primer valor hexadecimal. Continúe con el 0,6

0.6 * 16 = 9.6 

Entonces 9 se convierte en el segundo valor hexadecimal. Mantener va con el 0,6 restante

0.6 * 16 = 9.6 

etc.

Así 0.1 decimal = 0.19999 .. hexagonal

De memoria esto funciona con cualquier base recurrente. Obviamente, en un valor hexadecimal de toda 10 sería un etc.

3

Suponiendo que desea convertir a hexadecimal base/base, el siguiente debe hacer el truco:

static void Main(string[] args) 
{ 
    Console.WriteLine(Base16(135.34375, 10)); 
    Console.ReadLine(); 
} 

private static string Base16(double number, int fractionalDigits) 
{ 
    return Base(number, fractionalDigits, new char[]{ 
     '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 
     'A', 'B', 'C', 'D', 'E', 'F' }); 
} 

private static string Base(double number, int fractionalDigits, params char[] characters) 
{ 
    int radix = characters.Length; 
    StringBuilder sb = new StringBuilder(); 

    // The 'whole' part of the number. 
    long whole = (long)Math.Floor(number); 
    while (whole > 1) 
    { 
     sb.Insert(0, characters[whole % radix]); 
     whole = whole/radix; 
    } 

    // The fractional part of the number. 
    double remainder = number % 1; 
    if (remainder > Double.Epsilon || remainder < -Double.Epsilon) 
    { 
     sb.Append('.'); 

     double nv; 
     for (int i = 0; i < fractionalDigits; i++) 
     { 
      nv = remainder * radix; 
      if (remainder < Double.Epsilon && remainder > -Double.Epsilon) 
       break; 
      sb.Append(characters[(int)Math.Floor(nv)]); 
      remainder = nv % 1; 
     } 
    } 

    return sb.ToString(); 
} 

La conversión hexadecimal de 135.34375 es 87.58.

0

Prueba esto:

public static string Format(double number, double @base) 
{ 
    StringBuilder format = new StringBuilder(); 
    if(number < 0) 
    { 
     format.Append('-'); 
     number = -number; 
    } 
    double log = Math.Log(number, @base); 
    bool frac = false; 
    double order; 
    if(log < 0) 
    { 
     frac = true; 
     format.Append(digits[0]); 
     format.Append('.'); 
     order = 1/@base; 
    }else{ 
     order = Math.Pow(@base, Math.Floor(log)); 
    } 
    while(number != 0 || order >= 1) 
    { 
     double digit = Math.Floor(number/order); 
     if(digit >= @base) break; 
     number = number-digit*order; 
     number = Math.Round(number, 15); 
     if(order < 1 && !frac) 
     { 
      format.Append('.'); 
      frac = true; 
     } 
     order /= @base; 
     if(digit >= 10) 
     { 
      format.Append((char)('A'+(digit-10))); 
     }else{ 
      format.Append((char)('0'+digit)); 
     } 
    } 
    return format.ToString(); 
} 

usarlo como Format(headingAngle, 16). También puede comentar number = Math.Round(number, 15); para obtener resultados más interesantes. ☺

El resultado es en formato culturalmente invariable. Para 135.34375, devuelve 87.58.