8

可以对 float... 或 MinValue 提出相同的问题。

我正在考虑将其用作特殊值。我会因为精度而看到错误吗?我不希望对这些数字进行算术运算,只需设置它们即可。

澄清:我将其用于哨兵价值。

它是在 C# 规范中描述的吗?

4

5 回答 5

11

这取决于你如何使用它。

如果您将double.MaxValue其用作具有特殊语义的标记或哨兵值,那么是的,这只是您要比较的一种位模式。例如,您可以使用double.MaxValue来指示“未初始化”或“未知”值。还有其他方法可以做到这一点(例如使用 nullable double?),但double.MaxValue假设该值不会自然地出现在您的域中,使用也是合理的。

但是,如果您有一些任意double值,并且您想查看它是否“等于” double.MaxValue,那么您将想查看这些数字是否在彼此之间的某个小范围(epsilon)内,因为可能已经丢失了一些精度在计算您的其他double值时。这里要注意的问题是超出 的值double.MaxValue,造成溢出情况。

于 2011-04-21T22:19:47.300 回答
3

如果您比较double.MaxValuedouble.MaxValue是的,它们将是相同的。二进制表示是相同的,不会有问题。另一方面,如果您尝试以下操作:

double myDouble = (double.MaxValue - 3.1415) / 2;
if((myDouble * 2) + 3.1415 == double.MaxValue)
{
    ...
}

那么是的,您可能会开始看到奇怪的精度问题弹出。

以下是无法与自身进行比较的特殊常量。其他任何事情都是公平的游戏。

  • 负无穷大
  • 正无穷
于 2011-04-21T22:18:26.760 回答
1

使用“特殊值”通常是不好的做法。我更喜欢使用带有某种状态代码的对象,然后是一个 double(/float/whatever),只有在状态非异常时才会填充。

public class CalcNumber
{
    public CalcNumberStatus Status {get; private set;}
    public double Value {get; private set;}


    public CalcNumber(double value)
    {
        Status = CalcNumberStatus.Normal;
        Value = value;
    }

    public CalcNumber(CalcNumberStatus status)
    {
        if(status == CalcNumberStatus.Normal)
        {
            throw new Exception("Cannot create a normal CalcNumber without a value");
        }
        Status = status;
        Value = 0;
    }
}
public enum CalcNumberStatus 
{
    Normal,
    Error
}

如果需要,您甚至可以进行一些花哨的运算符重载,以便于转换和算术。

关于精度问题,因为听起来你不打算对这个数字进行算术运算,所以你不应该遇到阻止相等检查工作的精度问题。

于 2011-04-21T22:18:04.560 回答
1

如果您想要一个“特殊”值,我的建议是使用Nullable代替:

double? val = ...;

if(val.HasValue)
    // do something with val.Value
于 2011-04-21T22:19:58.873 回答
0

我不认为这应该是一个问题。我没有技术解释,但我已经多次使用 MaxValue 或 MinValue 进行比较,这从来都不是问题。

于 2011-04-21T22:18:40.730 回答