mirror of
https://github.com/corda/corda.git
synced 2025-06-06 09:21:47 +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) {
|
void branchFloat(Context* c, lir::TernaryOperation op, lir::Constant* target) {
|
||||||
switch (op) {
|
switch (op) {
|
||||||
case lir::JumpIfFloatEqual:
|
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);
|
conditional(c, 0x84, target);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -2467,13 +2467,27 @@ getJClassFromReference(MyThread* t, object pair)
|
|||||||
referenceName(t, pairSecond(t, 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
|
int64_t
|
||||||
compareDoublesG(uint64_t bi, uint64_t ai)
|
compareDoublesG(uint64_t bi, uint64_t ai)
|
||||||
{
|
{
|
||||||
double a = bitsToDouble(ai);
|
double a = bitsToDouble(ai);
|
||||||
double b = bitsToDouble(bi);
|
double b = bitsToDouble(bi);
|
||||||
|
|
||||||
if (a < b) {
|
if (isNaN(a) or isNaN(b)) {
|
||||||
|
return 1;
|
||||||
|
} else if (a < b) {
|
||||||
return -1;
|
return -1;
|
||||||
} else if (a > b) {
|
} else if (a > b) {
|
||||||
return 1;
|
return 1;
|
||||||
@ -2490,7 +2504,9 @@ compareDoublesL(uint64_t bi, uint64_t ai)
|
|||||||
double a = bitsToDouble(ai);
|
double a = bitsToDouble(ai);
|
||||||
double b = bitsToDouble(bi);
|
double b = bitsToDouble(bi);
|
||||||
|
|
||||||
if (a < b) {
|
if (isNaN(a) or isNaN(b)) {
|
||||||
|
return -1;
|
||||||
|
} else if (a < b) {
|
||||||
return -1;
|
return -1;
|
||||||
} else if (a > b) {
|
} else if (a > b) {
|
||||||
return 1;
|
return 1;
|
||||||
@ -2507,7 +2523,9 @@ compareFloatsG(uint32_t bi, uint32_t ai)
|
|||||||
float a = bitsToFloat(ai);
|
float a = bitsToFloat(ai);
|
||||||
float b = bitsToFloat(bi);
|
float b = bitsToFloat(bi);
|
||||||
|
|
||||||
if (a < b) {
|
if (isNaN(a) or isNaN(b)) {
|
||||||
|
return 1;
|
||||||
|
} if (a < b) {
|
||||||
return -1;
|
return -1;
|
||||||
} else if (a > b) {
|
} else if (a > b) {
|
||||||
return 1;
|
return 1;
|
||||||
@ -2524,7 +2542,9 @@ compareFloatsL(uint32_t bi, uint32_t ai)
|
|||||||
float a = bitsToFloat(ai);
|
float a = bitsToFloat(ai);
|
||||||
float b = bitsToFloat(bi);
|
float b = bitsToFloat(bi);
|
||||||
|
|
||||||
if (a < b) {
|
if (isNaN(a) or isNaN(b)) {
|
||||||
|
return -1;
|
||||||
|
} if (a < b) {
|
||||||
return -1;
|
return -1;
|
||||||
} else if (a > b) {
|
} else if (a > b) {
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -680,6 +680,18 @@ store(Thread* t, unsigned index)
|
|||||||
BytesPerWord * 2);
|
BytesPerWord * 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
isNaN(double v)
|
||||||
|
{
|
||||||
|
return fpclassify(v) == FP_NAN;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
isNaN(float v)
|
||||||
|
{
|
||||||
|
return fpclassify(v) == FP_NAN;
|
||||||
|
}
|
||||||
|
|
||||||
uint64_t
|
uint64_t
|
||||||
findExceptionHandler(Thread* t, object method, unsigned ip)
|
findExceptionHandler(Thread* t, object method, unsigned ip)
|
||||||
{
|
{
|
||||||
@ -1157,7 +1169,9 @@ interpret3(Thread* t, const int base)
|
|||||||
double b = popDouble(t);
|
double b = popDouble(t);
|
||||||
double a = 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));
|
pushInt(t, static_cast<unsigned>(-1));
|
||||||
} else if (a > b) {
|
} else if (a > b) {
|
||||||
pushInt(t, 1);
|
pushInt(t, 1);
|
||||||
@ -1172,7 +1186,9 @@ interpret3(Thread* t, const int base)
|
|||||||
double b = popDouble(t);
|
double b = popDouble(t);
|
||||||
double a = 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));
|
pushInt(t, static_cast<unsigned>(-1));
|
||||||
} else if (a > b) {
|
} else if (a > b) {
|
||||||
pushInt(t, 1);
|
pushInt(t, 1);
|
||||||
@ -1370,7 +1386,9 @@ interpret3(Thread* t, const int base)
|
|||||||
float b = popFloat(t);
|
float b = popFloat(t);
|
||||||
float a = 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));
|
pushInt(t, static_cast<unsigned>(-1));
|
||||||
} else if (a > b) {
|
} else if (a > b) {
|
||||||
pushInt(t, 1);
|
pushInt(t, 1);
|
||||||
@ -1385,7 +1403,9 @@ interpret3(Thread* t, const int base)
|
|||||||
float b = popFloat(t);
|
float b = popFloat(t);
|
||||||
float a = 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));
|
pushInt(t, static_cast<unsigned>(-1));
|
||||||
} else if (a > b) {
|
} else if (a > b) {
|
||||||
pushInt(t, 1);
|
pushInt(t, 1);
|
||||||
|
@ -329,5 +329,23 @@ public class Floats {
|
|||||||
|
|
||||||
{ float v = Float.POSITIVE_INFINITY;
|
{ float v = Float.POSITIVE_INFINITY;
|
||||||
expect(Long.MAX_VALUE == (long) v); }
|
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