An ordered comparison checks if neither operand is NaN. Conversely, an unordered comparison checks if either operand is a NaN.
This page gives some more information on this:
- http://csapp.cs.cmu.edu/public/waside/waside-sse.pdf (section 5)
The idea here is that comparisons with NaN are indeterminate. (can’t decide the result) So an ordered/unordered comparison checks if this is (or isn’t) the case.
double a = 0.;
double b = 0.;
__m128d x = _mm_set1_pd(a / b); // NaN
__m128d y = _mm_set1_pd(1.0); // 1.0
__m128d z = _mm_set1_pd(1.0); // 1.0
__m128d c0 = _mm_cmpord_pd(x,y); // NaN vs. 1.0
__m128d c1 = _mm_cmpunord_pd(x,y); // NaN vs. 1.0
__m128d c2 = _mm_cmpord_pd(y,z); // 1.0 vs. 1.0
__m128d c3 = _mm_cmpunord_pd(y,z); // 1.0 vs. 1.0
__m128d c4 = _mm_cmpord_pd(x,x); // NaN vs. NaN
__m128d c5 = _mm_cmpunord_pd(x,x); // NaN vs. NaN
cout << _mm_castpd_si128(c0).m128i_i64[0] << endl;
cout << _mm_castpd_si128(c1).m128i_i64[0] << endl;
cout << _mm_castpd_si128(c2).m128i_i64[0] << endl;
cout << _mm_castpd_si128(c3).m128i_i64[0] << endl;
cout << _mm_castpd_si128(c4).m128i_i64[0] << endl;
cout << _mm_castpd_si128(c5).m128i_i64[0] << endl;
Result:
0
-1
-1
0
0
-1
Ordered return true if the operands are comparable (neither number is NaN):
- Ordered comparison of
1.0and1.0givestrue. - Ordered comparison of
NaNand1.0givesfalse. - Ordered comparison of
NaNandNaNgivesfalse.
Unordered comparison is the exact opposite:
- Unordered comparison of
1.0and1.0givesfalse. - Unordered comparison of
NaNand1.0givestrue. - Unordered comparison of
NaNandNaNgivestrue.