在c#中从double中提取尾数和指数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/389993/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
extracting mantissa and exponent from double in c#
提问by dvenema
Is there any straightforward way to get the mantissa and exponent from a double in c# (or .NET in general)?
是否有任何直接的方法可以从 c#(或一般的 .NET)中的 double 中获取尾数和指数?
I found this exampleusing google, but I'm not sure how robust it would be. Could the binary representation for a double change in some future version of the framework, etc?
我使用谷歌找到了这个例子,但我不确定它会有多健壮。在框架的未来版本等中,二进制表示是否可以进行双重更改?
The other alternative I found was to use System.Decimal instead of double and use the Decimal.GetBits()method to extract them.
我发现的另一种替代方法是使用 System.Decimal 而不是 double 并使用Decimal.GetBits()方法来提取它们。
Any suggestions?
有什么建议?
采纳答案by Jon Skeet
The binary format shouldn't change - it would certainly be a breaking change to existing specifications. It's defined to be in IEEE754 / IEC 60559:1989 format, as Jimmy said. (C# 3.0 language spec section 1.3; ECMA 335 section 8.2.2). The code in DoubleConverter should be fine and robust.
二进制格式不应该改变——这肯定是对现有规范的重大改变。正如吉米所说,它被定义为 IEEE754 / IEC 60559:1989 格式。(C# 3.0 语言规范第 1.3 节;ECMA 335 第 8.2.2 节)。DoubleConverter 中的代码应该很好而且很健壮。
For the sake of future reference, the relevant bit of the code in the example is:
为了将来参考,示例中代码的相关位是:
public static string ToExactString (double d)
{
…
// Translate the double into sign, exponent and mantissa.
long bits = BitConverter.DoubleToInt64Bits(d);
// Note that the shift is sign-extended, hence the test against -1 not 1
bool negative = (bits & (1L << 63)) != 0;
int exponent = (int) ((bits >> 52) & 0x7ffL);
long mantissa = bits & 0xfffffffffffffL;
// Subnormal numbers; exponent is effectively one higher,
// but there's no extra normalisation bit in the mantissa
if (exponent==0)
{
exponent++;
}
// Normal numbers; leave exponent as it is but add extra
// bit to the front of the mantissa
else
{
mantissa = mantissa | (1L << 52);
}
// Bias the exponent. It's actually biased by 1023, but we're
// treating the mantissa as m.0 rather than 0.m, so we need
// to subtract another 52 from it.
exponent -= 1075;
if (mantissa == 0)
{
return negative ? "-0" : "0";
}
/* Normalize */
while((mantissa & 1) == 0)
{ /* i.e., Mantissa is even */
mantissa >>= 1;
exponent++;
}
…
}
The comments made sense to me at the time, but I'm sure I'd have to think for a while about them now. After the very first part you've got the "raw" exponent and mantissa - the rest of the code just helps to treat them in a simpler fashion.
这些评论当时对我来说很有意义,但我相信我现在必须考虑一段时间。在第一部分之后,您已经获得了“原始”指数和尾数 - 其余代码只是帮助以更简单的方式处理它们。
回答by Jimmy
The representation is a IEEE standard and shouldn't change.
该表示是 IEEE 标准,不应更改。
https://msdn.microsoft.com/en-us/library/system.double(v=vs.110).aspx
https://msdn.microsoft.com/en-us/library/system.double(v=vs.110).aspx
The Double type complies with the IEC 60559:1989 (IEEE 754) standard for binary floating-point arithmetic.
Double 类型符合 IEC 60559:1989 (IEEE 754) 二进制浮点运算标准。
EDIT: The reason why decimal has a getBits and double does not is that decimal preserves significant digits. 3.0000m == 3.00m but the exponents/mantissas are actually different. I think floats/doubles are uniquely represented.
编辑:decimal 有 getBits 而double 没有的原因是decimal 保留了有效数字。3.0000m == 3.00m 但指数/尾数实际上是不同的。我认为浮动/双打是唯一代表。