Calculating percentages in js [duplicate] - javascript

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

Related

Represent UNIX timestamp as two numbers (first 32 bits and next 16) [duplicate]

This question already has answers here:
How to do bitwise AND in javascript on variables that are longer than 32 bit?
(5 answers)
Closed 7 years ago.
I need to represent UNIX time as two numbers in JavaScript - first 32 bits and next 16 bits (would be enough for some time).
So, having a number that's potentially greater then 2^32 (but less then 2^48), I want to get its 0-31 bits part and 32-47 bits part as two numbers. Getting the first number is easy but the second is not due to 32-bitness of JavaScript's bit-wise operators.
I could do something like
longNumber.toString(2).substring(0, longNumber.length - 32)
to get the binary value of the second number and convert it to decimal. But I wonder is it possible to do it without string conversions?
Came up with this (it additionally splits first 32 bits into two 16 bits):
function splitTime(time) {
const first32 = time & 0xFFFFFFFF;
const first16 = first32 & 0xFFFF;
const second16 = first32 >>> 16;
const third16 = Math.floor((time / 0xFFFFFFFF) & 0xFFFF);
return [first16, second16, third16];
}

How to raise to the power of an exponent?

How can I calculate 98 raised to the power of exp(13-5) using JavaScript?
Is this the way?
Math.pow(98,Math.exp(8))
When I need to handle large positive numbers that would overflow standard floating point types then I store the numbers as log of the number instead. So instead of calculating 98 to the power of exp(8), I'd calculate exp(8) * log(98) and work with that. I haven't (yet) come across a situation where even that method was inadequate to store the numbers that I needed. However, I have come across several situations where the right answer involves multiplying very very large numbers by very very small numbers, and in that situation using logs as I described has avoided overflows/underflows which would result in the wrong answer.
Update: I suspect this is some kind of homework question relating to how to get round the problem that 98 ^ exp(8) is too big for standard floating point types. In which case, I think my suggestion to use logs comes in handy. For example, to print out the number in C# you could do the following:
double x = Math.Exp(13 - 5) * Math.Log(98); // the number required is exp(x)
int exponent = (int)Math.Floor(x / Math.Log(10));
double absissae = Math.Exp(x - exponent * Math.Log(10));
System.Diagnostics.Trace.WriteLine(absissae.ToString() + " E " + exponent.ToString());
which produces the output
5.77130918514205 E 5935

Expression solver for Javascript [duplicate]

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).

toFixed javascript function giving strange results?

I am trying to fix the number to 2 digits after decimal and for that i am using toFixedfunction of javascript. Below are the strange results i am getting, please check and help me.
var number = 11.995;
number.toFixed(2); // giving me 11.99 which is correct
var number = 19.995;
number.toFixed(2); // giving me 20.00 which is incorrect
Can anyone tell me why it is happening.
Thanks for your help.
This is how floating point math works. The value 19.995 is not exact binary (base 2). To make it more clear, think of an exact number when you divide 10/3.
For more in-depth explanations, read this: http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html
In your case you can work with strings instead (at least it seems like that is what you want):
number.toString().substr(0, n);
Or define a function like this (made in 2 minutes, just an example):
Number.toFixed = function(no, n) {
var spl = no.toString().split('.');
if ( spl.length > 1 ) {
return spl[0]+'.'+spl[1].substr(0,n);
}
return spl[0];
}
Number.toFixed(19.995, 2); // 19.99
toFixed rounds the value. Since 19.995 is exactly halfway between 19.99 and 20.00, it has to choose one of them. Traditionally, rounding prefers the even result (this prevents bias, since round-ups and round-downs will be equal).
I have create a function which done all for me..
function toFixed(number, precision) {
var multiplier = Math.pow(10, precision + 1),
wholeNumber = Math.floor(number * multiplier);
return Math.round(wholeNumber / 10) * 10 / multiplier;
}
//Call this function to retrive exect value
toFixed((+adjustmentval), 2);
David has answered your doubt I'm guessing. Just providing an alternate solution here.
You can use the Math.floor() method of the Math object for this.
Something like this, Math.floor(number*100)/100
Can anyone tell me why it is happening.
The IEEE-754 double-precision binary floating point number standard used by JavaScript's number type (and similar times in several other languages) does not perfectly store all numbers, it stores some numbers imprecisely, in a way that lets it A) Store them in just 64 bits, and B) Calculate with them quickly.
For 11.995, the actual value is 11.99499988555908203125, just slightly less than 11.995.
For 19.995, the actual value is 19.9950008392333984375, just slightly more than 19.995.
That explains why when you round them using the usual round-to-nearest-half-up operation, 11.995 (which is really 11.99499988555908203125) rounds down to 11.99 but 19.995 (which is really 19.9950008392333984375) rounds up to 20.00.
(This site has a handy calculator for visualizing this stuff.)
More here on SO:
Is floating point math broken?
How to deal with floating point number precision in JavaScript?

Javascript rounding issue [duplicate]

This question already has answers here:
Why does floating-point arithmetic not give exact results when adding decimal fractions?
(31 answers)
Closed 11 months ago.
I've got a weird maths/rounding problem in Javascript.
The snippet below is a very basic example of the code I'm running. Obviously it's not this exact code, but I'm taking a decimal value from a text box, working out a percentage and taking this away from one.
var ten = "10";
var eight = "8";
alert(1 - (eight/ten));
The problem is the answer is 0.2 but the calculation returns 0.1999999999999996. Yet if I do 1 + (eight/ten) 1.8 is returned. What is going on?
Welcome to the world of floating-point numbers!
Computers don't actually work with decimal numbers--i.e. numbers in base ten, the way we use them in normal life. They work with binary numbers, and that includes floating-point numbers. They're represented in binary as well, and that means that "number of decimal places" is not always a meaningful property of a floating-point number.
For instance, a floating-point number cannot exactly represent 0.1, and you'll get something like 0.1000000001 if you try to use it in your code. The exact value you get varies by implementation, and is not correctable by subtracting the difference, as the computer can't tell that there is a difference--that's as close as it can get to 0.1.
(Stole most of this answer from a previous answer of mine.)
It's because of the way floating point numbers are represented.
I have the same result on my android device which means your device or computer works with 64 bits floating point representation. For correct result, you must limit displaying your result to 15 digits. I found this workaround : running :
var res = 1 - 0.8;
var roundedRes = parseFloat(res.toPrecision(15) ) ;
alert ("res="+res+"\n" + "roundedRes="+roundedRes);
ouputs :
res=0.19999999999999996
roundedRes=0.2
JavaScript use binary floating point for representation of numbers like 1/2,1/8...1/1024. But decimal fractions which we mostly use are represented in form 1/10,1/100...
This will not be a problem with JavaScript only but with all languages that use binary floating point representation.

Categories

Resources