Skip to content

Instantly share code, notes, and snippets.

@benrr101
Created January 18, 2021 19:39
Show Gist options
  • Save benrr101/25915591f55dc16bc15cbdf0ae78e41a to your computer and use it in GitHub Desktop.
Save benrr101/25915591f55dc16bc15cbdf0ae78e41a to your computer and use it in GitHub Desktop.
Converters - IEEE 754 Double/Extended Conversion
public static double ConvertIeeeExtendedToDouble(byte[] bytes)
{
int e = ((bytes[0] & 0x7F) << 8) | (bytes[1] & 0xFF);
ulong h = ((ulong)bytes[2] << 24)
| ((ulong)bytes[3] << 16)
| ((ulong)bytes[4] << 8)
| bytes[5];
ulong l = ((ulong)(bytes[6]) << 24)
| ((ulong)(bytes[7]) << 16)
| ((ulong)(bytes[8]) << 8)
| bytes[9];
double f;
if (e == 0 && h == 0 && l == 0)
{
f = 0;
}
else
{
if (e == 0x7FFF)
{
f = double.PositiveInfinity;
}
else
{
e -= 16383;
f = h * Math.Pow(2, e -= 31);
f += l * Math.Pow(2, e -= 32);
}
}
return (bytes[0] & 0x80) != 0 ? -f : f;
}
public static byte[] ConvertDoubleToIeeeExtended(double num)
{
byte[] bytes = BitConverter.GetBytes(num);
if (BitConverter.IsLittleEndian)
{
Array.Reverse(bytes);
}
// Determine the exponent field to write out
int exponentToWrite = num < 0 ? 0x8000 : 0x0000;
if ((bytes[0] & 0x7F) == 0x7F && (bytes[1] & 0xF0) == 0xF0)
{
// Infinity
exponentToWrite |= 0x7FFF;
}
else
{
// Finite
int unbiasedExponent = (((bytes[0] & 0x7F) << 4) | (bytes[1] >> 4)) - 1023;
exponentToWrite |= unbiasedExponent + 16383;
}
// Determine the mantissa to write out
ulong mantissaToWrite = 0;
if (num != 0)
{
// Number is not 0
// - Write a 1 to integer part of the mantissa
mantissaToWrite |= (ulong)1 << 63;
// - Shift the double mantissa by 11 bits
mantissaToWrite |= (ulong)bytes[7] << 11;
mantissaToWrite |= (ulong)bytes[6] << 19;
mantissaToWrite |= (ulong)bytes[5] << 27;
mantissaToWrite |= (ulong)bytes[4] << 35;
mantissaToWrite |= (ulong)bytes[3] << 43;
mantissaToWrite |= (ulong)bytes[2] << 51;
mantissaToWrite |= ((ulong)bytes[1] & 0x0F) << 59;
}
byte[] output = new byte[10];
output[0] = (byte)((exponentToWrite & 0xFF00) >> 8);
output[1] = (byte)exponentToWrite;
output[2] = (byte)((mantissaToWrite & 0xFF00000000000000) >> 56);
output[3] = (byte)((mantissaToWrite & 0x00FF000000000000) >> 48);
output[4] = (byte)((mantissaToWrite & 0x0000FF0000000000) >> 40);
output[5] = (byte)((mantissaToWrite & 0x000000FF00000000) >> 32);
output[6] = (byte)((mantissaToWrite & 0x00000000FF000000) >> 24);
output[7] = (byte)((mantissaToWrite & 0x0000000000FF0000) >> 16);
output[8] = (byte)((mantissaToWrite & 0x000000000000FF00) >> 8);
output[9] = (byte)(mantissaToWrite);
return output;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment