2010-08-25 2 views
14

У меня есть это значение:Преобразовать дважды в шестнадцатеричной в C#

double headingAngle = 135.34375; 

Я хотел бы, чтобы преобразовать его в HEX и распечатать HEX к консоли. Я уже преобразовал строку и int в их соответствующие значения HEX, но двойной кажется более сложным. Может ли кто-нибудь указать мне в правильном направлении?

+1

Одна из причин отсутствия готовой функции для этого заключается в том, что она совершенно бесполезна. Кто может (и хочет) читать двойной как шестнадцатеричный? –

+0

согласны с Хенк. @rross: Я умираю, чтобы знать, зачем вам это нужно? – tenfour

+2

@Henk Нет ничего более менее полезного в представлении нецелого значения в шестнадцатеричном виде, чем в десятичной или любой другой базе. Мы просто больше привыкли к десятичной. –

ответ

12

Ну, я гугле в течение минуты или двух, и в соответствии с this здесь является довольно 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

Я знаю, что этот вопрос довольно старый, но, вероятно, стоит отметить, что этот код не преобразует значение double в его шестнадцатеричное представление. Скорее, он выпишет шестнадцатеричное представление битов, которые используются для хранения номера внутри. Для числа с плавающей запятой две разные вещи! –

+1

Точка взята. Хотя я не слышал ни одного стандарта шестнадцатеричной нотации для представления значений с плавающей запятой. Разумеется, важно помнить о спецификации оборудования и всех материалах с большим/низким уровнем. Однако стандарт IEEE 754 очень популярен и широко используется. Так.. – Bart

4

Вы можете преобразовать основание 10 в основание 16 путем непрерывного умножения фракции на 16, снятия «целого» числа и повторения с остатком.

Таким образом, чтобы преобразовать 0,1 десятичных чисел в Hex

0.1 * 16 
= 1.6 

Таким образом, 1 становится первым шестнадцатеричное значение. Продолжайте движение с остальными 0,6

0.6 * 16 = 9.6 

Таким образом, 9 становится вторым шестнадцатеричным значением. Сохраняя происходит с оставшимися 0,6

0.6 * 16 = 9.6 

т.д.

Так 0.1 Decimal = 0.19999 .. повторяющегося Hex

Из памяти это работает для любой системы счисления. Очевидно, что в шестнадцатеричном целое значение 10 бы и т.д.

3

Предполагая, что вы хотите преобразовать в шестнадцатеричное основание/радикса, следующий должен сделать трюк:

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(); 
} 

Преобразование шестнадцатеричной из 135.34375 является 87.58.

0

Попробуйте это:

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(); 
} 

Используйте его как Format(headingAngle, 16). Вы также можете прокомментировать number = Math.Round(number, 15); для получения более интересных результатов. ☺

Результат в культурно-инвариантном формате. Для 135.34375 он возвращает 87.58.

Смежные вопросы