Javascript Custom rounding approach for decimal - javascript

Input number is 21.2791499. I need to round it in 4 decimal places and expected output in is 21.2792, But all the following approaches give 21.2791 as output. What is the best solution to get the desired output.
The number "9" after number "4" should make the number "4" as "5". Then this "5" should make "1" as "2"
Good or bad, my client’s browser is IE6+ only.
Fiddle: https://jsfiddle.net/Lijo/16mgy0xm/1/
var inputNUmber = 21.2791499;
//Approach 1
var a = Math.round(inputNUmber * 10000) / 10000;
document.getElementById("firstText").value= a;
//Approach 2
var b = Number(Math.round(inputNUmber+'e4')+'e-4');
document.getElementById("secondText").value= b;
//Approach 3
var c =inputNUmber.toPrecision(6);
document.getElementById("thirdText").value= c;

So to be clear, you don't want to round to the nearest integer, you want to always round up?
In which case Math.ceil(21.2791499 * 10000) / 10000 = 21.2792
Scale the number up by the required number of decimal places, use the built in ceil function, and then scale it back down.

Alternative solution. It still suffers from floating point math inaccuracy to a point.
Basically it always "rounds" up unless the value has exactly four decimal places.
var inputNUmber = 21.2791499;
//Approach 1
var a = Math.round(inputNUmber * 10000) / 10000;
document.getElementById("firstText").value= a;
//Approach 2
var b = Number(Math.round(inputNUmber+'e4')+'e-4');
document.getElementById("secondText").value= b;
//Approach 3
var c =inputNUmber.toPrecision(6);
document.getElementById("thirdText").value= c;
// Here's my approach
var d = Math.floor(inputNUmber * 10000) / 10000
d += +(d < inputNUmber) / 10000;
document.getElementById("fourthText").value= d;
<input type="text" id="firstText"/>
<br />
<input type="text" id="secondText"/>
<br />
<input type="text" id="thirdText"/>
<br />
<input type="text" id="fourthText"/>

An approach using String.prototype.split() , String.prototype.slice() , Array.prototype.splice() , Array.prototype.join() , Math.round()
var inputNumber = 21.2791499;
// split value at `.` character
var n = String(inputNumber).split(".");
// portion of number after `.` character
var k = n[1];
// convert numbers after `.` to array
var res = k.slice(4).split("");
// add `.` at index `1` of numbers following `.` character
// of original input number; e.g., convert `2791499` to `2791.5`
res.splice(1, 0, ".");
// results
var input = document.getElementById("firstText");
// use `Math.round()` , `.slice()` , `.join()` on resulting number
// following insertion of `.` character
input.value = Math.round( k.slice(0, 4) + "." + Math.round(res.join("")));
<input type="text" id="firstText"/>
jsfiddle https://jsfiddle.net/16mgy0xm/6/

here is a solution to your weird rounding issue https://jsfiddle.net/16mgy0xm/5/
ESSENTIALLY ALL I AM DOING IS ROUNDING THE NUMBER TWICE
see example 1 I am dividing var a after setting var a this sets the value to round at the 5th decimal place, using the second math.round() i am them setting it back to the 4th decimal place to give you your desired effect.
var inputNUmber = 21.2791499;
//Approach 1
var a = Math.round(inputNUmber * 100000) ;
a = a / 100000;
var a1 = Math.round(a * 10000) / 10000;
document.getElementById("firstText").value= a1;

Related

How to round down decimal number in javascript

I have this decimal number: 1.12346
I now want to keep only 4 decimals but I want to round down so it will return: 1.1234. Now it returns: 1.1235 which is wrong.
Effectively. I want the last 2 numbers: "46" do round down to "4" and not up to "5"
How is this possible to do?
var nums = 1.12346;
nums = MathRound(nums, 4);
console.log(nums);
function MathRound(num, nrdecimals) {
return num.toFixed(nrdecimals);
}
If you're doing this because you need to print/show a value, then we don't need to stay in number land: turn it into a string, and chop it up:
let nums = 1.12346;
// take advantage of the fact that
// bit operations cause 32 bit integer conversion
let intPart = (nums|0);
// then get a number that is _always_ 0.something:
let fraction = nums - intPart ;
// and just cut that off at the known distance.
let chopped = `${fraction}`.substring(2,6);
// then put the integer part back in front.
let finalString = `${intpart}.${chopped}`;
Of course, if you're not doing this for presentation, the question "why do you think you need to do this" (because it invalidates subsequent maths involving this number) should probably be answered first, because helping you do the wrong thing is not actually helping, but making things worse.
I think this will do the trick.
Essentially correcting the round up.
var nums = 1.12346;
nums = MathRound(nums, 4);
console.log(nums);
function MathRound(num, nrdecimals) {
let n = num.toFixed(nrdecimals);
return (n > num) ? n-(1/(Math.pow(10,nrdecimals))) : n;
}
This is the same question as How to round down number 2 decimal places?. You simply need to make the adjustments for additional decimal places.
Math.floor(1.12346 * 10000) / 10000
console.log(Math.floor(1.12346 * 10000) / 10000);
If you want this as a reusable function, you could do:
function MathRound (number, digits) {
var adjust = Math.pow(10, digits); // or 10 ** digits if you don't need to target IE
return Math.floor(number * adjust) / adjust;
}
console.log(MathRound(1.12346, 4));
var nums = 1.12346;
var dec = 10E3;
var intnums = Math.floor(nums * dec);
var trim = intnums / dec;
console.log(trim);
var num = 1.2323232;
converted_num = num.toFixed(2); //upto 2 precision points
o/p : "1.23"
To get the float num :
converted_num = parseFloat(num.toFixed(2));
o/p : 1.23

Math.ceil not working with negative floats

I am trying to create a RoundUp function with help of Math.ceil it working fine with positive number but do not round up the negative numbers
Here is what i am trying
var value = -12.369754; --> output = -12
// make value = 12.369754; and out put will be 13
var decimalPoints = 0;
if (decimalPoints == 0) {
value = Math.ceil(parseFloat(value));
}
console.log(value);
Here is the Fiddle http://jsfiddle.net/n7ecyr7h/
Why This function?
I need to create a function in which user will give a number and decimal points upto which he wants to round the number The RoundUp function will roundUp the given value to a given number of decimal points
For example if user enters 12.12445 and wants to roundUp to 3 decimal points the output will be 12.125
Here is a table of required outputs with 2 decimal points
**Input** **output**
1.2369 1.24
1.2869 1.29
-1.1234 -1.13
-1.17321 -1.18
And here is the Updated Fiddle with original JS code http://jsfiddle.net/n7ecyr7h/1/
The Math.ceil method does actually round up even for negative values. The value -12 is the closest integer value that is at higher than -12.369754.
What you are looking for is to round away from zero:
value = value >= 0 ? Math.ceil(value) : Math.floor(value);
Edit:
To use that with different number of decimal points:
// it seems that the value is actually a string
// judging from the parseFloat calls that you have
var value = '-12.369754';
var decimalPoints = 0;
// parse it once
value = parseFloat(value);
// calculate multiplier
var m = Math.pow(10, decimalPoints);
// round the value
value = (value >= 0 ? Math.ceil(value * m) : Math.floor(value * m)) / m;
console.log(value);
Demo: http://jsfiddle.net/Guffa/n7ecyr7h/3/
Math.ceil(-1.1234) will be -1.12 because in negative -1.12 > -1.1234.
I think you misunderstood mathematically.

Find out how many thousands and hundreds and tens are there in a amount

I am having a asp application and in that amount column is there. I need to find out how many thousands and hundreds and tens are there in that amount
For example
if i am having amount as 3660 means
1000's - 3
100's - 6
10's - 6
like this i need
Can any body help me
The simple answer is to divide the number by 1000 whatever is the quotient that is the number of 1000's in the amount. Then divide the remainder with the 100's the quotient will be the number of 100's. And then again divide the remainder with 10, the quotient will be the number of 10's
Something like this:
quotient = 3660 / 1000; //This will give you 3
remainder = 3660 % 1000; //This will give you 660
Then,
quotient1 = remainder/ 100; //This will give you 6
remainder1 = remainder % 100; //This will give you 60
And finally
quotient2 = remainder1 / 10; //This will give you 6
Is it not easier to use type coercion and change the data type to string?
Then you can easily check the value by checking the value at selected index position,
var number = 1234;
number2 = new String(number);
var thousands = number2[0];
var hundreds = number2[1];
and so on....
It may not be usable in what you're doing, it was for me :)
If the "javascript" tag is the correct one, then you've already gotten some answers. If the "asp-classic" tag is actually the correct one, then chances are your scripting language is VBScript, not Javascript.
Did you just pick multiples of 10 as an example, or is that the actual multiple you're looking for? Because if it's the latter, then all you need to do is split the number into digits — that's what the base 10 number system means, after all.
Function SplitNum(theNum)
dim L, i, s, n
n = CStr(theNum)
L = Len(n)
s = ""
for i = 1 to 3
if s <> "" then s = "," & s
if i >= L then
s = "0" & s
else
s = Left(Right(n,i+1),1) & s
end if
next
if L > 4 then s = left(n,L-4) & s
SplitNum = s
End Function
If your actual divisors are something other than multiples of 10, you'll need to do arithmetic. The integer division operator in VBScript is \. (Integer division is basically the "opposite" of the modulus function.)
Function GetMultiples(theNum)
dim q, r
q = theNum \ 1000 & ","
r = theNum Mod 1000
q = q & r \ 100 & ","
r = r Mod 100
q = q & r \ 10
GetMultiples = q
End Function
Try this out...
Here is a fiddle that demonstrates how to use the output..
http://jsfiddle.net/Villarrealized/L3AxZ/1/
function getMultiplesOfTen(number){
number = parseInt(number);
if(typeof(number)!=="number") return number;
var result = {};
(function breakDown(num){
if(isNaN(num))return num;//if it's invalid return
if(num<=0)return false;
num = num.toFixed(0);//get rid of decimals
var divisor = Math.pow(10,num.length-1),//ex. when num = 300, divisor = 100
quotient = Math.floor(num/divisor);
result[divisor]=quotient;//add it to our object
breakDown(num % divisor);//break down the remainder
})(number);
//return result as an object
return result;
}
This function will return an object with the multiple of ten as the key and the number as the value
ex. getMultiplesOfTen(150)=={100:1,10:5} == 1 multiple of 100 and 5 multiples of 10.
Let's say we have the number 7354. To find the thousands:
variable a = 7354 / 1000
variable b = a % 10
The number which is stored in variable b now is the number if the thousands.
To find the hundreds:
variable c = 7354 / 100
variable d = a % 10
The number which is stored in variable d now is the number if the hundreds.
To find the tens:
variable e = 7354 / 10
variable f = a % 10
The number which is stored in variable f now is the number if the tens.
To find the ones:
7354 % 10
This works for every number in the place of 7354, even for bigger numbers than 7354.
The first digit in the quotient of 1,592÷64
1
is in the Choose... ones tens hundreds thousands place.
Decide where the first digit of the quotient should be placed. Do not complete the division.
The first digit of the quotient for 2,370÷24
2,370÷24
should be in the Choose... ones tens hundreds thousands place
2021 version here:
Cast your number as a string, spread it and reverse it like so:
x = 1234
x = [...x.toString()].reverse() // [4, 3, 2, 1]
thous = x[3] // 1
hunds = x[2] // 2
tens = x[1] // 3
units = x[0] // 4
y = [...x.toString()].reverse()[3] // 1 because 1000 has 3 zeros
I suppose you can use some fancy system of powers of 10 to get those indexes. So let's do exactly that and get #Villarrealized 15 lines of 2013 code condensed into just a few lines of 2021 code:
function placeValues(someNumber = 1234) {
x = [...someNumber.toString()].reverse().reduce((p, c, i) => {
p[10**i] = c;
return p;
}, {});
return x; // {1000:1, 100:2, 10:3, 1:4}
}

How do I zero-fill a number?

I have a working decimal to binary converter, but I want it to ALWAYS show 8 digits,
so if I put in 3 it will say '00000011' and not '11'
Anyone a clue how this can be done?
my code:
<script type="text/javascript">
function ConvertToBinary(dec) {
var bits = [];
var dividend = dec;
var remainder = 0;
while (dividend >= 2) {
remainder = dividend % 2;
bits.push(remainder);
dividend = (dividend - remainder) / 2;
}
bits.push(dividend);
bits.reverse();
return bits.join("");
}
<input type="text" id="txtDec" maxlength="3"/>
<input type="button" value="Convert" onclick="document.getElementById('spBin').innerHTML=ConvertToBinary(document.getElementById('txtDec').value);" />
<span id="spBin"></span>
JavaScript already makes the conversion for you, from a number, using toString method, because you can specify the radix (see the link above):
var n = 13;
console.log(n.toString(2)) // "1101"
If you want add lead zero, in case less then 8, you could have:
var bits = n.toString(2);
console.log("00000000".substr(bits.length) + bits);
With just one method call.
Edit: this answer was written in 2013, nowadays the method padStart can be used instead for the padding:
console.log(n.toString(2).padStart(8, "0"));
How about this:
return String('000000000' + bits.join("")).slice(-8);
Demo (change "dividend" to try with different numbers)
Basically adds 8 zeros to the left and then removes anything more than 8 characters long from the left.
How about before bits.reverse(); You do a while loop like this:
while(bits.length < 8){
bits.push(0);
}
Here's an example solution that will left-pad a number with zeros
#param "num" the number to be left-padded with zeros
#param "width" the number of characters required as a result
#return String the left-padded number
function zeroFill(num, width) {
str = String((new Array(width+1)).join('0') + num).slice(-width)
return str
}
There are other solutions which use a loop to create the zeros.

Math.round Rounding Error

I Want to round 1.006 to two decimals expecting 1.01 as output
When i did
var num = 1.006;
alert(Math.round(num,2)); //Outputs 1
alert(num.toFixed(2)); //Output 1.01
Similarly,
var num =1.106;
alert(Math.round(num,2)); //Outputs 1
alert(num.toFixed(2));; //Outputs 1.11
So
Is it safe to use toFixed() every time ?
Is toFixed() cross browser complaint?
Please suggest me.
P.S: I tried searching stack overflow for similar answers, but could not get proper answer.
EDIT:
Why does 1.015 return 1.01 where as 1.045 returns 1.05
var num =1.015;
alert(num.toFixed(2)); //Outputs 1.01
alert(Math.round(num*100)/100); //Outputs 1.01
Where as
var num = 1.045;
alert(num.toFixed(2)); //Outputs 1.04
alert(Math.round(num*100)/100); //Outputs 1.05
Try something like...
Math.round(num*100)/100
1) Multiple the original number by 10^x (10 to the power of x)
2) Apply Math.round() to the result
3) Divide result by 10^x
from: http://www.javascriptkit.com/javatutors/round.shtml
(to round any number to x decimal points)
This formula Math.round(num*100)/100 is not always good. Example
Math.round(0.145*100)/100 = 0.14
this is wrong, we want it to be 0.15
Explanation
The problem is that we have floats like that
0.145 * 100 = 14.499999999999998
step one
so If we round, we need to add a little bit to our product.
0.145 * 100 + 1e-14 = 14.500000000000009
I assume that sometimes the product might be something like 1.000000000000001, but it would not be a problem if we add to it, right?
step two
Calculate how much should we add?
We know float in java script is 17 digits.
let num = 0.145
let a = Math.round(num*100)/100
let b = a.toString().length
let c = 17-b-2
let result = Math.round(num*100 + 0.1**c)/100
console.log(result)
console.log('not - ' + a )
(-2) - is just to be sure we are not falling into the same trap of rounding.
One-liner:
let num = 0.145
let result = Math.round(num*100 + 0.1**(17-2-(Math.round(num*100)/100).toString().length))/100
Extras
Remember, that everything above is true for positive numbers. If you rounding negative number you would need to subtract a little bit. So the very final One-liner would be:
let num = -0.145
let result = Math.round(num*100 + Math.sign(num)*0.1**(17-2-(Math.round(num*100)/100).toString().length))/100
I realize this problem is rather old, but I keep running into it even 5 years after the question has been asked.
A working solution to this rounding problem I know of is to convert the number to a string, get the required precision number and round up or down using math rules.
An example where Math.round provides unexpected rounding and an example of string rounding can be found in the following fiddle:
http://jsfiddle.net/Shinigami84/vwx1yjnr/
function round(number, decimals = 0) {
let strNum = '' + number;
let negCoef = number < 0 ? -1 : 1;
let dotIndex = strNum.indexOf('.');
let start = dotIndex + decimals + 1;
let dec = Number.parseInt(strNum.substring(start, start + 1));
let remainder = dec >= 5 ? 1 / Math.pow(10, decimals) : 0;
let result = Number.parseFloat(strNum.substring(0, start)) + remainder * negCoef;
return result.toFixed(decimals);
}
let num = 0.145;
let precision = 2;
console.log('math round', Math.round(num*Math.pow(10, precision))/Math.pow(10, precision));
// 0.145 rounded down to 0.14 - unexpected result
console.log('string round', round(num, precision));
// 0.145 rounded up to 0.15 - expected result
Math.round doesn't work properly here because 0.145 multiplied by 100 is 14.499999999999998, not 14.5. Thus, Math.round will round it down as if it was 14.4. If you convert it to a string and subtract required digit (5), then round it using standard math rules, you will get an expected result of 0.15 (actually, 0.14 + 0.01 = 0.15000000000000002, use "toFixed" to get a nice, round result).

Categories