5

I have this JavaScript file (Rhino 1.7R4).

importPackage(java.io);
importPackage(java.lang);
importPackage(java.util);

var reader = new BufferedReader( new InputStreamReader(System['in']) );

var line = reader.readLine();
var tok = new java.util.StringTokenizer(line);

var A = Integer.parseInt(tok.nextToken());
var B = Integer.parseInt(tok.nextToken());
var C = Integer.parseInt(tok.nextToken());

// System.out.printf( "A=%d, B=%d, C=%d\n", A, B, C );
System.out.printf( "A=%f, B=%f, C=%f\n", A, B, C );

When I uncomment first printf - I'm getting

A=Exception in thread "main" org.mozilla.javascript.WrappedException: Wrapped java.util.IllegalFormatConversionException: d != java.lang.Double
        at org.mozilla.javascript.Context.throwAsScriptRuntimeEx(Context.java:1754)
        at org.mozilla.javascript.MemberBox.invoke(MemberBox.java:148)
        at org.mozilla.javascript.NativeJavaMethod.call(NativeJavaMethod.java:225)
        at org.mozilla.javascript.optimizer.OptRuntime.callN(OptRuntime.java:52)
        at test._c_script_0(Unknown Source)
        at test.call(Unknown Source)
        at org.mozilla.javascript.ContextFactory.doTopCall(ContextFactory.java:394)
        at org.mozilla.javascript.ScriptRuntime.doTopCall(ScriptRuntime.java:3091)
        at test.call(Unknown Source)
        at test.exec(Unknown Source)
        at org.mozilla.javascript.optimizer.OptRuntime$1.run(OptRuntime.java:218)
        at org.mozilla.javascript.Context.call(Context.java:489)
        at org.mozilla.javascript.ContextFactory.call(ContextFactory.java:504)
        at org.mozilla.javascript.optimizer.OptRuntime.main(OptRuntime.java:206)
        at test.main(Unknown Source)
Caused by: java.util.IllegalFormatConversionException: d != java.lang.Double
        at java.util.Formatter$FormatSpecifier.failConversion(Unknown Source)
        at java.util.Formatter$FormatSpecifier.printInteger(Unknown Source)
        at java.util.Formatter$FormatSpecifier.print(Unknown Source)
        at java.util.Formatter.format(Unknown Source)
        at java.io.PrintStream.format(Unknown Source)
        at java.io.PrintStream.printf(Unknown Source)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.lang.reflect.Method.invoke(Unknown Source)
        at org.mozilla.javascript.MemberBox.invoke(MemberBox.java:126)
        ... 13 more
Betlista
  • 10,327
  • 13
  • 69
  • 110

1 Answers1

3

That's a reault of the JavaScript type system. All numbers in JavaScript are doubles, so while `Integer.parseInt("4.5") returns 4, it needs to be converted to 4.0 for JavaScript.

Fortunately, 64-bit doubles have enough precision to represent any 32-bit int exactly, so on the JavaScript side you typically don't need to worry about it. But the Java object behind the value is always a Double and gets converted automatically when it needs to be. But since System.out.printf takes arguments of type Object it has to be passed as is.

Matthew Crumley
  • 101,441
  • 24
  • 103
  • 129
  • So I have to handle int arithmetic, for example integer division by my own? let say A is 5 B is 2, so I would expect that 5/2 is 2 and not 2.5 – Betlista Apr 30 '14 at 06:12
  • Ok, thanks I didn't expect that - here is the question about the division - http://stackoverflow.com/questions/4228356/integer-division-in-javascript – Betlista Apr 30 '14 at 06:18
  • 1
    Right, all division in JavaScript is floating point (really everything except the bit-wise and, or, complement, and xor operators which convert their operands to 32-bit ints first). – Matthew Crumley Apr 30 '14 at 13:18