我有这个值:
double headingAngle = 135.34375;
我想把它转换成十六进制并打印到控制台。我已经把一个字符串和一个整数转换成了它们各自的十六进制值,但是一个双精度型似乎要棘手得多。有人能给我指出正确的方向吗?
axzmvihb1#
根据this,这是一个非常优雅的解决方案
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));
1mrurvl12#
你可以把以10为底的数转换成以16为底的数,方法是不断地把分数乘以16,去掉“整数”,然后对余数重复。要将0.1十进制转换为十六进制
0.1 * 16 = 1.6
因此1成为第一个十六进制值,继续使用剩下的0.6
0.6 * 16 = 9.6
所以9变成了第二个十六进制值。继续剩下的0.6
等等。所以0.1十进制= 0.19999 ..循环十六进制在内存中,这对任何基数都有效。显然,在十六进制中,10的整数值将是A等。
0.1
0.19999
10
voase2hg3#
假设您想转换为十六进制的base/radix,下面的代码应该可以做到:
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。
87.58
ql3eal8s4#
BitConverter.DoubleToInt64Bits(value).ToString("X")
cx6n0qe35#
试试这个:
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。
Format(headingAngle, 16)
number = Math.Round(number, 15);
5条答案
按热度按时间axzmvihb1#
根据this,这是一个非常优雅的解决方案
1mrurvl12#
你可以把以10为底的数转换成以16为底的数,方法是不断地把分数乘以16,去掉“整数”,然后对余数重复。
要将0.1十进制转换为十六进制
因此1成为第一个十六进制值,继续使用剩下的0.6
所以9变成了第二个十六进制值。继续剩下的0.6
等等。
所以
0.1
十进制=0.19999
..循环十六进制在内存中,这对任何基数都有效。显然,在十六进制中,
10
的整数值将是A等。voase2hg3#
假设您想转换为十六进制的base/radix,下面的代码应该可以做到:
135.34375的十六进制转换为
87.58
。ql3eal8s4#
cx6n0qe35#
试试这个:
像
Format(headingAngle, 16)
一样使用它。你也可以注解掉number = Math.Round(number, 15);
以获得更有趣的结果。结果为区域性固定格式。对于135.34375,它返回87.58。