Expression solver for Javascript [duplicate] - javascript

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Elegant workaround for JavaScript floating point number problem
I need a workaround for the fact that Javascript can't do floating math reliably due to the IEEE 754 standard from 1985 it uses. Basically, what I need is a way to evaluate an expression like 5+3*(2+8/6). I'm thinking of doing it with strings and rolling my own functions for basic operations (+-*/%), but I was wondering first if you know of any library that does this already.

It depends on how big the numbers are. For small numbers (e.g. fewer than 14 significant digits), rounding to acceptable precision may do the job. e.g. given your example:
var n = 0.5 / 5 + 1 / 5; // 0.30000000000000004
var p = Math.pow(10, 14); // where 14 is calculated based on the first
// significant digit and its relationship to
// the decimal place
n = Math.round(n * p) / p; // 0.3
Calculating the power of 10 to use shouldn't be that hard. If you have large numbers, then life is more difficult (see existing libraries).

Related

Decimals are not percise [duplicate]

This question already has answers here:
How to deal with floating point number precision in JavaScript?
(47 answers)
Closed 4 years ago.
If I do 0.3 - 0.2 it gives 0.9999999998 not 0.1 is there a way to make it give a percise decimal? Can't trust a calculator if it's not percise.
You could try this solution: https://30secondsofinterviews.org/#what-does-0-1-0-2-0-3-evaluate-to-
A solution to this problem would be to use a function that determines if two numbers are approximately equal by defining an error margin (epsilon) value that the difference between two values should be less than.
const approxEqual = (n1, n2, epsilon = 0.0001) => Math.abs(n1 - n2) < epsilon
approxEqual(0.1 + 0.2, 0.3) // true
Here is a very quick answer that sums up all of the flags as best I can:
Use, for standard math:
(.3-.2).toFixed(10); //10 can be changed to whatever you like for your string
If you need to do more math with it than do:
Number((.3-.2).toFixed(10));
This last one will give you exactly what you expected in a number type.

Why JavaScript return me a wrong result in this subtraction of decimals values? [duplicate]

This question already has answers here:
Is floating point math broken?
(31 answers)
Closed 7 years ago.
I am pretty new in JavaScript and I have found a very strange situation doing an extremely simple mathematical operation: a subtraction.
So in a jQuery function I have this code:
saldoRicalcolato = finanziamento - variazioneAnticipoNumber;
Where finanziamento and variazioneAnticipoNumber are 2 numbers having decimal digits.
It works almost always good except for some specific values.
You can replicate the strange behavior performing this statement into the FireBug console:
2205.88 - 1103.01
1102.8700000000001
So in this case the result is substantially wrong because I obtain 1102.8700000000001 and not 1102.87 as I expected.
Why? What am I missing? Is it a JavaScript engine bug or something like this? Possible?
It's not a JavaScript problem but a more general computer problem. Floating number can't store all decimal numbers properly, because they store stuff in binary For example:
0.5 is store as b0.1
but 0.1 = 1/10 so it's 1/16 + (1/10-1/16) = 1/16 + 0.0375
0.0375 = 1/32 + (0.0375-1/32) = 1/32 + 00625 ... etc
so in binary 0.1 is 0.00011...
but that's endless. Except the computer has to stop at some point. So if in our example we stop at 0.00011 we have 0.09375 instead of 0.1.
It doesn't depend on which language but on the computer, what depends on the language is how you display the numbers. Usually the language will round numbers to an acceptable representation but apparently JavaScript doesn't.
If you're looking to get 1102.87. You'll need to set the decimal place to 2 by using toFixed()
This is just a solution of getting the number you want.
alert((2205.88 - 1103.01).toFixed(2));

A lot of decimals in javascript operations [duplicate]

This question already has answers here:
Is floating point math broken?
(31 answers)
Closed 8 years ago.
I'm running the following javascript code:
var var1 = 0.53;
var var2 = 0.47;
alert(var1-var2);
This code return:
0.06000000000000005
But if I execute this javascript code:
var var1 = 0.14;
var var2 = 100;
alert(var1*var2);
The return is:
14.0600000000000002
What documentation to explain this?
Thanks!
This is a very fundamental problem that is related to the way floating point numbers are represented (see the wikipedia article for a detailed explanation). It is not specific to javascript.
Since a computer works only on binary values it is not possible to exactly represent certain fractions. Example: 1/2 or 3/4 can be exactly represented. 1/3 on the other hand cannot (like in the decimal system). It is counterintutive that a seemingly "simple" number like 0.14 leads to a rounding error, however, when you think about it as 7/50 = 7/(5 * 5 * 2) it becomes clear. The problem are the fives. 1/5 = 0.2 is nice in the decimal system but not as a binary number.
Update:
I don't mean to say it is not possible to do such kinds of calculations exactly. However, you will have to use certain libraries for this purpose (e.g. for working with currency values)

Javascript avoid 0.2 + 0.4 = 0.6000000000000001 other than Math.round() [duplicate]

This question already has answers here:
How to deal with floating point number precision in JavaScript?
(47 answers)
Dealing with float precision in Javascript [duplicate]
(5 answers)
Closed 9 years ago.
Is there any better way other than
Math.round(0.2+0.4) = 0.6
Actually, I have a series of index 0, 0.02, 0.04, 0.06, 0.08, 0.10 ----
I have to convert it to Array Index 0,1,2,3,4,5-- by dividing by 0.02
JavaScript provides
0.28/0.02 = 14.000000000000002
I solve this problem by Math.round(0.28/0.02).
I am curious is there any other or better way to solve this problem
JS Number class is 64-bit floating-point, so it's bound to lose precision in corner cases like this one (also for integers > 2^53).
It's OK to use Math.round and their friends in your case. For a full discussion of the problem and possible workarounds, see the article provided by #Bergi.
I wonder isn't that easier in your particular case to precache the hash of indexes, like this:
var fpIndexes = ['0', '0.02', '0.04', '0.06'];
var fpIndexesHash = {};
for (var i = 0, l = fpIndexes.length; i < l; i++) {
fpIndexesHash[fpIndexes[i]] = i;
}
Then you'll be able to get the integer index out of floating-point value without doing Math.round:
someValues[fpIndexesHash['0.02']]; // the same as someValues[1];
I've used strings here, but I actually think plain floating-point literals can be used here too: my understanding is that a specific floating-point literal will never be represented by different IEEE-754 values at the same machine during the lifetime of a script.
So even if 0.06 literal is actually represented as 0.060000001 number in memory, it'll be uniform - and will be converted to the same string value both in fpIndexesHash assigning round and in the interpreting one.

Calculating percentages in js [duplicate]

This question already has answers here:
Is floating point math broken?
(31 answers)
Closed 9 years ago.
I'm trying to create a simple percentage calculator using javascript.
I try a simple calculation in the console (try it):
106 / 100 * 10
And it returns me:
10.600000000000001
What is going on here? Brackets makes no difference and this doesn't occur for every number. I would expect the result to be 10.6 right? Can anyone offer an explanation? This is not browser specific, it happens in Chrome dev tools and firebug.
No, the result is correct enough (even if changing the order of operations could lead to a different result), that's one of the miracles of IEEE754 floating point storage : a consequences of the fact that numbers aren't stored like you see them, that is some decimal digits and a comma but as
K * 2 ^ N
where K and N are signed integers.
As of course not all numbers can be stored exactly, others are only approached.
I'd suggest you to read this introduction to IEEE754 computing.
What you need is to format the number when outputting it to the user, for example with
var string = myNumber.toFixed(1);
Not all decimal numbers have exact representations in binary, so problems like this happen pretty regularly when you try to do math with floats.
Converted to binary, your operation is as follows:
106 = 64 + 32 + 8 + 2 = 1101010
100 = 64 + 32 + 4 = 1100100
1101010 / 1100100 = 1010.10011001100...
You then multiply this by 10, or 101 in binary and get
1010.10011001100... * 101 = 1010.1001100110011001100...
Which does not quite evaluate to 10.6.
In your particular case, the number has been truncated at 1010.10011001100110011001100110011001, or 36 bits.
Try Below :
Var myAnswer = 106 / 100 * 10;
var result = myAnswer.toFixed(1);
Javascript: formatting a rounded number to N decimals
How this will work for you...
Enajoy your day..!!!
Double precision. Numbers are stored in the computer as powers of two, e.g. 1/2 + 1/4 + 1/8... so when printed as decimals they may not be exact.
you could try (106 / 1000) * 100

Categories

Resources