WebAssembly / wabt

The WebAssembly Binary Toolkit
Apache License 2.0
6.83k stars 695 forks source link

[Help] How to literal a very large number? #1078

Closed xieguigang closed 5 years ago

xieguigang commented 5 years ago

Hi,

Help needed, today I test for a max value literal of the f64 number, and have error reports when convert wast to wasm binary:

literal.wast:42:47: error: invalid literal "1.79769313486232e+308"
(global $Double.MaxValue (mut f64) (f64.const 1.79769313486232e+308))
                                              ^^^^^^^^^^^^^^^^^^^^^

The value of Double.MaxValue its literal value in .NET Framework is 1.79769313486232E+308, but it seems that such literal syntax in scientific notation is not valid in WebAssembly S-Expression

I have check for the documents in repository WebAssembly/design, but didn't find something about literal a large number.

Here are some necessary information for reproduce this error:

Demo script: literal.txt Version of wat2wasm: wabt-1.0.11-win64

Horcrux7 commented 5 years ago

Use the hex syntax. The correct syntax for the max value is: 0x1.fffffffffffffp1023

The problem with the decimal syntax is that you have already exceed the maximum through rounding. In Java the max double in decimal is 1.7976931348623157e+308. This is a little smaller.

binji commented 5 years ago

Right, you can see that these numbers produce the same value in the wat2wasm demo:

(func
  f64.const 1.7976931348623157e+308
  f64.const 0x1.fffffffffffffp1023
  return)

output:

...
0000017: 44                                        ; f64.const
0000018: ffff ffff ffff ef7f                       ; f64 literal
0000020: 44                                        ; f64.const
0000021: ffff ffff ffff ef7f                       ; f64 literal
...
xieguigang commented 5 years ago

Oh, yes, many thanks to @Horcrux7, i found that too, the max value of double type in VB.NET is becomes bigger after default precision rounding in .NET Framework, so value 1.79769313486232E+308 will cause an overflow problem in webassembly compiler. If i adjust the precision to G17, then this max value literal will works:

;; Double.MaxValue.ToString("G17")
;; this works
(global $Double.MaxValue (mut f64) (f64.const 1.7976931348623157e+308))

Hi, @binji , :satisfied: i think use this exceed the max value error message to prompt user that such overflow problem is probably better than message invalid literal. because invalid literal message will make the user believe that there is something errors in their literal syntax instead of look for the overflow problem.

literal.wast:42:47: error: literal value: "1.79769313486232e+308" is exceed the max value of f64
(global $Double.MaxValue (mut f64) (f64.const 1.79769313486232e+308))
                                              ^^^^^^^^^^^^^^^^^^^^^

test.wast:4:47: error: literal value: "99999999999999999999" is exceed the max value of i64
(global $Long.MaxValue (mut i64) (i64.const 99999999999999999999))
                                            ^^^^^^^^^^^^^^^^^^^^
binji commented 5 years ago

@xieguigang good point, opened #1080.