我在数学和计算机科学的阅读中看到过几次使用等价符号≡
(基本上是带有三条线的“=”),并且总是习惯将其读作相等。这两个概念之间有什么区别?
=
通常表示两个物体相等,而等价符号 ≡
则表示两个物体在某些方面等价或具有相同的属性,但不一定完全相等。 在计算机科学中,等价关系通常指两个对象具有相同的结构或行为。 例如,如果两个算法最终会产生相同的结果,则可以说它们是等价的。我在数学和计算机科学的阅读中看到过几次使用等价符号≡
(基本上是带有三条线的“=”),并且总是习惯将其读作相等。这两个概念之间有什么区别?
=
通常表示两个物体相等,而等价符号 ≡
则表示两个物体在某些方面等价或具有相同的属性,但不一定完全相等。 在计算机科学中,等价关系通常指两个对象具有相同的结构或行为。 例如,如果两个算法最终会产生相同的结果,则可以说它们是等价的。在数学中,等价关系是一个将某个集合内的两个元素“等同”起来的二元关系。设a、b和c为集合X内任意元素,则“a ~ b”或“a ≡ b”表示a等价于b。
等价关系“~”具有自反性、对称性和传递性。
换句话说,等号就是等价关系的一种实例。
编辑:这看似简单的自反性、对称性和传递性标准并不总是显然的。例如,可参考Bloch著《Effective Java》第二版35页。
public final class CaseInsensitiveString {
...
// broken
@Override public boolean equals(Object o) {
if (o instance of CaseInsensitiveString)
return s.equalsIgnoreCase(
((CaseInsensitiveString) o).s);
if (o instanceof String) // One-way interoperability!
return s.equalsIgnoreCase((String) o);
return false;
}
}
上述的等于实现破坏了对称性,因为CaseInsensitiveString
知道String
类,但是String
类不知道CaseInsensitiveString
。
我理解你的问题是关于数学符号表示而不是编程。你所提到的三个等号可以在HTML中写作≡
,在LaTeX中写作\equiv
。
通常情况下,a ≡ b 表示“a被定义为b”或“使a等于b”。
因此,2+2=4,但是φ ≡ (1+sqrt(5))/2。
以下是一个方便的等价表:
Mathematicians Computer scientists
-------------- -------------------
= ==
≡ =
其他关于等价关系的回答也是正确的,但我认为它们不够常见。还有一种形式为 ≡ b (mod m) 的等式,发音为“a与b在模m意义下同余”,在程序员的术语中可以表示为 mod(a,m) == mod(b,m)。换句话说,在模m的情况下,a和b相等。
在我所见过区分等号和等价的语言中,等号通常表示类型和值都相同,而等价则只表示值相同。例如:
int i = 3;
double d = 3.0;
i和d之间具有等价关系,因为它们代表相同的值,但不是相等关系,因为它们具有不同的类型。其他语言可能会对等价关系有不同的理解(比如两个变量是否代表相同的对象)。
把它从编程的领域带出去。
(31) equal -- (具有与另一个相同的数量、价值或度量; "以平等条件"; "所有人在法律面前都是平等的")
equivalent, tantamount -- (本质上相当于某物; "它和黄金一样好"; "一个愿望相当于一条命令"; "他的陈述与承认有罪等同")
至少在我的字典中,“equivalence”表示它是原始物品的足够好的替代,但不一定完全相同,同样,“equality”传达了完全相同的意思。
null == 0 # true , null is equivelant to 0 ( in php )
null === 0 # false, null is not equal to 0 ( in php )
你可能会有两个具有相同真值(等价)的语句或两个相同的语句(等式)。同时,“带三条杠的等号”也可以表示“定义为”。
违反这一期望的最极端例子是C++:如果x == y
的结果为true
,则称x
和y
为相等,如果!(x < y) && !(y < x)
成立,则称x
和y
为等价。即使不考虑用户自定义重载操作符,在浮点数(float
、double
)情况下也存在差异:所有的NaN值彼此等价(实际上与任何其他值都等价),但与包括自身在内的任何其他值都不相等,而值-0.0
和+0.0
比较相等(且等价),尽管聪明的人可以区分它们。
在许多情况下,您需要更准确的术语来传达您的意图。给定两个变量x
和y
,
x
和y
都指向它。通过x
做的任何更改都会无意中通过y
观察到,反之亦然。在Java中,使用==
检查引用类型变量的身份,在C#中使用ReferenceEquals
方法。在C++中,如果x
和y
是引用,std::addressof(x) == std::addressof(y)
可以使用(而&x == &y
大部分情况下也可以工作,但&
可以针对用户定义的类型进行自定义)。x
和y
的内部表示相同。请注意,当对象在内部可以引用(部分)自身时,按位相等会失效。为了获得预期的含义,在这种情况下,概念必须被细化为:结构相同。在D中,可以通过is
来检查按位相等,C提供了memcmp
。我不知道有哪种语言内置了结构相等测试。f
接受两个参数,并且x
和y
是不可区分的,则调用f(x, y)
、f(x, x)
和f(y, y)
始终返回不可区分的值 - 除非f
直接检查身份(参见上面的要点)或者可能通过改变参数来检查身份。一个例子可以是两个恰好包含不可区分元素的搜索树,但内部树的布局不同。内部树布局是通常无法通过其公共方法观察到的实现细节。+0.0
不同的负零-0.0
,例如sign(1/x)
对于-0.0
和+0.0
是不同的。许多具有C语言风格(也称为Algol语法)的语言使用==
来检查浮点数的等价性。大多数面向对象的语言使用equals
(或类似命名的)方法来检查对象的等价性。C#有IEquatable<T>
接口,用于指定类上定义了一个标准/规范/默认的等价关系。在Java中,每个类都继承自Object
,需要重写equals
方法。正如您所看到的,这些概念变得越来越模糊。检查身份是大多数语言都可以表达的。身份和位等价通常无法被程序员钩取,因为这些概念与解释无关。曾经有一个C++20提案被拒绝了,它将引入最后两个概念作为强†和弱相等†。(† 网页已经不存在,404。)原始论文在这里。
有一些没有变异的语言,主要是函数式语言,例如Haskell。在那里,等号和等价性之间的区别不太重要,而更倾向于这些词在数学上的使用。(在数学中,一般情况下使用(递归定义的)序列代替重新赋值。)
C语言拥有的一切,同样适用于C++和任何能够使用C功能的语言。关于C#的所有说法也适用于Visual Basic .NET,以及可能是构建在.NET框架上的所有语言。类似地,Java代表了JRE语言,其中还包括Kotlin和Scala。实际上,相等性确实是一种特殊的等价关系。考虑下面这个说法:
0.9999999999999999... = 1
<
也不是>
的概念。这是一种用于排序稳定性和算法行为等方面的有用术语。 - Tomasz Gandor