Geth version: Geth/v1.9.12-stable/linux-amd64/go1.14 or Geth/v1.9.12-stable-b6f1c8dc/linux-amd64/go1.13.8
OS & Version: Debian GNU/Linux 10 (buster) 4.19.98-1 (2020-01-26) x86_64 GNU/Linux
geth attach run/geth/geth.ipc
23999016382000000000 + 32000000000000000000
55999016382000000000
geth attach run/geth/geth.ipc
23999016382000000000 + 32000000000000000000
55999016382000005000
root@buster-on-mac-BUILD:/usr/lib/envx-test/tests/exc-wf# geth attach run/geth/geth.ipc
Welcome to the Geth JavaScript console!
instance: Geth/v1.9.12-stable/linux-amd64/go1.14
coinbase: 0x8a736a05f7acdeba23331efae63194fd1fc42d1b
at block: 65 (Wed Mar 25 2020 10:48:42 GMT+0200 (EET))
datadir: /usr/lib/envx-test/tests/exc-wf/run/geth
modules: admin:1.0 clique:1.0 debug:1.0 eth:1.0 miner:1.0 net:1.0 personal:1.0 rpc:1.0 shh:1.0 txpool:1.0 web3:1.0
55999016382000005000 + 32000000000000000000
87999016382000000000
23999016382000000000 + 32000000000000000000
55999016382000005000
23999016382000000000 + 32000000000000000000
55999016382000005000
a = 23999016382000000000 + 32000000000000000000
55999016382000005000
a
55999016382000005000
I can confirm the problem - but it seems to be a general javascript issue - just got the same result in the browser:

This is a general JavaScript issue. It is using float types to represent numbers, and above a certain amount, you lose precision. When working with Ethereum magnitude numbers (> 10^18), you should use a big integer library in JavaScript (there's one included in the console too). This is also the reason why we serialize numbers as hex in the APIs and not pass them verbatim as decimals.
this might be interesting in this context: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/MAX_SAFE_INTEGER
This is a general JavaScript issue. It is using
floattypes to represent numbers, and above a certain amount, you lose precision. When working with Ethereum magnitude numbers (> 10^18), you should use a big integer library in JavaScript (there's one included in the console too). This is also the reason why we serialize numbers as hex in the APIs and not pass them verbatim as decimals.
It's not the problem with JavaScript, It's about how computers represent Numbers with binary , every language implemented IEEE_754 has the same problem.
@sapjax The problem is not with float, the problem is that JavaScript uses floats for all numbers which is moronic.
In case this ever helps anyone, this issue can be circumvented in Javascript by using the native Javascript BigInt (just make sure to pass the large numbers into BigInt as a string or it won't work properly):
BigInt("23999016382000000000") + BigInt("32000000000000000000")
Will output:
55999016382000000000n
If this then needs to be converted to the number (as a string), you can call .toString() on the BigInt variable, for example:
(BigInt("23999016382000000000") + BigInt("32000000000000000000")).toString()
Will output:
"55999016382000000000"
@sapjax The problem is not with float, the problem is that JavaScript uses floats for all numbers which is moronic.
You are right, it's not the same problem as 0.1 + 0.2 !== 0.3, so It's the fault of Brendan Eich,He didn't implement the operation of big integer,and just use float to represent integer 😂.
It's the fault of Brendan Eich,He didn't implement the operation of big integer,and just use float to represent integer joy.
Yes. Exactly.
If you make a dynamically typed language, then make the type inference correct. If you are incapable of inferring the correct type, then add a type system.
@karalabe I guess I must be missing something, but why does the example I shared with Javascript's native BigInt not solve the problem? 🌈
I would agree that it is inconvenient to have to use numbers as strings, but does it not at least solve the problem?
@JayWelsh It works indeed, but it was added in ES2020, so your interpreter needs to support the type.
Thanks @karalabe , much appreciated! I guess at least it is there now. ðŸŒ