2016-02-17 3 views
2

Мне нужно преобразовать значение float в шестнадцатеричную строку и обратно. Онлайн IEEE 754 Converter позволяет мне это сделать. Вот моя попытка осуществить преобразование:C# преобразование из float в hexstring через IEEE 754 и обратно в float

unsafe static void Main(string[] args) 
{ 
    float f = 0.0023984962F; 
    long l = *((long*)&f); 
    float r = *((float*)&l); 

    Console.WriteLine("{0} <-> {1:X} <-> {1:F1} <-> {2:F1}", f, l, r); 
    Console.ReadLine(); 
} 

Мои вопросы:

  1. С поплавком 0.0023984962 ожидаемый результат 0x3B1D3017, но мой код печатает 0x22CB20C3B1D3017. Что я делаю не так?

  2. Как сохранить выходные данные в переменной?

+1

Хорошее напоминание, почему 'unsafe' действительно небезопасно. Вместо этого используйте BitConverter.GetBytes(). –

ответ

0

Чтобы ответить на ваш второй вопрос, который вы можете использовать строковую переменную для хранения выходной, как:

String output = String.Format("{0} <-> {1:X} <-> {1:F1} <-> {2:F1}", f, l, r); 
2

Вы должны использовать int, не long при преобразовании float, так как float (ака Single) является 32-разрядный значение (в отличие от double, который является 64-бит):

unsafe static void Main(string[] args) 
{ 
    float f = 0.0023984962F; 
    int l = *((int*)&f); // int here: 32-bit float into 32-bit integer 
    float r = *((float*)&l); 

    // Let's save the result in the variable 
    String result = String.Format("{0} <-> {1:X} <-> {1:F1} <-> {2:F1}", f, l, r); 

    Console.WriteLine(result); 
    Console.ReadLine(); 
} 

Однако лучше провер тренере является использование BitConverter, который специально разработан для этой роли и избежать небезопасной рутины:

static void Main(string[] args) { 
    float f = 0.0023984962F; 

    uint l = BitConverter.ToUInt32(BitConverter.GetBytes(f), 0); 
    float r = BitConverter.ToSingle(BitConverter.GetBytes(l), 0); 

    // Let's save the result in the variable 
    String result = String.Format("{0} <-> {1:X} <-> {1:F1} <-> {2:F1}", f, l, r); 

    Console.WriteLine(result); 
    Console.ReadLine(); 
} 
+0

Я пытался конвертировать двойной и не мог понять, почему он не работает. Перенос двойника в поплавок сначала исправил мою проблему. –

+1

@Moon Waxing: 'double' is ** 64-bit ** value, поэтому при работе с' double' вы должны использовать 'long' (или' ulong') –

1

Чтобы иметь возможность конвертировать в обоих направления, нужна две функции. У вас есть ошибка в коде, в котором вы добавили 32-битное число с плавающей запятой (float) в 64-битное целое число (long). Поскольку ваш код равен unsafe, эта ошибка не попадает в компилятор.

Однако, используя unsafe код работает очень хорошо, так вот код, который работает:

unsafe string ToHexString(float f) { 
    var i = *((int*) &f); 
    return "0x" + i.ToString("X8"); 
} 

unsafe float FromHexString(string s) { 
    var i = Convert.ToInt32(s, 16); 
    return *((float*) &i); 
} 

Чтобы избежать проблем unsafe кода вы можете также использовать BitConverter, который будет проверять размер промежуточных буферов байт для вы.

string ToHexString(float f) { 
    var bytes = BitConverter.GetBytes(f); 
    var i = BitConverter.ToInt32(bytes, 0); 
    return "0x" + i.ToString("X8"); 
} 

float FromHexString(string s) { 
    var i = Convert.ToInt32(s, 16); 
    var bytes = BitConverter.GetBytes(i); 
    return BitConverter.ToSingle(bytes, 0); 
} 

Теперь вы можете конвертировать в обоих направлениях:

var hexString = ToHexString(0.0023984962F); 
var f = FromHexString(hexString); 
Смежные вопросы