Quirky numbers in javascript
When I add 0.01 it instead adds something odd..
How can I solve this?
47 Replies
pretty sure this is some problem with floating points and bits, don't know exactly how it works, but it's something like, you can't have .5 bits. This is a dummy script i found on StackOverflow that identifies the problem
function test() {
var x = 0.1 * 0.2;
document.write(x);
}
test();
this will result in 0.020000000000000004. it's just because the precision in the floating points isn't that great.
Here is the explanation if you're interested:
https://stackoverflow.com/a/588014
Sadly there is no one way to fix it (as far as i know)Stack Overflow
Is floating point math broken?
Consider the following code:
0.1 + 0.2 == 0.3 -> false
0.1 + 0.2 -> 0.30000000000000004
Why do these inaccuracies happen?
Then how can I fix my code?
It needs to add 1 more 0.01 but it doesnt bc of that floating point bits stuff
Is there maybe something I can change in its parameters for triggering this?
else if((equalizer + 0.01) <= difference && (cid[0][1] - change[0][1]) >= 0) {change[0][1] += 0.01; equalizer += 0.01;}
This is the line of code for every numberadding
Basically CID exists of a so called virtual cash register in this exercise thing
So it has a set value in it
And I need it to give change if possible, starting w highest count to lowest
Everything is working fine up until this point xd
The second bit of my IF statement is just to make sure it doesn't add too much
As in a previous test I noticed it only has 60 of TWENTY
Yet it tried to give 80, so I made it check if it is possible by subtracting whats already been given from whats in cid
What if I put a fixed 2 decimel?
So basically, what I am asking, is there a way that I can tell my code round up to x,xx
I think that would do the trick tho I am not certain, maybe it still keeps track of all thats behind itif it's only adding and subtracting, you can try to use parseFloat(yournumber).toFixed(2)
i don't think it keeps track, but i don't know for sure.
oh, xd this is literally what I sked, alright one sec lemme give it a try
parseFloat
takes a string.so I should just do
n.toFixed(2)
with n standing for number?
pretty sure it also works for a number
well I(ll give both ways a shot, give me a moment
I'm going to apply it to every adding in this function
but yeah, it was some oversight on my part
What's the point though? You're converting a number to a number.
my bad indeed, it was a brain fart moment xd
well um... I don't think toFixed() did the trick, both with float and just number only
.toFixed(x)
will return a string. You can do Number(x.toFixed(2))
.Number as in calling the object Number
or Number as in myNumber ?
or is the x representing myNumber ,
x is in this case your myNumber, Number is used to parse it back to a number.
computer said no :(
Number.parseFloat(x).toFixed(2) <-- did not work either
no, the parseFloat was a mistake on my part
Yes I know, but with this new Number.toFixed
I went ahead and looked things up, on the MND it showed Number.parseFloat(x).toFixed(2)
it does not work
what happens when you try parseFloat(x.toFixed(2))
Yet here it works?
oh I get the same outcome as I get now, which is:
[ [ 'TWENTY', '020.0020.00' ] ]
its supposed to be 60 btw... But I get that jumbled mess of 0's and 2's
wait, what are you logging?
The entire array of that for loop
so if it works correctly it basically shows this here: (one sec
[ [ 'TWENTY', 60 ],
[ 'TEN', 20 ],
[ 'FIVE', 15 ],
[ 'ONE', 1 ],
[ 'QUARTER', 0.5 ],
[ 'DIME', 0.2 ],
[ 'PENNY', 0.03 ] ]
You can try equalizer = Number( (equalizer + 20).toFixed(2))
but penny is supposed to be 0.04 as the change is smth witha 4 in the end
But due to those number glitching out, when the first penny is added
it adds to 69.9999999999999999999 instead of 70
and some other numbesr are jumbed messes too but thats behidn the screens for some reason
Here is the value of equalizer everytime
It gives it at one strange point
anfor some reason it doesnt add the final penny or it adds it incorrectly
maybe its like 0.039999 but the 999 hidden idk man
bc it does trigger 4 times but it doesnt show 0.04
even tho you would expect 0.04 if you do
0.01 + 0.01 + 0.01 + 0.01
can you try to add a line to the end of the for-loop
equalizer = Number(equalizer.toFixed(2));
right after the else statement
just to see if it will change the equalizer thereWell that has solved the weird .999 its getting
However penny is still at 0.03 which is odd, its written exactly the same as every other
don't make your math with decimal numbers, if you need it to be accurate
just use integers
then, when you need to present the number, divide by 100
But the thing is, this is representing money
Money in essence is
euros, cents
or dollars, whatevers there
or other ways
don't try to fix it, you can't
forget it, really
0.1 + 0.2 is not 0.3
you can't fix that
just use integers
then divide by 100 to get the number you want
you can use the
.toFixed(2)
method after, as explained beforeThe issue is tho, the source is already using decimals... xd
so while your idea is valid it can't be used sadly
as I don't choose what I start with
you're sol
I am what?
Dictionary.com
Sol Definition & Meaning | Dictionary.com
Sol definition, the syllable used for the fifth tone of a diatonic scale. See more.
6/9 definition
so, basically, you're in trouble
multiply by 100 then round it
it should get rid of the floating point error
the problem with floating point numbers is that
0.3
doesn't exist, but it is actually 0.299999999999999988897769753748434595763683319091796875
and 0.1 + 0.2
is not 0.3
but 0.3000000000000000444089209850062616169452667236328125
what a pain
it is a pain, but it's the best that computers can do, currently
besides doing math with strings
if you multiply by 100, javascript automatically does some sort of black magic and returns an integer
in the cases where it doesn't, then rounding it will give you the closest value to what you actually intended
then, you do your math with integers only
it should be fine, as long as it is below
Number.MAX_SAFE_INTEGER
(currently 9007199254740991
).. Nah, I'm done
This is just black magic at this point, some sorcery beyond sorcery
o wait, hold on maybe im just crazy
maybe
maybe not
When doing computations that needs to be accurate to a given precision (a hundredth here) you should do all your operations on integers and divide/multiply at the end to get the desired precision.
See it as operating on cents here instead of dollars (or whatever money you are supposed to work with).
Similarly, when you have to be precise to the hundredth of cent (like when computing taxes on small amounts) you should only handle cents as hundreds (100=1c, 10000=1[$£€])
TL;DR: don't use floats (non-integer values) if possible
you said exactly what i said before
but way better explained
Not gonna lie... I didn't read the whole thread
i know