- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
哪些指令将用于比较由4 * 32位浮点值组成的两个128位向量?
是否有一条指令将两侧的NaN值视为相等?如果不是,提供反射性(即,NaN等于NaN)的变通方法对性能的影响有多大?
我听说,与NaN不等同于IEEE语义的IEEE语义相比,确保反射性会对性能产生重大影响,我想知道这种影响是否会很大。
我知道您通常在处理浮点值时要使用epsilon比较而不是精确的质量。但是这个问题是关于精确相等比较的,例如,您可以使用它来消除哈希集中的重复值。
要求+0
和-0
必须相等。NaN
必须与自身进行比较。
NaN的不同表示形式应该相等,但是如果对性能的影响太大,则可能会牺牲该要求。
如果两个向量中的所有四个float元素都相同,则结果应为布尔值true
,如果至少一个元素不同,则结果为false。其中,true
用标量整数1
表示,false
用0
表示。
测试用例
(NaN, 0, 0, 0) == (NaN, 0, 0, 0) // for all representations of NaN
(-0, 0, 0, 0) == (+0, 0, 0, 0) // equal despite different bitwise representations
(1, 0, 0, 0) == (1, 0, 0, 0)
(0, 0, 0, 0) != (1, 0, 0, 0) // at least one different element => not equal
(1, 0, 0, 0) != (0, 0, 0, 0)
NotLessThan
组合两个
CMPNLTPS
比较(
and
?)以达到所需的结果。等效于
AllTrue(!(x < y) and !(y < x))
或
AllFalse((x < y) or (y > x)
的汇编器。
.Equals
方法争论的地方,需要更清晰地了解此自反等式对IEEE均衡器的性能影响有多大。有关详细信息,请参见programmers.se上的
Should Vector<float>.Equals
be reflexive or should it follow IEEE 754 semantics?。
最佳答案
甚至AVX VCMPPS(具有大大增强的谓词选择)也无法为我们提供单指令谓词。您必须至少进行两次比较并合并结果。不过还算不错。
不同的NaN编码不相等:实际上是2个额外的insn(增加了2个uops)。没有AVX:超出此范围后再增加一个movaps
。
不同的NaN编码是相等的:实际上有4个额外的insn(加了4个uops)。没有AVX:两个额外的movaps
insn
IEEE比较和分支为3微秒:cmpeqps
/ movmskps
/测试和分支。 Intel和AMD都将测试分支与宏融合到单个uop / m-op中。
使用AVX512:逐位NaN可能只是一条额外的指令,因为正常的向量比较和分支可能使用vcmpEQ_OQps
/ ktest same,same
/ jcc
,因此组合两个不同的掩码reg是免费的(只需将args更改为ktest
)。唯一的成本是额外的vpcmpeqd k2, xmm0,xmm1
。
AVX512 any-NaN只是两个额外的指令(2x VFPCLASSPS
,第二个指令使用第一个指令的结果作为零掩码。请参见下文)。同样,然后ktest
用两个不同的args设置标志。
到目前为止,我最好的主意:ieee_equal || bitwise_equal
如果我们放弃考虑彼此相等的不同NaN编码:
按位相等捕获两个相同的NaN。
IEEE equal捕获+0 == -0
情况。
在任何情况下都不存在比较结果为假的情况(因为当任一操作数为NaN时ieee_equal
为false:我们希望相等,而不是相等或无序。AVXvcmpps
提供两种选择,而SSE仅提供普通选择均等操作。)
我们想知道何时所有元素都相等,因此我们应该从反向比较开始。检查至少一个非零元素比检查所有非零元素要容易。 (即,水平与比较难,水平或比较容易(pmovmskb
/ test
或ptest
)。相反的比较是免费的(jnz
代替jz
)。)保罗R使用的相同技巧。
; inputs in xmm0, xmm1
movaps xmm2, xmm0 ; unneeded with 3-operand AVX instructions
cmpneqps xmm2, xmm1 ; 0:A and B are ordered and equal. -1:not ieee_equal. predicate=NEQ_UQ in VEX encoding expanded notation
pcmpeqd xmm0, xmm1 ; -1:bitwise equal 0:otherwise
; xmm0 xmm2
; 0 0 -> equal (ieee_equal only)
; 0 -1 -> unequal (neither)
; -1 0 -> equal (bitwise equal and ieee_equal)
; -1 -1 -> equal (bitwise equal only: only happens when both are NaN)
andnps xmm0, xmm2 ; NOT(xmm0) AND xmm2
; xmm0 elements are -1 where (not bitwise equal) AND (not IEEE equal).
; xmm0 all-zero iff every element was bitwise or IEEE equal, or both
movmskps eax, xmm0
test eax, eax ; it's too bad movmsk doesn't set EFLAGS according to the result
jz no_differences
...PS
和
pcmpeqQ
将相同。
movmskps
结果进行位扫描将为您提供第一个差异的位置。
PTEST
,您可以将
andnps
/
movmskps
/ test-and-branch替换为:
ptest xmm0, xmm2 ; CF = 0 == (NOT(xmm0) AND xmm2).
jc no_differences
CF
的
PTEST
结果对任何事情都有用。 :)
setcc
或
cmovcc
而不是
jcc
,则效率会更高,因为这些宏无法与
test
进行宏融合。
cmpeqps
/
movmskps
/测试和分支。)
PTEST
在AMD Bulldozer系列CPU(
14c on Steamroller)上具有很高的延迟。它们具有两个整数内核共享的一组矢量执行单元。 (这是超线程的替代方法。)这增加了直到可以检测到分支错误预测或数据依赖链的延迟(
cmovcc
/
setcc
)的时间。
ZF
时设置
0==(xmm0 AND xmm2)
:如果两个元素都不都是
bitwise_equal
和IEEE(neq或无序),则设置。即,如果任何元素为
bitwise_equal
且同时为
!ieee_equal
,则未设置ZF。这仅在一对元素包含按位等于
NaN
时才会发生(但在其他元素不相等时可能发生)。
movaps xmm2, xmm0
cmpneqps xmm2, xmm1 ; 0:A and B are ordered and equal.
pcmpeqd xmm0, xmm1 ; -1:bitwise equal
ptest xmm0, xmm2
jc equal_reflexive ; other cases
...
equal_reflexive:
setnz dl ; set if at least one both-nan element
CF=1
和有关
ZF
的任何内容。
ja
测试
CF=0 and ZF=1
。无论如何,您不太可能只想进行测试,因此在
jnz
分支目标中放置
jc
可以正常工作。 (如果您只想测试
equal_reflexive
和
at_least_one_nan
,则其他设置可能会适当地设置标志)。
; inputs in xmm0, xmm1
movaps xmm2, xmm0
cmpordps xmm2, xmm2 ; find NaNs in A. (0: NaN. -1: anything else). Same as cmpeqps since src and dest are the same.
movaps xmm3, xmm1
cmpordps xmm3, xmm3 ; find NaNs in B
orps xmm2, xmm3 ; 0:A and B are both NaN. -1:anything else
cmpneqps xmm0, xmm1 ; 0:IEEE equal (and ordered). -1:unequal or unordered
; xmm0 AND xmm2 is zero where elements are IEEE equal, or both NaN
; xmm0 xmm2
; 0 0 -> equal (ieee_equal and both NaN (impossible))
; 0 -1 -> equal (ieee_equal)
; -1 0 -> equal (both NaN)
; -1 -1 -> unequal (neither equality condition)
ptest xmm0, xmm2 ; ZF= 0 == (xmm0 AND xmm2). Set if no differences in any element
jz equal_reflexive
; else at least one element was unequal
; alternative to PTEST: andps xmm0, xmm2 / movmskps / test / jz
PTEST
的
CF
结果。我们使用
PCMPEQD
时会这样做,因为它没有反数(
cmpunordps
具有
cmpordps
的方式)。
movaps
。)但是,Skylake SnB系列之前的CPU只能在p1上运行
cmpps
,因此,如果吞吐量,则FP-add单元上的瓶颈是一个问题。 Skylake在p0 / p1上运行
cmpps
。
andps
的编码比
pand
短,从Nehalem到Broadwell的Intel CPU只能在port5上运行。可能需要防止它从周围的FP代码中窃取p0或p1周期。否则,
pandn
可能是一个更好的选择。在AMD BD系列上,
andnps
始终在ivec域中运行,因此您不能避免int和FP向量之间的绕过延迟(否则,如果您使用
movmskps
而不是
ptest
可能会希望避免这种情况,在此版本中仅使用
cmpps
,而不使用
pcmpeqd
)。还要注意,此处为了便于阅读而选择了指令顺序。将FP compare(A,B)放在
ANDPS
之前,可以帮助CPU更快地开始该周期。
movaps
/
cmpps
。
vcmpps
的操作数之一是已知没有任何NaN的向量(例如,零位寄存器),则
vcmpunord_qps xmm2, xmm15, [rsi]
将在
[rsi]
中找到NaN。
PTEST
,则可以通过使用相反的比较,但是将它们与相反的逻辑运算符(AND与OR)相结合,可以得到相同的结果。
; inputs in xmm0, xmm1
movaps xmm2, xmm0
cmpunordps xmm2, xmm2 ; find NaNs in A (-1:NaN 0:anything else)
movaps xmm3, xmm1
cmpunordps xmm3, xmm3 ; find NaNs in B
andps xmm2, xmm3 ; xmm2 = (-1:both NaN 0:anything else)
; now in the same boat as before: xmm2 is set for elements we want to consider equal, even though they're not IEEE equal
cmpeqps xmm0, xmm1 ; -1:ieee_equal 0:unordered or unequal
; xmm0 xmm2
; -1 0 -> equal (ieee_equal)
; -1 -1 -> equal (ieee_equal and both NaN (impossible))
; 0 0 -> unequal (neither)
; 0 -1 -> equal (both NaN)
orps xmm0, xmm2 ; 0: unequal. -1:reflexive_equal
movmskps eax, xmm0
test eax, eax
jnz equal_reflexive
NaN
的编码。 (
Try it out。也许我们可以避免使用
POR
或
PAND
在每个操作数上分别合并
cmpps
的结果?
; inputs in A:xmm0 B:xmm1
movaps xmm2, xmm0
cmpordps xmm2, xmm2 ; find NaNs in A. (0: NaN. -1: anything else). Same as cmpeqps since src and dest are the same.
; cmpunordps wouldn't be useful: NaN stays NaN, while other values are zeroed. (This could be useful if ORPS didn't exist)
; integer -1 (all-ones) is a NaN encoding, but all-zeros is 0.0
cmpunordps xmm2, xmm1
; A:NaN B:0 -> 0 unord 0 -> false
; A:0 B:NaN -> NaN unord NaN -> true
; A:0 B:0 -> NaN unord 0 -> true
; A:NaN B:NaN -> 0 unord NaN -> true
; Desired: 0 where A and B are both NaN.
cmpordps xmm2, xmm1
只是翻转每种情况的最终结果,“奇数输出”仍位于第一行。
cmpordps
之后将
pand
的想法用作
cmpordps self,self
的替代。这没有用:即使我们有AVX但没有AVX2,我们也可以使用
vandps
和
vandnps
(和
vmovmskps
,因为
vptest
仅是AVX2)。按位布尔值仅是单周期延迟,不要占用向量FP添加执行端口,该端口已经是此代码的瓶颈。
VFIXUPIMMPS
vcmpneqps
然后用每个源操作数修复该结果(以消除合并3个
vcmpps
指令结果的布尔指令)。我现在相当确定这是不可能的,因为仅仅知道一个操作数是NaN本身还不足以更改
IEEE_equal(A,B)
结果。
vfixupimmps
的唯一方法是分别检测每个源操作数中的NaN,就像
vcmpunord_qps
一样,但更糟。或作为
andps
,在先前比较的掩码结果中检测到0或全1(NaN)。
VFPCLASSPS k2 {k1}, xmm2, imm8
写入屏蔽寄存器,可以选择由其他屏蔽寄存器屏蔽。通过仅设置imm8的QNaN和SNaN位,我们可以得到向量中存在NaN的掩码。通过设置所有其他位,我们可以求逆。
vfpclassps
的零掩码,我们只需两个指令即可找到两个NaN位置,而不是通常的cmp / cmp / combine。因此,我们保存了
or
或
andn
指令。顺便说一句,我想知道为什么没有OR-NOT操作。它出现的频率可能比“与非”运算的发生率甚至更低,或者他们只是不想在指令集中使用
porn
。
; I think this works
; 0x81 = CLASS_QNAN|CLASS_SNAN (first and last bits of the imm8)
VFPCLASSPS k1, zmm0, 0x81 ; k1 = 1:NaN in A. 0:non-NaN
VFPCLASSPS k2{k1}, zmm1, 0x81 ; k2 = 1:NaNs in BOTH
;; where A doesn't have a NaN, k2 will be zero because of the zeromask
;; where B doesn't have a NaN, k2 will be zero because that's the FPCLASS result
;; so k2 is like the bitwise-equal result from pcmpeqd: it's an override for ieee_equal
vcmpNEQ_UQps k3, zmm0, zmm1
;; k3= 0 only where IEEE equal (because of cmpneqps normal operation)
; k2 k3 ; same logic table as the pcmpeqd bitwise-NaN version
; 0 0 -> equal (ieee equal)
; 0 1 -> unequal (neither)
; 1 0 -> equal (ieee equal and both-NaN (impossible))
; 1 1 -> equal (both NaN)
; not(k2) AND k3 is true only when the element is unequal (bitwise and ieee)
KTESTW k2, k3 ; same as PTEST: set CF from 0 == (NOT(k2) AND k2)
jc .reflexive_equal
vfpclassps
insn重用与零掩码和目标相同的掩码寄存器,但是如果要在注释中区分它们,我使用了不同的寄存器。该代码至少需要两个掩码寄存器,而无需额外的向量寄存器。我们也可以使用
k0
代替
k3
作为
vcmpps
的目的地,因为我们不需要将其用作谓词,而仅将其用作dest和src。 (
k0
是不能用作谓词的寄存器,因为该编码方式表示“无掩码”。)
reflexive_equal
结果创建单个蒙版,而无需
k...
指令在某个点上将两个蒙版组合在一起(例如,用
kandnw
代替
ktestw
)。掩码仅用作零掩码,不能用作可将结果强制为1的掩码,因此将
vfpclassps
结果组合只能作为AND。因此,我认为我们一直坚持使用1-means-both-NaN,这是将其用作
vcmpps
的零掩码的错误认识。先执行
vcmpps
,然后将掩码寄存器用作
vfpclassps
的目的地和谓词,也没有帮助。合并屏蔽而不是零屏蔽可以解决问题,但是在写入屏蔽寄存器时不可用。
;;; Demonstrate that it's hard (probably impossible) to avoid using any k... instructions
vcmpneq_uqps k1, zmm0, zmm1 ; 0:ieee equal 1:unequal or unordered
vfpclassps k2{k1}, zmm0, 0x81 ; 0:ieee equal or A is NaN. 1:unequal
vfpclassps k2{k2}, zmm1, 0x81 ; 0:ieee equal | A is NaN | B is NaN. 1:unequal
;; This is just a slow way to do vcmpneq_Oqps: ordered and unequal.
vfpclassps k3{k1}, zmm0, ~0x81 ; 0:ieee equal or A is not NaN. 1:unequal and A is NaN
vfpclassps k3{k3}, zmm1, ~0x81 ; 0:ieee equal | A is not NaN | B is not NaN. 1:unequal & A is NaN & B is NaN
;; nope, mixes the conditions the wrong way.
;; The bits that remain set don't have any information from vcmpneqps left: both-NaN is always ieee-unequal.
ktest
最终像
ptest
一样是2 uops,并且不能进行宏熔断,则
kmov eax, k2
/ test-and-branch可能会比
ktest k1,k2
/ jcc便宜。希望它只会是一个uop,因为掩码寄存器更像是整数寄存器,并且可以从一开始就设计为在内部“接近”标志。经过许多代的设计,向量和
ptest
之间没有交互,仅在SSE4.1中添加了
EFLAGS
。
kmov
确实为您设置了popcnt,bsf或bsr。 (
bsf
/
jcc
不会进行宏保险,因此在搜索循环中,您可能仍想测试/ jcc,并且在发现非零值时仅希望bsf。对tzcnt进行编码的额外字节不会除非您正在做无分支的事情,否则不要买任何东西,因为即使dest寄存器未定义,
bsf
仍会将ZF设置为零输入。尽管
lzcnt
给出了
32 - bsr
,所以即使在您知道输入为非零。)
vcmpEQps
并以不同方式合并结果:
VFPCLASSPS k1, zmm0, 0x81 ; k1 = set where there are NaNs in A
VFPCLASSPS k2{k1}, zmm1, 0x81 ; k2 = set where there are NaNs in BOTH
;; where A doesn't have a NaN, k2 will be zero because of the zeromask
;; where B doesn't have a NaN, k2 will be zero because that's the FPCLASS result
vcmpEQ_OQps k3, zmm0, zmm1
;; k3= 1 only where IEEE equal and ordered (cmpeqps normal operation)
; k3 k2
; 1 0 -> equal (ieee equal)
; 1 1 -> equal (ieee equal and both-NaN (impossible))
; 0 0 -> unequal (neither)
; 0 1 -> equal (both NaN)
KORTESTW k3, k2 ; CF = set iff k3|k2 is all-ones.
jc .reflexive_equal
kortest
的大小与矢量中元素的数量完全匹配时,这种方法才有效。例如256b双精度元素向量仅包含4个元素,但是
kortestb
仍根据输入掩码寄存器的低8位设置CF。
+0
和
-0
的所有位均为零,除了
-0
设置了符号位(MSB)。
A OR B
均为0。根据是否需要覆盖按位,左移1将使其变为全零或非全零。 -相等测试。
cmpneqps
使用了一条指令,因为我们正在使用
por
/
paddD
模拟我们需要的功能。 (或
pslld
减一,但要长一个字节。它确实在与
pcmpeq
不同的端口上运行,但是您需要考虑周围代码的端口分布以将其纳入决策中。)
;inputs in xmm0:A xmm1:B
movaps xmm2, xmm0
pcmpeqd xmm2, xmm1 ; xmm2=bitwise_equal. (0:unequal -1:equal)
por xmm0, xmm1
paddD xmm0, xmm0 ; left-shift by 1 (one byte shorter than pslld xmm0, 1, and can run on more ports).
; xmm0=all-zero only in the +/- 0 case (where A and B are IEEE equal)
; xmm2 xmm0 desired result (0 means "no difference found")
; -1 0 -> 0 ; bitwise equal and +/-0 equal
; -1 non-zero -> 0 ; just bitwise equal
; 0 0 -> 0 ; just +/-0 equal
; 0 non-zero -> non-zero ; neither
ptest xmm2, xmm0 ; CF = ( (not(xmm2) AND xmm0) == 0)
jc reflexive_equal
cmpneqps
版本低一两个周期。
PTEST
的优势:在两个不同的操作数之间使用其ANDN,并在整个过程中使用其相对于零的比较。我们不能用
pandn / movmskps
替换它,因为我们需要检查所有位,而不仅仅是每个元素的符号位。
is_quiet
标志,以区分信令/静默NaN。另请参阅英特尔手册vol1,表4-3(
Floating-Point Number and NaN Encodings
)。
A > 0x7f800000
的无符号比较来检查NaN。 (
0x7f800000
是单精度+ Inf)。但是,请注意
pcmpgtd
/
pcmpgtq
是有符号整数比较。 AVX512F
VPCMPUD
是无符号比较(目标=屏蔽寄存器)。
!(a<b) && !(b<a)
!(a<b) && !(b<a)
建议无效,也不能对其进行任何修改。您不能仅从两个具有反向操作数的比较中分辨出一个NaN和两个NaN之间的差异。甚至混合谓词也无济于事:
VCMPPS
谓词无法将一个操作数为NaN与两个操作数为NaN进行区分,或取决于是第一个还是第二个操作数为NaN。因此,将它们组合在一起就不可能获得该信息。
VCMPPS
结果组合不足,但使用
A
和
B
以外的操作数确实有帮助。 (一个已知的非NaN向量或两次相同的操作数)。
pcmpeqd
没有反函数,因此我们不能使用其他逻辑运算符,而仍然可以对所有相等进行检验):
; inputs in xmm0, xmm1
movaps xmm2, xmm0
cmpeqps xmm2, xmm1 ; -1:ieee_equal. EQ_OQ predicate in the expanded notation for VEX encoding
pcmpeqd xmm0, xmm1 ; -1:bitwise equal
orps xmm0, xmm2
; xmm0 = -1:(where an element is bitwise or ieee equal) 0:elsewhere
movmskps eax, xmm0
test eax, eax
jnz at_least_one_equal
; else all different
PTEST
不能用这种方式,因为与OR组合是唯一有用的东西。
// UNFINISHED start of an idea
bitdiff = _mm_xor_si128(A, B);
signbitdiff = _mm_srai_epi32(bitdiff, 31); // broadcast the diff in sign bit to the whole vector
signbitdiff = _mm_srli_epi32(bitdiff, 1); // zero the sign bit
something = _mm_and_si128(bitdiff, signbitdiff);
关于assembly - SIMD指令用于浮点相等比较(NaN == NaN),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34951714/
我想使用 NetworkX Graph 对象作为 Python dict 中的键。但是,我不希望默认的比较行为(即通过对象的地址)。相反,我希望同构图是 dict 中相同元素的键。 此行为是否已在某处
这个问题已经有答案了: What is the most effective way for float and double comparison? (33 个回答) 已关闭 7 年前。 在您认为我
我正在学习 C 编程,为了练习,我找到了一个需要解决的任务。这有点像一个游戏,有人选择一个单词,其他人猜测字母。我必须检查有多少给定的单词可能是所选单词的正确答案。 输入: 3 3//数字 n 和 m
我两天前开始学习C,在做作业时遇到了问题。我们的目的是从字符数组中获取字符列表,并通过计算连续字符并将其替换为数字来缩短它。对“a4b5c5”说“aaaabbbbbccccc”。这是我到目前为止的代码
已关闭。此问题需要 debugging details 。目前不接受答案。 编辑问题以包含 desired behavior, a specific problem or error, and the
为什么我在 if 中的比较不起作用?答案应该是 8 但它返回 0。 function findMissing(missingArray){ var getArray = missing
我想知道为什么以下 JavaScript 比较会给出不同的结果。 (1==true==1) true (2==true==2) false (0==false==0) false (0==false)
我想知道是否有人可以帮助我完成这个程序。编写一个接受两个字符串的函数。该函数应该将这两个字符串与字典顺序上排在第一位的字符串组合起来。两个字符串之间应该有一个空格。在一行上打印结果字符串。在一行上打印
有谁知道一个免费的开源库(实用程序类),它允许您比较一个 Java bean 的两个实例并返回一个属性列表/数组,这两个实例的值不同?请发布一个小样本。 干杯 托马斯 最佳答案 BeanCompara
我是java新手。任何人都可以给出以下类声明的含义 public class ListNode, V> { K key; V value; ListNode next;
我需要用 C 语言计算和比较 3 种不同大小(100 * 100、1000 * 1000 和 10000 * 10000)的 2 个矩阵相乘的执行时间。我编写了以下简单代码来为 1000 * 1000
当我在 ACCESS 2007 中运行以下 SQL 时 Select Location, COUNT(ApartmentBuildings) AS TotalIBuildingsManaged Fro
根据我对互斥锁的了解——它们通常提供对共享资源的锁定功能。因此,如果一个新线程想要访问这个锁定的共享资源——它要么退出,要么必须不断轮询锁(并在等待锁时浪费处理器周期)。 但是,监视器具有条件变量,它
通常在编程中,不应该比较浮点数据类型是否相等,因为存储的值通常是近似值。 由于两个非整数 Oracle NUMBER 值的存储方式不同(以 10 为基数),是否可以可靠地比较它们是否相等? 最佳答案
使用 PowerShell 时,我们偶尔会比较不同类型的对象。一个常见的场景是 $int -eq $bool (即其中 0 -eq $false 、 0 -ne $true 和任何非零值仅等于真,但不
#include #define MAX 1000 void any(char s1[], char s2[], char s3[]); int main() { char string1[
我想比较两个日期。 从这两个日期中,我只使用 ToShortDateString() 获取日期组件, 如下所示。现在的问题是当我比较两个日期时。它的 throw 错误—— "Operator >= c
用户输入一个数字( float 或整数),并且它必须大于下限。 这是从 UITextField 获取数字的代码: NSNumberFormatter * f = [[NSNumberFormatter
我已经摆弄这段代码大约一个小时了,它让我难以置信。我认为解决方案相当简单,但我似乎无法弄清楚。无论如何,这里去。我制作了一个 javascript 函数来检查用户输入的字符,以便它只能接受 7 个字符
我不太明白为什么当我们在不覆盖 equals 的情况下比较具有相同类属性的两个实例时方法,它将给出 false .但它会给出 true当我们比较一个案例类的两个实例时。例如 class A(val
我是一名优秀的程序员,十分优秀!