For example, let's say I have the number 12.24
in base 8 (10.3125
in base 10), and I want to round the number to 1 point of precision so that I get 12.3
.
To round a number to the nearest 5, call the Math. round() function, passing it the number divided by 5 and multiply the result by 5 .
The Math. round() method rounds a number to the nearest integer. 2.49 will be rounded down (2), and 2.5 will be rounded up (3).
The Math. round() function in JavaScript is used to round the number passed as parameter to its nearest integer. Parameters : The number to be rounded to its nearest integer.
Use the toFixed() method to round a number to 2 decimal places, e.g. const result = num. toFixed(2) . The toFixed method will round and format the number to 2 decimal places.
T here is no built-in method to round to a certain number of digits in JavaScript. You might think the Math.round () function would take an argument specifying a desired precision, but it doesn’t. “The Math.round () function returns the value of a number rounded to the nearest integer.” — MDN Docs
Unfortunately, you can actually run into the same issue with a positive number of decimal places, where 0.5 is occasionally rounded down instead of up, as you can see in the following example: What just happened? Floating point math in JavaScript can produce rounding errors at times, as I discussed in my article in JavaScript in Plain English:
The first number rounds up since it above .5. The second number rounds down since it is below .5. Math.floor rounds the number down to the nearest whole number no matter what the decimals are. Here both numbers round down to 5.
You just need to be aware of JavaScript’s inherent floating point rounding errors, which are usually not too serious. You can avoid rounding errors completely by using exponential notation when rounding. This tutorial only addressed arithmetic rounding, not creating a string from a number using a certain number of decimal places.
There isn´t a function in js that can do this. So need to create one in order to do it. What it does is to check if the digit to fix (in your case the "4") is closer to the base (8) or closer to 0:
if (base - digit_tofix <= base / 2) {
Then, just add or substract the difference to 10 or 0, so if the number is 12.24
, it would return:
return 12.24 + 0.06; // ---> equals to 12.3
If the number is 12.23
, returns:
return 12.23 - 0.03 // ---> equals to 12.2
So could make something like this:
function round(n, base, precision) {
const digit_tofix = n.toString().split(".")[1].split("")[precision];
if (base - digit_tofix <= base / 2) {
return (n + (10 - digit_tofix) / Math.pow(10, precision + 1)).toFixed(precision);
}else {
return (n - digit_tofix / Math.pow(10, precision + 1)).toFixed(precision);
}
}
EDIT: however, this wouldn´t catch carry overflow. So a number in base_8 like this:
55.74
would transform in:
55.74 + 0.06 = 55.8 // --> number 8 doesn´t exist in octal
So there must be an overflow-check loop using do while()
. What this statement do is to move the digit_tofix
to the previous number and check if there is an overflow every time we make an addition:
// Overflow check
do {
n += (10 - digit_tofix) / Math.pow(10, precision + 1);
precision--;
digit_tofix = precision > -1 ? n.toFixed(precision + 1).split(".")[1].split("")[precision] :
n.toFixed(0).split(".")[0].split("")[precision + n.toString().split(".")[0].split("").length];
} while(digit_tofix == base);
return n.toFixed(precision > -1 ? precision + 1 : 0);
round()
function. Here some working examplesconst oct = 12.24;
console.log( round(oct, 8, 1) );
function round(n, base, precision) {
let digit_tofix = n.toString().split(".")[1].split("")[precision];
if (base - digit_tofix <= base / 2) {
// Overflow check
do {
n += (10 - digit_tofix) / Math.pow(10, precision + 1);
precision--;
digit_tofix = precision > -1 ? n.toFixed(precision + 1).split(".")[1].split("")[precision] :
n.toFixed(0).split(".")[0].split("")[precision + n.toString().split(".")[0].split("").length];
} while(digit_tofix == base);
return n.toFixed(precision > -1 ? precision + 1 : 0);
}else {
return (n - digit_tofix / Math.pow(10, precision + 1)).toFixed(precision);
}
}
const bin = 10011.011;
console.log( round(bin, 2, 1) );
function round(n, base, precision) {
let digit_tofix = n.toString().split(".")[1].split("")[precision];
if (base - digit_tofix <= base / 2) {
// Overflow check
do {
n += (10 - digit_tofix) / Math.pow(10, precision + 1);
precision--;
digit_tofix = precision > -1 ? n.toFixed(precision + 1).split(".")[1].split("")[precision] :
n.toFixed(0).split(".")[0].split("")[precision + n.toString().split(".")[0].split("").length];
} while(digit_tofix == base);
return n.toFixed(precision > -1 ? precision + 1 : 0);
}else {
return (n - digit_tofix / Math.pow(10, precision + 1)).toFixed(precision);
}
}
function round(n, base, precision) {
// To get number value of letter: a = 10, b = 11, c = 12 ...
const getNumber = e => isNaN(e) ? e.charCodeAt(0) - 87 : parseInt(e);
// Just to check incompability and invalid parameters
const checkIncompatible = () => {
if (digits.reduce((a, d) => d == "." ? ++a : a, 0) > 1 ||
(digits.some(d => isNaN(d) && (getNumber(d) < 10 || getNumber(d) > 35) && d != "."))) return "Invalid Number";
if (digits.some(d => getNumber(d) >= base && d != ".")) return "Number doesn´t match base";
if (precision < 0) return "Invalid precision argument";
if (base < 2 || base > 36) return "Invalid base argument";
return false;
};
// Recursive function to carry overflow
const add = p => {
if (digits[p] == ".") add(p - 1);
else if (getNumber(digits[p]) + 1 == base) {
digits[p] = "0";
if (p > 0) add(p - 1);
else digits.unshift("1");
}else {
if (isNaN(digits[p])) digits[p] = String.fromCharCode(digits[p].charCodeAt(0) + 1);
else digits[p] = digits[p] < 9 ? parseInt(digits[p]) + 1 : "a" ;
}
};
n = n.toString().toLowerCase().split(",").join("."); // In case there is a comma
let digits = n.split("");
// Avoid problems with undefined array index and other issues
if (typeof digits[digits.indexOf(".") + 1 + precision] === "undefined" ||
digits.reduce((a, d) => d == "." ? ++a : a, 0) < 1) return n;
let state = checkIncompatible();
if (state) return state;
const digit_tofix = getNumber(digits[digits.indexOf(".") + 1 + precision]);
// Check if digit_tofix is closer to base or zero
if (base - digit_tofix <= base / 2) {
add(digits.indexOf(".") + precision);
}
// Splice the array to get the substring
digits.splice(digits.indexOf(".") + 1 + precision);
if (!precision) digits.splice(-1);
return digits.join("");
}
This solution is more complex, but is broader since you can use any number from base 2 to 36, it means you can use hexadecimal.
Similarly to first solution, it checks if the digit to fix (in your case the "4") is closer to the base (8) or closer to 0:
if (base - digit_tofix <= base / 2) {
If is closer to zero, just need to take the substring of the number (using splice()
array method). So if number is:
"12.23"
its substring is
"12.2"
But if digit-to-fix is closer to the base, we need to add +1 to the previous number, so if number is:
"12.24"
its substring is
"12.3" //--> 2 + 1 = 3
For example, if number in base_8 is:
"12.74"
its substring should be
"13.0" // 7 + 1 = 8 (base is 8 so there is an overflow)
That´s why there is a recursive function called add()
in order to carry in case of overflow.
The round()
function returns a string with the new number.
console.log( round("c3.bf9", 16, 2) );
console.log( round("AA.D1", 16, 1) );
console.log( round("ff.fff", 16, 0) );
function round(n, base, precision) {
const getNumber = e => isNaN(e) ? e.charCodeAt(0) - 87 : parseInt(e);
const checkIncompatible = () => {
if (digits.reduce((a, d) => d == "." ? ++a : a, 0) > 1 ||
(digits.some(d => isNaN(d) && (getNumber(d) < 10 || getNumber(d) > 35) && d != "."))) return "Invalid Number";
if (digits.some(d => getNumber(d) >= base && d != ".")) return "Number doesn´t match base";
if (precision < 0) return "Invalid precision argument";
if (base < 2 || base > 36) return "Invalid base argument";
return false;
};
const add = p => {
if (digits[p] == ".") add(p - 1);
else if (getNumber(digits[p]) + 1 == base) {
digits[p] = "0";
if (p > 0) add(p - 1);
else digits.unshift("1");
}else {
if (isNaN(digits[p])) digits[p] = String.fromCharCode(digits[p].charCodeAt(0) + 1);
else digits[p] = digits[p] < 9 ? parseInt(digits[p]) + 1 : "a" ;
}
};
n = n.toString().toLowerCase().split(",").join(".");
let digits = n.split("");
if (typeof digits[digits.indexOf(".") + 1 + precision] === "undefined" ||
digits.reduce((a, d) => d == "." ? ++a : a, 0) < 1) return n;
let state = checkIncompatible();
if (state) return state;
const digit_tofix = getNumber(digits[digits.indexOf(".") + 1 + precision]);
if (base - digit_tofix <= base / 2) {
add(digits.indexOf(".") + precision);
}
digits.splice(digits.indexOf(".") + 1 + precision);
if (!precision) digits.splice(-1);
return digits.join("");
}
console.log( round(12.24, 8, 1) );
console.log( round(17.77, 8, 1) );
console.log( round(0.74, 8, 1) );
function round(n, base, precision) {
const getNumber = e => isNaN(e) ? e.charCodeAt(0) - 87 : parseInt(e);
const checkIncompatible = () => {
if (digits.reduce((a, d) => d == "." ? ++a : a, 0) > 1 ||
(digits.some(d => isNaN(d) && (getNumber(d) < 10 || getNumber(d) > 35) && d != "."))) return "Invalid Number";
if (digits.some(d => getNumber(d) >= base && d != ".")) return "Number doesn´t match base";
if (precision < 0) return "Invalid precision argument";
if (base < 2 || base > 36) return "Invalid base argument";
return false;
};
const add = p => {
if (digits[p] == ".") add(p - 1);
else if (getNumber(digits[p]) + 1 == base) {
digits[p] = "0";
if (p > 0) add(p - 1);
else digits.unshift("1");
}else {
if (isNaN(digits[p])) digits[p] = String.fromCharCode(digits[p].charCodeAt(0) + 1);
else digits[p] = digits[p] < 9 ? parseInt(digits[p]) + 1 : "a" ;
}
};
n = n.toString().toLowerCase().split(",").join(".");
let digits = n.split("");
if (typeof digits[digits.indexOf(".") + 1 + precision] === "undefined" ||
digits.reduce((a, d) => d == "." ? ++a : a, 0) < 1) return n;
let state = checkIncompatible();
if (state) return state;
const digit_tofix = getNumber(digits[digits.indexOf(".") + 1 + precision]);
if (base - digit_tofix <= base / 2) {
add(digits.indexOf(".") + precision);
}
digits.splice(digits.indexOf(".") + 1 + precision);
if (!precision) digits.splice(-1);
return digits.join("");
}
console.log( round(101.10, 2, 1) );
console.log( round("100,11", 2, 1) );
console.log( round(100.11, 2, 1) );
function round(n, base, precision) {
const getNumber = e => isNaN(e) ? e.charCodeAt(0) - 87 : parseInt(e);
const checkIncompatible = () => {
if (digits.reduce((a, d) => d == "." ? ++a : a, 0) > 1 ||
(digits.some(d => isNaN(d) && (getNumber(d) < 10 || getNumber(d) > 35) && d != "."))) return "Invalid Number";
if (digits.some(d => getNumber(d) >= base && d != ".")) return "Number doesn´t match base";
if (precision < 0) return "Invalid precision argument";
if (base < 2 || base > 36) return "Invalid base argument";
return false;
};
const add = p => {
if (digits[p] == ".") add(p - 1);
else if (getNumber(digits[p]) + 1 == base) {
digits[p] = "0";
if (p > 0) add(p - 1);
else digits.unshift("1");
}else {
if (isNaN(digits[p])) digits[p] = String.fromCharCode(digits[p].charCodeAt(0) + 1);
else digits[p] = digits[p] < 9 ? parseInt(digits[p]) + 1 : "a" ;
}
};
n = n.toString().toLowerCase().split(",").join(".");
let digits = n.split("");
if (typeof digits[digits.indexOf(".") + 1 + precision] === "undefined" ||
digits.reduce((a, d) => d == "." ? ++a : a, 0) < 1) return n;
let state = checkIncompatible();
if (state) return state;
const digit_tofix = getNumber(digits[digits.indexOf(".") + 1 + precision]);
if (base - digit_tofix <= base / 2) {
add(digits.indexOf(".") + precision);
}
digits.splice(digits.indexOf(".") + 1 + precision);
if (!precision) digits.splice(-1);
return digits.join("");
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With