-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Rounding 0.00015 to precision 4 is not giving 0.0002 #11
Comments
This may help to resolve the problem: https://go.dev/play/p/HP82b8ZX_Zp
|
OK. Forget it :) ... I just found that the real problem here is how I initialize the variable!
I guess my Round routine actually works "correct" in an unexpected way because it introduces a similar rounding as all the other float64 "outputs" do. I hope I did not waste your time. Thanks for this great package! |
Actually. Maybe it is a bug because it should also round |
Thanks for checking out the module!
How are you testing that? It seems to be correct to me: x, _ := new(big.Int).SetString("5534023222112865", 10)
y, _ := new(big.Int).SetString("36893488147419103232", 10)
fmt.Println(rounding.Round(new(big.Rat).SetFrac(x, y), 3, rounding.HalfEven).FloatString(3))
fmt.Println(rounding.Round(new(big.Rat).SetFrac(x, y), 4, rounding.HalfEven).FloatString(4))
fmt.Println(rounding.Round(new(big.Rat).SetFrac(x, y), 5, rounding.HalfEven).FloatString(5))
fmt.Println(rounding.Round(new(big.Rat).SetFrac(x, y), 32, rounding.HalfEven).FloatString(32)) Gives:
Which looks correct based on: |
Yes. Your package works correct but that is the problem with float64 origins. Because we all expect it to be not correct. So Rounding |
What I mean is that if you have a periodic '9'er non-rational input number, you may want to round it before truncating: 0,00015*10000=1,4999999999999999 = trunc(1) = 1,4 ... but is that really what we want? |
I am actually looking into this for some hours, I need "Bankers Rounding" on place 4 and originally started with a float variant:
I didn't notice that problem before I tried to implement a
big.Rat
version myself. In the end, I came up with:This does solve all my tests, which I verified with multiple online calculators (of which one had the problem I described above):
While implementing stuff, I found that I needed to truncate
big.Rat
values to 4 decimals. This is when I found your package.While looking through it, I saw your rounder and tried
rounding.Round(num, 4, rounding.HalfEven)
, which I thought, it would be maybe more elegant than my quick straightforward implementation, that uses strings to detect the different cases. But the results are similar to the Float64 version I posted above. In fact, nearly every implementation I find does that "wrong". This includes a big Go database. There is a lot of code that uses multiply/divide usingmath.Pow()
or some variant. It seems that all of them suffer from the floating-point problematic, that I think causes the problem.See also: https://go.dev/play/p/bduKZF3AfQC
The text was updated successfully, but these errors were encountered: