The relevant portion of the code:
For example:
n = 1.2345678901234567
puts n.round(9) # => 1.23456789
puts (n * 1e9).round / 1e9 # => 1.23456789
puts n.round(12) # => 1.2345678895572774
puts (n * 1e12).round / 1e12 # => 1.234567890123
puts n.round(8,16) # => -NaN
base ** digits is treated as an 32-bit integer when both base and digits are integers, and hence can overflow.
Moreover, it doesn't do any input checks on both base or digits, not even if they are integers. They don't make sense if they are non-integers, so they should either be converted or raised when this happens.
Mostly related to decisions in #3103. Overflow semantics in crystal's compiler and stdlib are largely undefined and unsafe.
In Crystal 0.31.1 it's
n = 1.2345678901234567
puts n.round(9) # => 1.23456789
puts (n * 1e9).round / 1e9 # => 1.23456789
puts n.round(12) # => 1.234567890123
puts (n * 1e12).round / 1e12 # => 1.234567890123
puts n.round(8,16) # => 1.2345678901765496
$ crystal --version
Crystal 0.31.1 (2019-10-02)
LLVM: 8.0.1
Default target: x86_64-apple-macosx
Yes, it seems to be working fine. Let's close this. Please reopen if you think it's still not working well.
Most helpful comment
In Crystal 0.31.1 it's