I have this value:
double headingAngle = 135.34375;
I would like to convert it to HEX and print the HEX to the console. I have already converted a string and int into their respective HEX values, but a double seems to be much more tricky. Can someone point me in the right direction?
Well, I googled for a minute or two and according to this
here is a quite ellegant solution
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));
You can convert base 10 to base 16 by continually multiplying the fraction by 16, stripping out the 'whole' number, and repeating with the remainder.
So to convert 0.1 Decimal to Hex
0.1 * 16
= 1.6
So 1 becomes the first hex value. Keep going with the remaining 0.6
0.6 * 16 = 9.6
So 9 becomes the second hex value. Keeping going with the remaining 0.6
0.6 * 16 = 9.6
etc.
So 0.1
Decimal = 0.19999
.. recurring hex
From memory this works for any radix. Obviously in hex a whole value of 10
would be A etc.
Assuming you want to convert to hexadecimal base/radix, the following should do the trick:
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();
}
The hexadecimal conversion of 135.34375 is 87.58
.
BitConverter.DoubleToInt64Bits(value).ToString("X")
Try this:
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();
}
Use it like Format(headingAngle, 16)
. You can also comment out number = Math.Round(number, 15);
for more interesting results. ☺
Result is in culture-invariant format. For 135.34375, it returns 87.58.