gpt4 book ai didi

c# - 为什么将 double.epsilon 添加到一个值会产生相同的值,完全相等?

转载 作者:IT王子 更新时间:2023-10-29 04:32:53 25 4
gpt4 key购买 nike

我有一个单元测试,测试边界:

[TestMethod]
[ExpectedException(typeof(ArgumentOutOfRangeException))]
public void CreateExtent_InvalidTop_ShouldThrowArgumentOutOfRangeException()
{
var invalidTop = 90.0 + Double.Epsilon;
new Extent(invalidTop, 0.0, 0.0, 0.0);
}

public static readonly double MAX_LAT = 90.0;

public Extent(double top, double right, double bottom, double left)
{
if (top > GeoConstants.MAX_LAT)
throw new ArgumentOutOfRangeException("top"); // not hit
}

我以为我可以通过向其添加最小可能的正 double 来使 90.0 超过边缘,但现在没有抛出异常,知道为什么吗?

在调试时,我看到 top 显示为 90,而它应该是 90.00000000...。

编辑:我应该更认真地考虑一下,90+Double.Epsilon 会失去分辨率。似乎最好的方法是进行一些位移。

解决方案:

[TestMethod]
[ExpectedException(typeof(ArgumentOutOfRangeException))]
public void CreateExtent_InvalidTop_ShouldThrowArgumentOutOfRangeException()
{
var invalidTop = Utility.IncrementTiny(90); // 90.000000000000014
// var sameAsEpsilon = Utility.IncrementTiny(0);
new Extent(invalidTop, 0, 0, 0);
}

/// <summary>
/// Increment a double-precision number by the smallest amount possible
/// </summary>
/// <param name="number">double-precision number</param>
/// <returns>incremented number</returns>
public static double IncrementTiny(double number)
{
#region SANITY CHECKS
if (Double.IsNaN(number) || Double.IsInfinity(number))
throw new ArgumentOutOfRangeException("number");
#endregion

var bits = BitConverter.DoubleToInt64Bits(number);

// if negative then go opposite way
if (number > 0)
return BitConverter.Int64BitsToDouble(bits + 1);
else if (number < 0)
return BitConverter.Int64BitsToDouble(bits - 1);
else
return Double.Epsilon;
}

/// <summary>
/// Decrement a double-precision number by the smallest amount possible
/// </summary>
/// <param name="number">double-precision number</param>
/// <returns>decremented number</returns>
public static double DecrementTiny(double number)
{
#region SANITY CHECKS
if (Double.IsNaN(number) || Double.IsInfinity(number))
throw new ArgumentOutOfRangeException("number");
#endregion

var bits = BitConverter.DoubleToInt64Bits(number);

// if negative then go opposite way
if (number > 0)
return BitConverter.Int64BitsToDouble(bits - 1);
else if (number < 0)
return BitConverter.Int64BitsToDouble(bits + 1);
else
return 0 - Double.Epsilon;
}

这就完成了工作。

最佳答案

根据 the documentation of Double.Epsilon :

The value of the Epsilon property reflects the smallest positive Double value that is significant in numeric operations or comparisons when the value of the Double instance is zero.

(强调我的。)

将它添加到 90.0 不会产生“90.0 之后的下一个最小值”,这只会再次产生 90.0。

关于c# - 为什么将 double.epsilon 添加到一个值会产生相同的值,完全相等?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27506477/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com