I am having an issue with how javascript is dividing and rounding the number.
I have two float , 0.11 and 0.12
I want to calculate the mid of these two numbers and round it to the nearest highest value with 2 decimal price.
For example, if I do this on Calculator
0.11+0.12 / 2 = 0.115, and I need to round it to 0.12 as it is mid or above mid.
If I do this with Javascript, I am not getting an accurate number
Example,
var high = parseFloat(0.12);
var low = parseFloat(0.11);
var mid = (high + low) / 2;
document.getElementById("demo1").innerHTML = mid;
document.getElementById("demo2").innerHTML = mid.toFixed(2);
var another = mid.toFixed(3);
document.getElementById("demo3").innerHTML =another;
var last = Math.floor(another)
document.getElementById("demo4").innerHTML =last;
http://jsfiddle.net/gzqwbp6c/9/
Any input would be appreciated.
As the 0.11499999999999999 shows, the result is very slightly less than 0.115. This is because 0.11 and 0.12 cannot be represented with perfect accuracy using floating-point-numbers.
When you don't want to deal with floating-point-error, it's often easier to work with integers directly. Small integers are represented exactly by floating point numbers.
You can multiply by 100 before, and round, to ensure your numbers are integers, and only divide after you get your final result:
var a = Math.round(100 * parseFloat("0.12")) // 12
var b = Math.round(100 * parseFloat("0.11")) // 11
var mid = (a + b) / 2 // 11.5.
// 0.5 can be represented exactly in floating point for small numbers.
var midRound = (Math.round(mid) / 100).toFixed(2) // "0.12"
Need to multiply (workout on int part, i.e. find mid, and divide to reconvert to origin):
function myMid(high,low, precision){
var precision=2
var convFactor = Math.pow(10,precision);
return
(Math.round((low*convFactor+high*convFactor)/2)/convFactor).toFixed(precision);
}
Float is not precise, you cant rely on that, you'll have unexpected results.
everything *100 to prevent inaccuracies
.toFixed() does the rounding
var a = 0.11;
var b = 0.12;
c = parseFloat((((a*100) + (b*100))/200).toFixed(2));
console.log(c);
I have a number var x = 2.305185185185195;
x = x.toFixed(5);
x = 2.30519 but I require this without rounding i.e. 2.30518
I read some thread with two decimal places but could not find for five decimal places.
Any help would be appreciated.
You can use an apropriate factor and floor it and return the result of the division.
Basically this solution moves the point to the left with a factor of 10^d and gets an integer of that and divided the value with the former factor to get the right digits.
function getFlooredFixed(v, d) {
return (Math.floor(v * Math.pow(10, d)) / Math.pow(10, d)).toFixed(d);
}
var x = 2.305185185185195;
document.write(getFlooredFixed(x, 5));
If you need only a "part" of a number with a floating point without rounding, you can just "cut" it:
function cutNumber(number, digitsAfterDot) {
const str = `${number}`;
return str.slice(0, str.indexOf('.') + digitsAfterDot + 1);
}
const x = 2.305185185185195;
console.log(cutNumber(x, 5)); // 2.30518
This method is fast (https://jsfiddle.net/93m8akzo/1/) and its execution time doesn't depend on number or digitsAfterDot values.
You can also "play around" with both functions in a given fiddle for a better understanding of what they do.
You can read more about slice() method here - MDN documentation
NOTE This function is only an example, don't use it in production applications.
You should definitely add input values validation and errors handling!
The Math.trunc() function returns the integer part of a number by
removing any fractional digits
So you can multiply the number by 10^n where n is the desired number of precision, truncate the decimal part using Math.trunc(), divide by the same number (10^n) and apply toFixed() to format it (in order to get the form of 2.30 instead of 2.3 for example)
var x = 2.305185185185195;
console.log((Math.trunc(x*100000)/100000).toFixed(5));
I have sorted it out by adding a small amount if the decimal is 5, then rounding as usual:
function(value, decimals) {
var decimals = decimals || 2;
if( isNaN(value) ){ return 0; }
var decimalPart = value.toString().trim().split('.').pop(),
extra = decimalPart.substr(decimals, decimalPart.length - decimals);
if( extra == '5' &&
decimalPart.length > decimals
){
value = parseFloat(value) + (1 / ( Math.pow(10, decimals + 5) ) );
}
return Number( parseFloat( value ).toFixed( decimals ) );
}
In other languages which can represent 64-bit integers, it is possible to do this very easily...
How to store a 64 bit integer in two 32 bit integers and convert back again
How to store a 64 bit integer in two 32 bit integers in Ruby
// convert 64-bit n to two 32-bit x and y
x = (n & 0xFFFFFFFF00000000) >> 32
y = n & 0xFFFFFFFF
But JavaScript CAN NOT represent 64-bit integers. It can only represent 52-bit integers without problems.
Now that means that it is not possible to convert a 64-bit integer into two 32 bit integers, because it is not even possible to have a 64-bit integer in the first place.
But still, we have 52 bits remaining. My question is: how can we split this 52-bit integer in JavaScript in two 32-bit integers (20 high bits and 32 low bits)
Can someone suggest bit manipulation code like above to do 20-bit and 32-bit split in JavaScript?
Related:
How are 32 bit JavaScript numbers resulting from a bit-wise operation converted back to 64 bit numbers
Before we start
First of all, your link contains a minor inaccuracy in stating that
"Any whole number less than 252 [...] will safely fit in a JavaScript number. " While technically correct, it is not a tight bound: it can be verified without too much trouble that javascript numbers can store every positive integer up to 253 (but not 253+1).
Some code
Without further ado, the functions you requested, splitting 52-bit numbers into the bottom 32 bits and the 20 top bits:
function to_int52(hi, lo) {
/* range checking */
if ((lo !== lo|0) && (lo !== (lo|0)+4294967296))
throw new Error ("lo out of range: "+lo);
if (hi !== hi|0 && hi >= 1048576)
throw new Error ("hi out of range: "+hi);
if (lo < 0)
lo += 4294967296;
return hi * 4294967296 + lo;
}
function from_int52(i) {
var lo = i | 0;
if (lo < 0)
lo += 4294967296;
var hi = i - lo;
hi /= 4294967296;
if ((hi < 0) || (hi >= 1048576)
throw new Error ("not an int52: "+i);
return { lo: lo, hi: hi };
}
Where to split
I would not suggest using these though. Javascript bitwise ops are signed (#dandavis: JS does not have UInt32s), and the sign bit causes headaches when we actually want the positive value. Plus V8 has optimizations for (signed) integers that can be stored in 31 bits. Combining these two facts, you should split at no more than 30 bits, the maximum positive size that will fit in a V8 small integer ("smi").
Here's code to split numbers into 30 low bits and 22 high bits:
function int52_30_get(i) {
var lo = i & 0x3fffffff;
var hi = (i - lo) / 0x40000000;
return { lo: lo, hi: hi };
}
You probably don't want to be creating objects though. These should get inlined (if you're actually bothering with functions at all):
function int52_30_get_lo(i) {
return i & 0x3fffffff;
}
function int52_30_get_hi(i) {
return (i - (i & 0x3fffffff)) / 0x40000000;
}
And to create the numbers from the low and high parts:
function int52_30_new_safe(hi, lo) {
return (hi & 0x3fffff) * 0x40000000 + (lo & 0x3fffffff);
}
If you're really sure hi and lo are in range you can skip the masking:
function int52_30_new(hi, lo) {
return hi * 0x40000000 + lo;
}
Set the high and low parts individually:
/* set high part of i to hi */
i = (hi & 0x3fffff) * 0x40000000 + (i & 0x3fffffff);
/* set low part of i to lo */
i += (lo & 0x3fffffff) - (i & 0x3fffffff);
If you're sure that hi and lo are in range:
/* set high part of i to hi */
i = hi * 0x40000000 + (i & 0x3fffffff);
/* set low part of i to lo */
i += lo - (i & 0x3fffffff);
(These aren't functions because they modify i.)
For extra fun, a function to pull out arbitrary bitfields:
function int52_30_get_bits(i, lsb, nbits) {
while (lsb >= 32) {
i /= 4294967296;
lsb -= 32;
}
return (i / (1<<lsb)) & ((1<<nbits)-1);
}
(nbits must be <= 31. The failure mode when nbits is 32 is interesting, and is due to only the 5 low bits of the rhs operand of << being significant, a flaw the javascript spec shares with the x86 ISA.)
More than 52 bits?
It's perfectly possible to use the sign bit to store 53-bit binary numbers as integers from -253 to 253-1. I haven't done this but it should be easy enough. After that it starts to get a bit hairy, and you'll eventually run into the fact that there aren't enough floats to go round (many are NaNs) before you get to 264. Packing 63 binary digits into a float should be theoretically doable, but is left as an exercise for the reader :)
Other approaches
Another approach is to use typed arrays and create a Float view and an Int view: this lets you manipulate the underlying binary representation of floats directly. But then you have to start worrying about endianness and the like.
All the people who are suggesting string manipulation are just crazy.
Well you can do it numerically like this:
function numeric(n) {
return {
hi: Math.floor(n / 4294967296),
lo: (n & 0xFFFFFFFF) >>> 0
}
}
or the string version could be:
function strings(n) {
s = n.toString(16);
if (s.length > 8) {
return {
hi: parseInt( s.toString(16).slice(0, s.length - 8), 16),
lo: parseInt( s.toString(16).slice(s.length - 8), 16)
}
} else {
return { hi: 0, lo: n }
}
}
or maybe ...
function stringPad(n) {
s = "00000000000"+n.toString(16);
return {
hi: parseInt( s.toString(16).slice(0, s.length - 8), 16),
lo: parseInt( s.toString(16).slice(s.length - 8), 16)
}
}
Now, which is faster. To find out I set up a test bed here: http://jsfiddle.net/SpaceDog/ZTJ2p/ (you could also use your favorite JS profiler).
The results (for 100000 calls):
Function: numeric completed in 146 ms
Function: strings completed in 379 ms
Function: stringPad completed in 459 ms
I would have thought strings were faster, and wondered if it was the parseInt call, but no:
Function: stringPadNoParse completed in 386 ms
Now, this isn't very precise as it depends on a lot of other things (again, a profiler might be better) but it does seem like the numeric version is faster and I've run that a few times to test.
But maybe someone will come and provide another way of doing it.
Typed arrays can be used to get the two halves of the double value
var buf = new ArrayBuffer(8);
(new Float64Array(buf))[0] = f;
fl = (new Uint32Array(buf))[0];
fh = (new Uint32Array(buf))[1];
Now you have the mantissa. If needed just extract and shift to get the integer parts
var exp = ((fh >> 20) & 0x7FF) - 1023;
var mant_h = (fh & 0xFFFFF) | (1 << 20);
var mant_l = fl;
if (exp > 52)
throw new Error ("overflow int53 range");
else if (exp >= 32)
{
L = mant_h >> (exp - 32);
H = 0;
}
else if (exp >= 0)
{
L = (mant_l >> exp) | (mant_h << (32 - exp));
H = mant_h >> exp;
}
But if you can use a typed array then you should use a 32-bit array with 2 elements for your integers right from the start, no need to deal with double and all the related hassle. That way you have two 32-bit values, not only 20 bits
With the reverse direction you can store a 64-bit int in a JavaScript variable
javascript float from/to bits
floatToIntBits() in https://github.com/mattdesl/number-util
Note that you can have 64-bit int in Javascript with BigInt64Array and BigUint64Array. You can use it and split into two 32-bit parts instead of double, but it'll be less efficient than a 32-bit array
Native 64bit integers in Javascript
Since ECMAScript® 2020 there's also a new BigInt type for arbitrary precision integers (with the BigInt object or n suffix). Most major browsers already have support for it
const previousMaxSafe = BigInt(Number.MAX_SAFE_INTEGER);
// ↪ 9007199254740991
const maxPlusOne = previousMaxSafe + 1n;
// ↪ 9007199254740992n
Although it can handle arbitrary-precision integers, one of the rationale for its introduction to the standard is to efficiently work with 64-bit or 128-bit system object handles or IDs, so I suppose it should have very good support for 64-bit integers
I needed a way to split an amount (in dollars) between one or more "buckets", for lack of a better word. It needed to have the standard two decimal precision a dollar amount should, but every penny needed to be accounted for.
To illustrate the problem, consider this example:
$200 split 3 ways. If you round down, each amount is $66.66 and you end up 2 cents short, but if you round up, each amount is $66.67 and you're 2 cents over. The answer, of course, is to have one $66.66 and the other two $66.67. That's easy enough for a human to reason, but trying to make bit of JavaScript understand that is kind of a challenge.
Here's the function I came up with:
function SplitTotal( totalAmount, numberToSplit, precision ) {
var precisionFactor = Math.pow(10, precision);
var remainderFactor = 1 / precisionFactor;
var splitAmount = Math.ceil( totalAmount / numberToSplit * precisionFactor ) / precisionFactor;
var remainder = Math.round( (splitAmount * numberToSplit - totalAmount) * precisionFactor ) / precisionFactor;
var result = [];
for (var i = 0; i < numberToSplit; i++) {
result.push( (remainder >= remainderFactor) ?
Math.round( (splitAmount - remainderFactor) * precisionFactor ) / precisionFactor :
splitAmount );
remainder = Math.round( (remainder - remainderFactor) * precisionFactor ) / precisionFactor;
}
return result;
}
The code is a little convoluted, because JavaScript handles floating point numbers atrociously. In order to get a nice, precise decimal amount, you need to multiply the amount by what I call here a "precision factor", which is just some exponent of 10, round the resulting number, and then divide by that precision factor to get back to the original decimal precision.
Even though I only needed 2 decimal spaces of precision, I made the precision easily definable, so this can work for more applications that just dollar amounts. If you want just integers, you can specify a precision of 0.
Ex: $235.38 divided 7 ways:
> SplitTotal(235.38, 7, 2)
[33.62, 33.62, 33.62, 33.63, 33.63, 33.63, 33.63]
In JavaScript, how do I get:
The whole number of times a given integer goes into another?
The remainder?
For some number y and some divisor x compute the quotient (quotient)[1] and remainder (remainder) as:
const quotient = Math.floor(y/x);
const remainder = y % x;
Example:
const quotient = Math.floor(13/3); // => 4 => the times 3 fits into 13
const remainder = 13 % 3; // => 1
[1] The integer number resulting from the division of one number by another
I'm no expert in bitwise operators, but here's another way to get the whole number:
var num = ~~(a / b);
This will work properly for negative numbers as well, while Math.floor() will round in the wrong direction.
This seems correct as well:
var num = (a / b) >> 0;
I did some speed tests on Firefox.
-100/3 // -33.33..., 0.3663 millisec
Math.floor(-100/3) // -34, 0.5016 millisec
~~(-100/3) // -33, 0.3619 millisec
(-100/3>>0) // -33, 0.3632 millisec
(-100/3|0) // -33, 0.3856 millisec
(-100-(-100%3))/3 // -33, 0.3591 millisec
/* a=-100, b=3 */
a/b // -33.33..., 0.4863 millisec
Math.floor(a/b) // -34, 0.6019 millisec
~~(a/b) // -33, 0.5148 millisec
(a/b>>0) // -33, 0.5048 millisec
(a/b|0) // -33, 0.5078 millisec
(a-(a%b))/b // -33, 0.6649 millisec
The above is based on 10 million trials for each.
Conclusion: Use (a/b>>0) (or (~~(a/b)) or (a/b|0)) to achieve about 20% gain in efficiency. Also keep in mind that they are all inconsistent with Math.floor, when a/b<0 && a%b!=0.
ES6 introduces the new Math.trunc method. This allows to fix #MarkElliot's answer to make it work for negative numbers too:
var div = Math.trunc(y/x);
var rem = y % x;
Note that Math methods have the advantage over bitwise operators that they work with numbers over 231.
I normally use:
const quotient = (a - a % b) / b;
const remainder = a % b;
It's probably not the most elegant, but it works.
var remainder = x % y;
return (x - remainder) / y;
You can use the function parseInt to get a truncated result.
parseInt(a/b)
To get a remainder, use mod operator:
a%b
parseInt have some pitfalls with strings, to avoid use radix parameter with base 10
parseInt("09", 10)
In some cases the string representation of the number can be a scientific notation, in this case, parseInt will produce a wrong result.
parseInt(100000000000000000000000000000000, 10) // 1e+32
This call will produce 1 as result.
Math.floor(operation) returns the rounded down value of the operation.
Example of 1st question:
const x = 5;
const y = 10.4;
const z = Math.floor(x + y);
console.log(z);
Example of 2nd question:
const x = 14;
const y = 5;
const z = Math.floor(x % y);
console.log(x);
JavaScript calculates right the floor of negative numbers and the remainder of non-integer numbers, following the mathematical definitions for them.
FLOOR is defined as "the largest integer number smaller than the parameter", thus:
positive numbers: FLOOR(X)=integer part of X;
negative numbers: FLOOR(X)=integer part of X minus 1 (because it must be SMALLER than the parameter, i.e., more negative!)
REMAINDER is defined as the "left over" of a division (Euclidean arithmetic). When the dividend is not an integer, the quotient is usually also not an integer, i.e., there is no remainder, but if the quotient is forced to be an integer (and that's what happens when someone tries to get the remainder or modulus of a floating-point number), there will be a non-integer "left over", obviously.
JavaScript does calculate everything as expected, so the programmer must be careful to ask the proper questions (and people should be careful to answer what is asked!) Yarin's first question was NOT "what is the integer division of X by Y", but, instead, "the WHOLE number of times a given integer GOES INTO another". For positive numbers, the answer is the same for both, but not for negative numbers, because the integer division (dividend by divisor) will be -1 smaller than the times a number (divisor) "goes into" another (dividend). In other words, FLOOR will return the correct answer for an integer division of a negative number, but Yarin didn't ask that!
gammax answered correctly, that code works as asked by Yarin. On the other hand, Samuel is wrong, he didn't do the maths, I guess, or he would have seen that it does work (also, he didn't say what was the divisor of his example, but I hope it was 3):
Remainder = X % Y = -100 % 3 = -1
GoesInto = (X - Remainder) / Y = (-100 - -1) / 3 = -99 / 3 = -33
By the way, I tested the code on Firefox 27.0.1, it worked as expected, with positive and negative numbers and also with non-integer values, both for dividend and divisor. Example:
-100.34 / 3.57: GoesInto = -28, Remainder = -0.3800000000000079
Yes, I noticed, there is a precision problem there, but I didn't had time to check it (I don't know if it's a problem with Firefox, Windows 7 or with my CPU's FPU). For Yarin's question, though, which only involves integers, the gammax's code works perfectly.
const idivmod = (a, b) => [a/b |0, a%b];
there is also a proposal working on it
Modulus and Additional Integer Math
Alex Moore-Niemi's comment as an answer:
For Rubyists here from Google in search of divmod, you can implement it as such:
function divmod(x, y) {
var div = Math.trunc(x/y);
var rem = x % y;
return [div, rem];
}
Result:
// [2, 33]
If you need to calculate the remainder for very large integers, which the JS runtime cannot represent as such (any integer greater than 2^32 is represented as a float and so it loses precision), you need to do some trick.
This is especially important for checking many case of check digits which are present in many instances of our daily life (bank account numbers, credit cards, ...)
First of all you need your number as a string (otherwise you have already lost precision and the remainder does not make sense).
str = '123456789123456789123456789'
You now need to split your string in smaller parts, small enough so the concatenation of any remainder and a piece of string can fit in 9 digits.
digits = 9 - String(divisor).length
Prepare a regular expression to split the string
splitter = new RegExp(`.{1,${digits}}(?=(.{${digits}})+$)`, 'g')
For instance, if digits is 7, the regexp is
/.{1,7}(?=(.{7})+$)/g
It matches a nonempty substring of maximum length 7, which is followed ((?=...) is a positive lookahead) by a number of characters that is multiple of 7. The 'g' is to make the expression run through all string, not stopping at first match.
Now convert each part to integer, and calculate the remainders by reduce (adding back the previous remainder - or 0 - multiplied by the correct power of 10):
reducer = (rem, piece) => (rem * Math.pow(10, digits) + piece) % divisor
This will work because of the "subtraction" remainder algorithm:
n mod d = (n - kd) mod d
which allows to replace any 'initial part' of the decimal representation of a number with its remainder, without affecting the final remainder.
The final code would look like:
function remainder(num, div) {
const digits = 9 - String(div).length;
const splitter = new RegExp(`.{1,${digits}}(?=(.{${digits}})+$)`, 'g');
const mult = Math.pow(10, digits);
const reducer = (rem, piece) => (rem * mult + piece) % div;
return str.match(splitter).map(Number).reduce(reducer, 0);
}
If you are just dividing with powers of two, you can use bitwise operators:
export function divideBy2(num) {
return [num >> 1, num & 1];
}
export function divideBy4(num) {
return [num >> 2, num & 3];
}
export function divideBy8(num) {
return [num >> 3, num & 7];
}
(The first is the quotient, the second the remainder)
function integerDivison(dividend, divisor){
this.Division = dividend/divisor;
this.Quotient = Math.floor(dividend/divisor);
this.Remainder = dividend%divisor;
this.calculate = ()=>{
return {Value:this.Division,Quotient:this.Quotient,Remainder:this.Remainder};
}
}
var divide = new integerDivison(5,2);
console.log(divide.Quotient) //to get Quotient of two value
console.log(divide.division) //to get Floating division of two value
console.log(divide.Remainder) //to get Remainder of two value
console.log(divide.calculate()) //to get object containing all the values
You can use ternary to decide how to handle positive and negative integer values as well.
var myInt = (y > 0) ? Math.floor(y/x) : Math.floor(y/x) + 1
If the number is a positive, all is fine. If the number is a negative, it will add 1 because of how Math.floor handles negatives.
This will always truncate towards zero.
Not sure if it is too late, but here it goes:
function intdiv(dividend, divisor) {
divisor = divisor - divisor % 1;
if (divisor == 0) throw new Error("division by zero");
dividend = dividend - dividend % 1;
var rem = dividend % divisor;
return {
remainder: rem,
quotient: (dividend - rem) / divisor
};
}
Calculating number of pages may be done in one step:
Math.ceil(x/y)
Here is a way to do this. (Personally I would not do it this way, but thought it was a fun way to do it for an example) The ways mentioned above are definitely better as this calls multiple functions and is therefore slower as well as takes up more room in your bundle.
function intDivide(numerator, denominator) {
return parseInt((numerator/denominator).toString().split(".")[0]);
}
let x = intDivide(4,5);
let y = intDivide(5,5);
let z = intDivide(6,5);
console.log(x);
console.log(y);
console.log(z);