I'm following "Nim basics" tutorial and stumbled to this case when I was trying to convert in to cm:
import math,strformat
echo " in | cm"
echo "---------------------"
for i in 1 .. 40:
echo fmt"{i:3}", " | ", round(float(i) * 2.54, 1)
Results:
in | cm
---------------------
1 | 2.5
2 | 5.1
3 | 7.6
4 | 10.2
5 | 12.7
6 | 15.2
7 | 17.8
8 | 20.3
9 | 22.9
10 | 25.4
11 | 27.9
12 | 30.5
13 | 33.0
14 | 35.6
15 | 38.1
16 | 40.6
17 | 43.2
18 | 45.7
19 | 48.3
20 | 50.8
21 | 53.3
22 | 55.9
23 | 58.4
24 | 61.0
25 | 63.5
26 | 66.0
27 | 68.59999999999999
28 | 71.09999999999999
29 | 73.7
30 | 76.2
31 | 78.7
32 | 81.3
33 | 83.8
34 | 86.40000000000001
35 | 88.90000000000001
36 | 91.40000000000001
37 | 94.0
38 | 96.5
39 | 99.09999999999999
40 | 101.6
What makes these odd floats?
It`s a bit hard to believe that this is a serious question because of
https://nim-lang.org/docs/math.html#round%2CT%2Cint
But maybe you missed that and have no CS experience.
The basic fact is that we can not present each decimal number exact in a 64 bit floating point intern computer representation. That is not a Nim issue, but occurs from representation of floats in the CPU. I can not remember details how exactly the float format was defined by computer manufactures, but it should be known that float math is never exact, so for example it can occur that a + (b + c) != (a + b) + c. For your output, I would assume the the "strange" values like 66.04 can not be presented exactly, so there is only an approximaton available internally. So the round() function should be not used if printout is the desire, but instead other functions which have the goal to make a nice human readable output. Maybe use strformat module as recommended in the round() function description. And note, the round() function is still very useful, I think it should not be called deprecated. Assume you have a CAD program, and user uses a mm coordinate space with a grid of 0.01 mm. When we draw something then we may want that the mouse should jump to nearest grid position. For that we would want to use the round() proc.
Your answer was nice but I think you it was equally helpful without:
It's a bit hard to believe that this is a serious question because of..
and
But maybe you missed that and have no CS experience.
I think most people would have stumbled across this in one programming language or another.
You can learn how float works in following web sites:
Maybe I'm wrong but I think the answer is fine, did not notice any arrogance IMHO.
He just points out the docs first. It is really important to get used to docs although no one likes them.
So called "CS degrees" are also very useful, you learn a ton of interesting things there.
another option when in need for accuracy and to avoid rounding problem (like in financial activities) is to use a Decimal library..
@Stefan_Salewski @Nam > It`s a bit hard to believe that this is a serious question because of > But maybe you missed that and have no CS experience. > That is not a Nim issue, but occurs from representation of floats in the CPU
it's a serious question, no need to question about OP's CS credentials, and it is indeed a nim issue.
Here's a minimal version:
echo 'echo(26.0 * 2.54)' | nim c -r -
66.04000000000001
python does a better job:
python3 -c 'print(26.0*2.54)'
66.04
without sacrificing precision:
python3 -c 'print(1/0.3)'
3.3333333333333335
the fix is to port ryu to nim stdlib, which is tracked here https://github.com/nim-lang/Nim/issues/13365 there's already a POC nimble pkg from @disruptek
echo 'import pkg/ryu; echo f2s(26.0*2.54)' | nim c -r -
6.604e1
which, if https://github.com/disruptek/ryu/issues/4 is addressed, could have an option to customize format and display like in python: 66.04 instead of 6.604e1it's a serious question,
Maybe. I hoped he would come back so that we would know for sure, but he did not.
Well sometimes my answers may be wrong or bad, so it may be better to do not answer at all and leave answers to the paid Nim devs, or at least native english speakers. In am none of that. The paid devs may still have a good feeling when they give a detailed and friendly answer to all the trolls.
The facts that it was his first question, the problem was explained in the round() proc documentation, he did not ask for help or for why, but just called it an issue and "odd", and the name NAM is for me a strong troll indication. Trolls love to start a long discussion with some provocatively statement, and I don't like to make trolls happy. But on the other side, maybe it was indeed intended as a serious question, maybe he was hoping for an answer, and wants not to wait a full day until a Nim dev may answer, maybe only with a tree word sentence. So I wrote as short answer -- maybe sometime in future I will learn to be extremely friendly all day and not saying what my feelings are.