可以对 float... 或 MinValue 提出相同的问题。
我正在考虑将其用作特殊值。我会因为精度而看到错误吗?我不希望对这些数字进行算术运算,只需设置它们即可。
澄清:我将其用于哨兵价值。
它是在 C# 规范中描述的吗?
可以对 float... 或 MinValue 提出相同的问题。
我正在考虑将其用作特殊值。我会因为精度而看到错误吗?我不希望对这些数字进行算术运算,只需设置它们即可。
澄清:我将其用于哨兵价值。
它是在 C# 规范中描述的吗?
这取决于你如何使用它。
如果您将double.MaxValue
其用作具有特殊语义的标记或哨兵值,那么是的,这只是您要比较的一种位模式。例如,您可以使用double.MaxValue
来指示“未初始化”或“未知”值。还有其他方法可以做到这一点(例如使用 nullable double?
),但double.MaxValue
假设该值不会自然地出现在您的域中,使用也是合理的。
但是,如果您有一些任意double
值,并且您想查看它是否“等于” double.MaxValue
,那么您将想查看这些数字是否在彼此之间的某个小范围(epsilon)内,因为可能已经丢失了一些精度在计算您的其他double
值时。这里要注意的问题是超出 的值double.MaxValue
,造成溢出情况。
如果您比较double.MaxValue
,double.MaxValue
是的,它们将是相同的。二进制表示是相同的,不会有问题。另一方面,如果您尝试以下操作:
double myDouble = (double.MaxValue - 3.1415) / 2;
if((myDouble * 2) + 3.1415 == double.MaxValue)
{
...
}
那么是的,您可能会开始看到奇怪的精度问题弹出。
以下是无法与自身进行比较的特殊常量。其他任何事情都是公平的游戏。
使用“特殊值”通常是不好的做法。我更喜欢使用带有某种状态代码的对象,然后是一个 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
}
如果需要,您甚至可以进行一些花哨的运算符重载,以便于转换和算术。
关于精度问题,因为听起来你不打算对这个数字进行算术运算,所以你不应该遇到阻止相等检查工作的精度问题。
如果您想要一个“特殊”值,我的建议是使用Nullable代替:
double? val = ...;
if(val.HasValue)
// do something with val.Value
我不认为这应该是一个问题。我没有技术解释,但我已经多次使用 MaxValue 或 MinValue 进行比较,这从来都不是问题。