Rounding off number shows different result on positive and negative numbers - javascript

I've rounding the number into 2 decimal places:
function round(num, decimals)
{
var factor = Math.pow(10, decimals);
return Math.round(num * factor) / factor;
} round(-5.255, 2);
-5.25
function round(num, decimals)
{
var factor = Math.pow(10, decimals);
return Math.round(num * factor) / factor;
} round(5.255, 2);
5.26
But I've observed that it is giving different result when it is positive or negative.
Why is this happening and How can this be corrected?

From the documentation:
If the fractional portion of number is 0.5 or greater, the argument is rounded to the next higher integer.
So when the fraction is exactly 0.5, it rounds up. For a negative number, this means it rounds closer to 0, for a positive number it rounds away from 0. So -0.5 rounds to 0, while 0.5 rounds to 1.
If you want symmetric rounding, you can get the number's absolute value, round that, then convert it back to the original sign:
function symmetricRound(num) {
return Math.sign(num) * Math.round(Math.abs(num));
}
Math.sign is an EcmaScript 6 addition. If you're on an older browser, use the polyfill from the documentation.

Why:
If i remembrer my maths courses (quite long ago...), 0,1,2,3&4 round to the nearest smaller value, 5,6,7,8,&9 round to the nearest greater value. 5.26 is greater than 5.255. So is -5.25 greater than -5.255.
How:
If you really need to have a behavior that is the same in absolute value, why not round the absolute value, then apply a "-1" factor if original value is <0?

Related

Truncate to the nearest 50 in JavaScript

What JavaScript formula can I use to truncate a number to the nearest 50.
Example. I wanted 498 > 450
I have tried
Math.round (498, 50 )
And
Math.ceil(498, 50)
But am not getting. Please help
This may be a mixup of terminology, mixing terms like "nearest" and "truncate", neither of which quite describes what the example demonstrates.
The example you give always rounds down, never up, to the nearest custom value (in this case 50). To do that you can just subtract the result of % 50. For example:
const val = 498;
console.log(val - val % 50);
Even make it a re-usable function:
const Nearest = (val, num) => val - val % num;
console.log(Nearest(498, 50));
Divide by 50, do the operation, multiply by 50.
console.log(Math.floor(498 / 50) * 50);
console.log(Math.ceil(498 / 50) * 50);
console.log(Math.round(498 / 50) * 50);
console.log(Math.trunc(498 / 50) * 50);
You divide your number by 50, take the ceiling of that number and then multiply it by 50.
Math.ceil(value / 50) * 50;
A quick sidenote: truncate has a whole other meaning for numbers in Javascript: Math.trunc on MDN
Edit:
If you want other rounding semantics than ceil you can of course use floor (always goes to lowest multiple of 50):
Math.floor(451 / 50) * 50; // => 450
You divide by the multiple and round and then multiply by the multiple. If you want the lower bound, you use floor instead of round. If you want the upper bound, you use ceil instead of round. Look at these examples:
let x = 498;
let y = Math.round(498/50)*50;
console.log(y);
y = Math.floor(498/50)*50;
console.log(y);
y = Math.ceil(498/50)*50;
console.log(y);
To do what you want, the Remainder operator is your best friend. This will give you whatever is left over after dividing the number by the nearest number.
If your goal is to always round down, the following function would work. Just take your original number, find the remainder, and remove the remainder:
function roundDownToNearest(num, nearest){
return num - (num % nearest);
}
console.log(roundDownToNearest(498, 50))
If you always want to round up, you round down, then add the nearest amount:
function roundUpToNearest(num, nearest){
return num - (num % nearest) + nearest;
}
console.log(roundUpToNearest(498, 50))
If you want to get to the closest of the two, you could do the following. Find your remainder, then see if it's greater or less than half of your nearest value. If it's greater, round up. If less, round down.
function roundToNearest(num, nearest){
if(num % nearest > nearest / 2){
return roundUpToNearest(num, nearest);
} else {
return roundDownToNearest(num, nearest);
}
}
console.log(roundToNearest(498, 50))
console.log(roundToNearest(458, 50))

Javascript equiv to FLOOR in excel with 0.5 values [duplicate]

This question already has an answer here:
Math.floor () to round down to nearest 0.5 in javascript [duplicate]
(1 answer)
Closed 3 years ago.
I do NOT want to round to the NEAREST 0.5. I want to round DOWN to the nearest 0.5 value.
I have a function from excel that I use: =FLOOR(value,0.5)
9.55 becomes 9.5
9.99 becomes 9.5
9.2 becomes 9
Etc.
Is there an equivalent in javascript? I know that Math.floor () will round down to the nearest integer. However, does anyone know of a good way to round down to the nearest 0.5 instead?
Thank you in advance
Return the whole number + 0.5, if the original decimal value is >= 0.5.
const floor = (value) => {
let wholeNumber = Math.floor(value)
return wholeNumber + ((value - wholeNumber) < 0.5 ? 0.0 : 0.5)
}
This can be modified to support nearly any fraction other than 0.5.
const assertEquals = (n1, n2, precision = 0.001) => Math.abs(n1 - n2) <= precision
/**
* Returns the largest integer less than or equal to a given number rounded down to the nearest fraction.
* #param {number} value - A positive floating-point value
* #param {number} [nearest=1.0] - A fractional value between (0.0, 1.0]
* #return A number representing the largest integer less than or equal to the specified number rounded down to the nearest fraction
*/
const floorNearest = (value, nearest = 1.0) => {
let wholeNumber = Math.floor(value)
let fraction = value - wholeNumber
let factor = Math.floor(fraction / nearest)
return wholeNumber + (nearest * factor)
}
console.log(assertEquals(floorNearest(1.50), 1))
console.log(assertEquals(floorNearest(1.25), 1))
console.log(assertEquals(floorNearest(9.55, 0.5), 9.5))
console.log(assertEquals(floorNearest(9.99, 0.5), 9.5))
console.log(assertEquals(floorNearest(9.20, 0.5), 9.0))
console.log(assertEquals(floorNearest(0.55, 0.200), 0.400))
console.log(assertEquals(floorNearest(0.55, 0.250), 0.500))
console.log(assertEquals(floorNearest(0.99, 0.333), 0.666))
.as-console-wrapper { top: 0; max-height: 100% !important; }

How to round the sum of decimal numbers more accurately in javascript

I am trying to find a way to round the sum of an array of numbers in more accurate way.
for example giving an array of [33.33, 33.33, 33.33] the sum is 99.99 in this case I don't want to round the sum to be 100.
but if the array of numbers was [33.3333 , 33.3333, 33.3333] then it should round the sum to 100.
Using Math.round() is rounding always to 100 even if you have an array of [33.22 , 33.33 , 33.33]
You could multiply before rounding to have different precision:
var a = 99.99;
var b = 99.9999;
var precision = 100;
console.log(a, Math.round(a), Math.round(a * precision) / precision);
console.log(b, Math.round(b), Math.round(b * precision) / precision);
The better solution to round off a number is demoed here
function precisionRound(number, precision) {
var factor = Math.pow(10, precision);
return Math.round(number * factor) / factor;
}
console.log(precisionRound(99.99, 2)); //99.99
console.log(precisionRound(99.9999, 2)); //100

How to determine the number that when multiplied will get you the closest to a target number?

Let's say I have the number 2062 and the multiplier is 0.75
What is the JavaScript formula to find which number that, when multiplied by 0.75, will come the closest to 2062?
PS: The closest here means either equal (==) or very close, but below the target number, and not very close but above.
You are looking for x in x * 0.75 = 2062. So solving for x that should be x = 2062 / 0.75. To ensure that the number is the closest whole number less than or equal to x, you can use Math.floor:
Math.floor(2062 / 0.75) = 2749
function findFactor(a, b) {
return Math.floor(a / parseFloat(b));
}
findFactor(2062, 0.75) -> 2749
https://jsfiddle.net/0s8cr5gd/

Explain Math.floor(Math.random())

I have seen many places using Math.floor() and Math.random()
like below
$('a.random-color').hover(function() { //mouseover
var col = 'rgb(' + (Math.floor(Math.random() * 256)) + ',' + (Math.floor(Math.random() * 256)) + ',' + (Math.floor(Math.random() * 256)) + ')';
$(this).animate({
'color': col,
'paddingLeft': '20px'
},1000);
},function() { //mouseout
$(this).animate({
'color': original,
'paddingLeft': '0'
},500);
});
});
Why used Math.floor() and Math.random()?
Math.random will give you a floating point number between 0 (inclusive) and 1 (exclusive).
Multiplying that by 256 will give you a number in the range 0 (inclusive) through 256 (exclusive), but still floating point.
Taking the floor of that number will give you an integer between 0 and 255 (both inclusive).
It's the integer from 0 to 255 that you need to construct RGB values like rgb(72,25,183).
It seems a random color is desired - one with each component random between 0 and 255.
Math.random() returns a random number on [0,1) (ie it may be exactly zero or up to but not including one).
Multiplying that random value by 256 gives a random number on the range [0,256) (ie it may be 255.99, but never 256). Almost there, but not quite.
Math.floor() rounds the number downwards to the nearest whole integer, making the result an integer on [0,255] as desired.
Math.floor will give a whole number and gets rid of the decimals.
Math.random returns a number between 0 and 1 and therefore will produce decimal numbers when multiplied with 256. Thats why you want to use floor to get rid of the decimals otherwise the rgb values won't work.
The Math.floor() is to drop the decimal portion of the Number. It is the opposite of Math.ceil().
You can also double the invert bitwise operator (~~) to achieve the same as Math.floor() (though of course the floor() method is much more readable to most).
~~(Math.random() * 256)
Math.random returns value between 0 and 1. You are multiplying it with 256 so it will return some float value between 0 and 256. math.floor will omit fraction value from it.
~~Number is only the Math.floor() for positive numbers. For negative numbers, it is the Math.ceil().
For positive numbers you can use:
Math.floor(x) == ~~(x)
Math.round(x) == ~~(x + 0.5)
Math.ceil(x) == ~~(x + 1)
For negative numbers you can use:
Math.ceil(x) == ~~(x)
Math.round(x) == ~~(x - 0.5)
Math.floor(x) == ~~(x - 1)

Categories

Resources