On Sun, 24 Nov 2024 17:29:00 +0100
Bonita Montero <
[email protected]> wrote:
This code combines finite values with NaN-values and Inf-values and
compares them with all basic comparison operators.
#include <iostream>
#include <limits>
using namespace std;
int main()
{
constexpr double
NaN = numeric_limits<double>::quiet_NaN(),
Inf = numeric_limits<double>::infinity(),
Finite = 1.0;
static struct value_t
{
char const *what;
double value;
} const values[] =
{
{ "Finite", Finite },
{ "Inf", Inf },
{ "NaN", NaN }
};
static struct op_t
{
char const *what;
bool (*op)( double, double );
} const ops[] =
{
{ "<", +[]( double a, double b ) { return a < b; } },
{ "<=", +[]( double a, double b ) { return a <= b; }
}, { "==", +[]( double a, double b ) { return a == b; } },
{ ">=", +[]( double a, double b ) { return a >= b; }
}, { ">", +[]( double a, double b ) { return a > b; } }
};
for( value_t const &vA : values )
{
cout << vA.what << endl;
for( value_t const &vB : values )
{
if( &vA == &vB && &vA == values )
continue;
cout << "\t" << vB.what << endl;
for( op_t const &op : ops )
{
cout << "\t\t" << op.what << ": ";
cout << (ops->op( vA.value, vB.value
) ? "true" : "false") << endl; }
}
}
}
This are the results:
Finite
Inf
<: true
<=: true
==: true
>=: true
>: true
NaN
<: false
<=: false
==: false
>=: false
>: false
Inf
Finite
<: false
<=: false
==: false
>=: false
>: false
Inf
<: false
<=: false
==: false
>=: false
>: false
NaN
<: false
<=: false
==: false
>=: false
>: false
NaN
Finite
<: false
<=: false
==: false
>=: false
>: false
Inf
<: false
<=: false
==: false
>=: false
>: false
NaN
<: false
<=: false
==: false
>=: false
>: false
Interesting results !
Nothing of interest here, except for another proof that combination of borderline-sane programming language with insane programming style
causes bugs.
Here is the same test written in more sane language and style. Results
are 100% as expected:
#include <stdio.h>
#include <math.h>
int main()
{
static const double vals[3] = { 1.0, INFINITY, NAN };
_Bool results[3][3][5];
for (int i = 0; i < 3; ++i) {
for (int j = 0; j < 3; ++j) {
results[i][j][0] = vals[i] < vals[j];
results[i][j][1] = vals[i] <= vals[j];
results[i][j][2] = vals[i] == vals[j];
results[i][j][3] = vals[i] >= vals[j];
results[i][j][4] = vals[i] > vals[j];
}
}
static const char* ops[5] = { "<", "<=", "==", ">=", ">" };
for (int i = 0; i < 3; ++i) {
for (int k = 0; k < 5; ++k) {
for (int j = 0; j < 3; ++j)
printf(" %3g %2s %3g : %-5s ;",
vals[i], ops[k], vals[j],
results[i][j][k] ? "true" : "false");
printf("\n");
}
}
return 0;
}
Results:
1 < 1 : false ; 1 < inf : true ; 1 < nan : false ;
1 <= 1 : true ; 1 <= inf : true ; 1 <= nan : false ;
1 == 1 : true ; 1 == inf : false ; 1 == nan : false ;
1 >= 1 : true ; 1 >= inf : false ; 1 >= nan : false ;
1 > 1 : false ; 1 > inf : false ; 1 > nan : false ;
inf < 1 : false ; inf < inf : false ; inf < nan : false ;
inf <= 1 : false ; inf <= inf : true ; inf <= nan : false ;
inf == 1 : false ; inf == inf : true ; inf == nan : false ;
inf >= 1 : true ; inf >= inf : true ; inf >= nan : false ;
inf > 1 : true ; inf > inf : false ; inf > nan : false ;
nan < 1 : false ; nan < inf : false ; nan < nan : false ;
nan <= 1 : false ; nan <= inf : false ; nan <= nan : false ;
nan == 1 : false ; nan == inf : false ; nan == nan : false ;
nan >= 1 : false ; nan >= inf : false ; nan >= nan : false ;
nan > 1 : false ; nan > inf : false ; nan > nan : false ;
--- SoupGate-Win32 v1.05
* Origin: fsxNet Usenet Gateway (21:1/5)