在Silverlight Toolkit中有这种方法:
/// <summary>
/// Removes the noise from double math.
/// </summary>
/// <param name="value">The value.</param>
/// <returns>A double without a noise.</returns>
internal static double RemoveNoiseFromDoubleMath(double value)
{
if (value == 0.0 || Math.Abs((Math.Log10(Math.Abs(value)))) < 27)
{
return (double)((decimal)value);
}
return Double.Parse(value.ToString(CultureInfo.InvariantCulture), CultureInfo.InvariantCulture);
}
我不明白目的是什么,在.Net中做数学的双打是否有噪音?
使用双精度数转换为双精度数是多少?
为什么ToString是Parse?
我写了一个快速测试项目来生成一些随机数并通过该方法运行它,我没有看到任何变化(不是我认为我会)。
答案 0 :(得分:1)
这样做的目的是减轻继承到浮点运算的舍入差异。
例如,如果您采用以下代码段:
double result = 1.0 / 7.0;
double difference = result - RemoveNoiseFromDoubleMath(result);
Console.WriteLine(difference);
这产生-1,38777878078145E-16的差异。
答案 1 :(得分:0)
真的很棒,这个函数有一个注释块,实际上并没有解释它实际上要处理的“噪音”是什么,以及它如何影响价值。
我读它的方式,如果数字少于27个基数-10位数(或正好为零),它将转换为小数,然后再转换为双精度数。我原本预计转换为十进制应该对该值没有影响,因为十进制的分辨率高于double。转换回双倍应该再次无损。
Pieter的例子表明,这个操作实际上确实会影响该值,因此显然从double到decimal和back的转换都不是保值,即使它们可以。看看msdn,我看到了这个: http://msdn.microsoft.com/en-us/library/yht2cx7b(v=VS.80).aspx
说:
将float或double转换为 十进制,转换源值 到十进制表示和舍入 在28日之后到最近的数字 小数位,如果需要的话。
好的,所以它是圆的。这意味着如果您有一个值为1.9999999999999999999999999999的double,则转换为十进制会将其四舍五入为2,因此当它转换回double时,您将得到一个值为2.0的double。
如果数字超过27位,它将转换为字符串,然后进行解析。我不确定最终结果是什么 - 它将取决于ToString和Double.parse的默认行为。