Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Nan comparison in Javascript with javax.scriptEngine on JDK8

According to IEEE 754 NaN equal comparison with any number should be false (both Java and JavaScript languages). But in the following code, using javax scriptEngine for JavaScript, a variable set to NaN compared with itself returns true.

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;

public class Main {

    public static void main(String[] args) throws ScriptException {
        final ScriptEngineManager mgr = new ScriptEngineManager();
        final ScriptEngine engine = mgr.getEngineByName("JavaScript");
        System.out.println("neq: " + engine.eval("a1 = NaN; a1!=a1;"));
        System.out.println("eq: " + engine.eval("a1 = NaN; a1==a1;"));
        System.out.println("nid: " + engine.eval("a1 = NaN; a1!==a1;"));
        System.out.println("id: " + engine.eval("a1 = NaN; a1===a1;"));
    }
}

Output :

neq: true
eq: true
nid: true
id: false

Using oracle JDK :

java version "1.8.0_60"
Java(TM) SE Runtime Environment (build 1.8.0_60-b27)
Java HotSpot(TM) 64-Bit Server VM (build 25.60-b23, mixed mode)

My understanding is the 'eq' expression should return false.

Why is a1 == a1 True instead of False when a1 is NaN ?

like image 315
fleroux Avatar asked Jun 30 '26 00:06

fleroux


1 Answers

Whatever causes this behavior seems to be a side-effect of the assignment or, more specific, of the reassignment (within the same script). I modified your test case to

final ScriptEngineManager mgr = new ScriptEngineManager();
ScriptEngine engine = mgr.getEngineByName("JavaScript");
System.out.println("neq: " + engine.eval("a1 = NaN; a1!=a1;"));
System.out.println("eq: " + engine.eval("a1 = NaN; a1==a1;"));
System.out.println();
engine = mgr.getEngineByName("JavaScript");
System.out.println("eq: " + engine.eval("a1 = NaN; a1==a1;"));
System.out.println("neq: " + engine.eval("a1 = NaN; a1!=a1;"));
System.out.println();
engine = mgr.getEngineByName("JavaScript");
engine.eval("a1 = NaN;");
System.out.println("neq: " + engine.eval("a1!=a1;"));
System.out.println("eq: " + engine.eval("a1==a1;"));
System.out.println();
engine = mgr.getEngineByName("JavaScript");
engine.eval("a1 = NaN;");
System.out.println("eq: " + engine.eval("a1==a1;"));
System.out.println("neq: " + engine.eval("a1!=a1;"));

and got:

neq: true
eq: true

eq: false
neq: false

neq: false
eq: true

eq: true
neq: false

So when a1 does not get reassigned within an engine, it exhibits a consistent (not necessarily correct) behavior, while with the reassignment, the result is not just wrong but entirely inconsistent.

like image 173
Holger Avatar answered Jul 02 '26 12:07

Holger



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!