比较 double.MaxValue 是否相等是个好主意吗?

发布于 2024-11-03 02:31:40 字数 143 浏览 4 评论 0原文

同样的问题也可以问 float... 或 MinValue。

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

澄清:我用它作为哨兵值。

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

Same question can be asked of float... or of MinValue.

I am thinking of using it as a special value. Will i see bugs due to precision? I don't expect to do arithmetic with these numbers, just set them and that's it.

Clarification: I am using this for a sentinel value.

Is it something that's described in a C# spec?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

任性一次 2024-11-10 02:31:41

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

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

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

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

  • NaN
  • 负无穷
  • 正无穷

If you compare double.MaxValue to double.MaxValue, yes they will be the same. The binary representation is identical, there won't be a problem. If, on the other hand, you try something like:

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

then yes you'll probably start seeing weird precision issues pop up.

The following are special constants that can't be compared to themselves. Anything else is fair game.

  • NaN
  • NegativeInfinity
  • PositiveInfinity
一绘本一梦想 2024-11-10 02:31:41

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

double? val = ...;

if(val.HasValue)
    // do something with val.Value

If you want a "special" value, my suggestion would be to use Nullable instead:

double? val = ...;

if(val.HasValue)
    // do something with val.Value
哽咽笑 2024-11-10 02:31:41

使用“特殊值”通常是不好的做法。我更喜欢使用带有某种状态代码的对象,然后使用仅在状态非异常时才填充的 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
}

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

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

Using "special values" is generally bad practice. I would prefer to use an object with some kind of status code, and then a double(/float/whatever) that is only populated if the status is non-exceptional.

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
}

You could even do some fancy operator overloading to make for easy conversion and arithmetic if you need to.

Regarding precision issues, since it sounds like you're not planning to do arithmetic on this number, so you shouldn't run into precision issues that prevent the equality check from working.

对不⑦ 2024-11-10 02:31:41

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

I don't think it should be a problem. I don't have a technical explanation but I've used MaxValue or MinValue for comparisons many times and it's never been an issue.

一笑百媚生 2024-11-10 02:31:40

这取决于你如何使用它。

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

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

It depends on how you use it.

If you're using double.MaxValue as a token or sentinel value that has special semantics, then yes, it's just a bit pattern that you're comparing against. For example, you could use double.MaxValue to indicate an "uninitialized" or "unknown" value. There are other ways to do this (e.g. with the nullable double?), but using double.MaxValue is also reasonable assuming the value doesn't naturally occur in your domain.

If you have some arbitrary double value, though, and you want to see if it's "equal" to double.MaxValue, then you'll want to see if the numbers are within some small range (epsilon) of each other since some precision could've been lost when computing your other double value. The issue to be aware of here is with values that go beyond double.MaxValue, creating an overflow situation.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文