C#NaN等于之间的比较差异()和== [英] c# NaN comparison differences between Equals() and ==

查看:174
本文介绍了C#NaN等于之间的比较差异()和==的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

检查了这一点:

    var a = Double.NaN;

    Console.WriteLine(a == a);
    Console.ReadKey();



版画假

Prints "False"

    var a = Double.NaN;

    Console.WriteLine(a.Equals(a));
    Console.ReadKey();



打印真!

Prints "True"!

为什么它打印真?由于浮点数规范,值是NaN不等于本身!如此看来,equals()方法来实现错了...
我缺少的东西吗?

Why it prints "True"? Due to floating point numbers specification, value that is NaN is not equal to itself! So it seems that Equals() method is implemented wrong... Am I missing something ?

推荐答案

我发现文章解决你的问题: .NET安全博客:为什么==和equals方法返回不同的结果为浮点值

I found an article addressing your question: .NET Security Blog: Why == and the Equals Method Return Different Results for Floating Point Values

根据IEC 60559:1989,二
浮点数值与
NaN的是从来没有平等的。不过,根据该规范为
System.Object的
:: equals方法,它是
需要重写此方法以
提供价值相等的语义。
[...]

According to IEC 60559:1989, two floating point numbers with values of NaN are never equal. However, according to the specification for the System.Object::Equals method, it's desirable to override this method to provide value equality semantics. [...]

所以现在我们有两个相互矛盾的想法$什么等于应该意味着B $湾
::对象等于说,BCL值
类型应该重写提供价值
平等和IEC 60559说,NaN的
不等于NaN的。
的ECMA规范的划分由我做附注约
段在特定情况8.2.5.2 [下文]

So now we have two conflicting ideas of what Equals should mean. Object::Equals says that the BCL value types should override to provide value equality, and IEC 60559 says that NaN does not equal NaN. Partition I of the ECMA spec provides resolution for this conflict by making a note about this specific case in section 8.2.5.2 [below]

更新:部分8.2.5从的the CLI规范(ECMA-335)揭示了一些这方面的更多的光。我在这里复制的相关位:


Update: The full text of section 8.2.5 from the CLI spec (ECMA-335) sheds some more light on this. I've copied the relevant bits here:

有所有的对数值定义
二元算:身份的和
平等的。他们返回一个布尔结果,而数学
等价运营商的;也就是说,它们是:

8.2.5 Identity and equality of values

There are two binary operators defined on all pairs of values: identity and equality. They return a Boolean result, and are mathematical equivalence operators; that is, they are:


  • 反思 - A OP一个是真实的

  • 对称 - A OP b 为真,当且仅当 b OP一个是真的

  • 传递 - 如果 A OP b 的真实, b OPç为真,那么 A OPç
    真。

  • Reflexive – a op a is true.
  • Symmetric – a op b is true if and only if b op a is true.
  • Transitive – if a op b is true and b op c is true, then a op c is true.

此外,虽然身份总是
意味着平等,反之则不是
真。 [...]

In addition, while identity always implies equality, the reverse is not true. [...]

身份运营商是由CTS定义如下。

The identity operator is defined by the CTS as follows.


  • 如果该值具有不同确切类型,那么它们不相同。

  • 否则,如果他们的确切类型是值类型,那么它们是相同的,如果
    且仅当
    值的比特序列一样,点点滴滴。

  • 否则,如果他们的确切类型是引用类型,那么它们是
    相同,当且仅当值的位置
    相同。

身份通过的ReferenceEquals 方法上的 System.Object的实施

有关值类型,等于运算符
是精确的$定义的一部分b $ b型。平等的定义应该
遵循以下规则:

For value types, the equality operator is part of the definition of the exact type. Definitions of equality should obey the following rules:


  • 平等应该是一个等价运算符,如上面所定义

  • 身份应该意味着平等,如前所述。

  • 如果(或两者)操作数是装箱值,[...]

平等是通过
System.Object的实施等号

Equality is implemented on System.Object via the Equals method.

[注意的:虽然两个浮点数
NaN是由定义IEC 60559:1989至
始终比较不平等,为System.Object.Equals

合同要求覆盖必须满足
为等价
运营商的要求。因此,
System.Double.Equals
System.Single.Equals 返回True $比较当两个非数字,而
等于运算符将返回
这种情况​​下假,所要求的IEC
标准b $ b。 注完的]

[Note: Although two floating point NaNs are defined by IEC 60559:1989 to always compare as unequal, the contract for System.Object.Equals requires that overrides must satisfy the requirements for an equivalence operator. Therefore, System.Double.Equals and System.Single.Equals return True when comparing two NaNs, while the equality operator returns False in that case, as required by the IEC standard. end note]

以上不指定的属性== 在所有运营商(除了最后要注意的);它主要是定义的ReferenceEquals 的行为和等于。对于 == 运营商的 C#语言规范(ECMA-334)(第14.9.2)明确如何对待NaN值:

The above does not specify the properties of the == operator at all (except for the final note); it is primarily defining the behavior of ReferenceEquals and Equals. For the behavior of the == operator, the C# language spec (ECMA-334) (section 14.9.2) is clear about how to treat NaN values:

如果操作数[以运算符== ]是NaN,结果为false

If either operand [to operator ==] is NaN, the result is false

这篇关于C#NaN等于之间的比较差异()和==的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆