mirror of
https://github.com/corda/corda.git
synced 2025-03-03 04:49:46 +00:00
fix NaN handling in floating point comparisons
This commit is contained in:
parent
cc8d655762
commit
b436bd460a
@ -243,6 +243,9 @@ void branch(Context* c, lir::TernaryOperation op, lir::Constant* target) {
|
||||
void branchFloat(Context* c, lir::TernaryOperation op, lir::Constant* target) {
|
||||
switch (op) {
|
||||
case lir::JumpIfFloatEqual:
|
||||
// jp past the je so we don't jump to the target if unordered:
|
||||
c->code.append(0x7a);
|
||||
c->code.append(6);
|
||||
conditional(c, 0x84, target);
|
||||
break;
|
||||
|
||||
|
@ -2467,13 +2467,27 @@ getJClassFromReference(MyThread* t, object pair)
|
||||
referenceName(t, pairSecond(t, pair)))));
|
||||
}
|
||||
|
||||
bool
|
||||
isNaN(double v)
|
||||
{
|
||||
return fpclassify(v) == FP_NAN;
|
||||
}
|
||||
|
||||
bool
|
||||
isNaN(float v)
|
||||
{
|
||||
return fpclassify(v) == FP_NAN;
|
||||
}
|
||||
|
||||
int64_t
|
||||
compareDoublesG(uint64_t bi, uint64_t ai)
|
||||
{
|
||||
double a = bitsToDouble(ai);
|
||||
double b = bitsToDouble(bi);
|
||||
|
||||
if (a < b) {
|
||||
if (isNaN(a) or isNaN(b)) {
|
||||
return 1;
|
||||
} else if (a < b) {
|
||||
return -1;
|
||||
} else if (a > b) {
|
||||
return 1;
|
||||
@ -2490,7 +2504,9 @@ compareDoublesL(uint64_t bi, uint64_t ai)
|
||||
double a = bitsToDouble(ai);
|
||||
double b = bitsToDouble(bi);
|
||||
|
||||
if (a < b) {
|
||||
if (isNaN(a) or isNaN(b)) {
|
||||
return -1;
|
||||
} else if (a < b) {
|
||||
return -1;
|
||||
} else if (a > b) {
|
||||
return 1;
|
||||
@ -2507,7 +2523,9 @@ compareFloatsG(uint32_t bi, uint32_t ai)
|
||||
float a = bitsToFloat(ai);
|
||||
float b = bitsToFloat(bi);
|
||||
|
||||
if (a < b) {
|
||||
if (isNaN(a) or isNaN(b)) {
|
||||
return 1;
|
||||
} if (a < b) {
|
||||
return -1;
|
||||
} else if (a > b) {
|
||||
return 1;
|
||||
@ -2524,7 +2542,9 @@ compareFloatsL(uint32_t bi, uint32_t ai)
|
||||
float a = bitsToFloat(ai);
|
||||
float b = bitsToFloat(bi);
|
||||
|
||||
if (a < b) {
|
||||
if (isNaN(a) or isNaN(b)) {
|
||||
return -1;
|
||||
} if (a < b) {
|
||||
return -1;
|
||||
} else if (a > b) {
|
||||
return 1;
|
||||
|
@ -680,6 +680,18 @@ store(Thread* t, unsigned index)
|
||||
BytesPerWord * 2);
|
||||
}
|
||||
|
||||
bool
|
||||
isNaN(double v)
|
||||
{
|
||||
return fpclassify(v) == FP_NAN;
|
||||
}
|
||||
|
||||
bool
|
||||
isNaN(float v)
|
||||
{
|
||||
return fpclassify(v) == FP_NAN;
|
||||
}
|
||||
|
||||
uint64_t
|
||||
findExceptionHandler(Thread* t, object method, unsigned ip)
|
||||
{
|
||||
@ -1157,7 +1169,9 @@ interpret3(Thread* t, const int base)
|
||||
double b = popDouble(t);
|
||||
double a = popDouble(t);
|
||||
|
||||
if (a < b) {
|
||||
if (isNaN(a) or isNaN(b)) {
|
||||
pushInt(t, 1);
|
||||
} if (a < b) {
|
||||
pushInt(t, static_cast<unsigned>(-1));
|
||||
} else if (a > b) {
|
||||
pushInt(t, 1);
|
||||
@ -1172,7 +1186,9 @@ interpret3(Thread* t, const int base)
|
||||
double b = popDouble(t);
|
||||
double a = popDouble(t);
|
||||
|
||||
if (a < b) {
|
||||
if (isNaN(a) or isNaN(b)) {
|
||||
pushInt(t, static_cast<unsigned>(-1));
|
||||
} if (a < b) {
|
||||
pushInt(t, static_cast<unsigned>(-1));
|
||||
} else if (a > b) {
|
||||
pushInt(t, 1);
|
||||
@ -1370,7 +1386,9 @@ interpret3(Thread* t, const int base)
|
||||
float b = popFloat(t);
|
||||
float a = popFloat(t);
|
||||
|
||||
if (a < b) {
|
||||
if (isNaN(a) or isNaN(b)) {
|
||||
pushInt(t, 1);
|
||||
} if (a < b) {
|
||||
pushInt(t, static_cast<unsigned>(-1));
|
||||
} else if (a > b) {
|
||||
pushInt(t, 1);
|
||||
@ -1385,7 +1403,9 @@ interpret3(Thread* t, const int base)
|
||||
float b = popFloat(t);
|
||||
float a = popFloat(t);
|
||||
|
||||
if (a < b) {
|
||||
if (isNaN(a) or isNaN(b)) {
|
||||
pushInt(t, static_cast<unsigned>(-1));
|
||||
} if (a < b) {
|
||||
pushInt(t, static_cast<unsigned>(-1));
|
||||
} else if (a > b) {
|
||||
pushInt(t, 1);
|
||||
|
@ -329,5 +329,23 @@ public class Floats {
|
||||
|
||||
{ float v = Float.POSITIVE_INFINITY;
|
||||
expect(Long.MAX_VALUE == (long) v); }
|
||||
|
||||
expect(Double.NaN != Double.NaN);
|
||||
expect(! (Double.NaN == Double.NaN));
|
||||
|
||||
{ double d = Double.NaN;
|
||||
expect(Double.NaN != d);
|
||||
expect(! (Double.NaN == d));
|
||||
expect(d != d);
|
||||
expect(! (d == d)); }
|
||||
|
||||
expect(Float.NaN != Float.NaN);
|
||||
expect(! (Float.NaN == Float.NaN));
|
||||
|
||||
{ float d = Float.NaN;
|
||||
expect(Float.NaN != d);
|
||||
expect(! (Float.NaN == d));
|
||||
expect(d != d);
|
||||
expect(! (d == d)); }
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user