JS decimal number problem need a function similar to toFixed() - javascript

var num = 20.3698 //20.37
var num = 0.36587 //0.37
var num = 0.000014247 //0.000014
var num = 0.0000000000099879 //0.000000000001
I am facing a problem in my JavaScript code: I have some random large and small decimal numbers which on printing takes too much space on view pane.
Example:
var num = 0.023810002044 is okay because here I can use toFixed(2) but numbers like this 0.00000000008824721 take much space and if I use toFixed(2) then it will give me 0.00 but I want 0.00000000009 and if given a number like 0.03248 then output should be 0.03.

You could take the logarithm of 10 and adjust smaller numbers.
const
fix = v => v > 0.01
? v.toFixed(2)
: v.toFixed(1 - Math.floor(Math.log10(Math.abs(v))));
console.log([20.3698, 0.36587, 0.000014247, 0.00000000008824721, 0.0000000000099879].map(fix));

Related

Javascript (Floating-Point Question): is there any reliable way to convert a fraction to a decimal AND THEN BACK AGAIN?

Say I have a very simple fraction (for the purposes of this question, presuppose all cases discussed will be 0 < [VALUE] < 1; that is: nothing like 8 7/16 or 1.625):
My starting fraction:
someFraction = '1/3'; // result: STRING value containing "1/3".
Okay easy enough to convert that to a decimal:
correspondingDecimal = eval(someFraction); // result: FLOAT value containing 0.3333333333333333
(yes, yes, "evils of eval and all that. Work with me here; this is an example)
Now say I wanted it BACK again to "1/3". If this were 1/4 (0.25), no problem:
We'd want a simple greatest common denominator function (to reduce the results to manageability), say
function reduce(numerator,denominator){
let getGCD = (a,b) => b ? getGCD(b, a%b) : a;
gcd = getGCD(numerator,denominator);
return (numerator/gcd) + '/' + (denominator/gcd);
}
...and then we can just grab out the decimal portion of our test string:
let justDecimalPart = ('' + 0.25).slice(2);
and multiply by its length power to get our numerator and our denominator to reduce:
let commonFactor = Math.pow(10,justDecimalPart.length); // Result: 100
// = 25 = 100
reduce((justDecimalPart * commonFactor), commonFactor); // Result: 1/4
... capital! That worked out fine!
EDIT: On a whim, I tried that same reduce function on the decimal values without multiplying them at all (reduce(0.25,1); // result: "1/4"). Sorry; brain-fart. Ignore the exponent bit above ☺️
...But 1/3 is a repeating decimal. If we run the same steps through, we wind up with 3333333333333333/10000000000000000 (((1/3) * 1e16) + '/' + 1e16). It's even worse with something like 17/29.
Is there any way to arrive BACK at "1/3" after taking the plunge from 1/3?
EDIT: I'm not trying to get to an infinite precision, just to a manageable one, preferably through throttling/limiting decimal lengths and then rounding/simplifying the result.
Use-case example here: I'm working on a carpentry calculator. 25mm, expressed in US Common units (to a precision of 3 decimal places) is identical to 63/64. I can only seem to arrive at 125/128.
(25/25.4).toPrecision(3) = 0.984
(63/64).toPrecision(3) = 0.984
It appears I was leaving out a step in my conversion; I wasn't rounding the result of the decimal multiplied against the denominator:
decimalValue = (63 / 64).toPrecision(3); // Result: 0.984
denominator = 128;
numerator = decimalValue * denominator; // Result: 125.952
numerator = Math.round(numerator); // Result: 126
reduce(numerator, denominator); // Result: 63/64

JS use parseFloat,there are a lot of 0 in the decimal

I use this way to divide a decimal.I want to divide this number by 100.
var myNumber="1245.6699";
myNumber=""+parseFloat(myNumber)*10000/1000000;//"12.4566990000000002"
myNumber=Number(myNumber);//12.4566990000000002
I want this division to keep 6 digit decimal like this 12.456699,but now the result is 12.4566990000000002,how to modify?
Use toFixed() method of Number object:
var myNumber = "1245.6699";
console.log(
(myNumber / 100).toFixed(6)
)

Rounding up to two decimal place in javascript eg 4.9995 to 4.99 in mathematical way in js

How can I convert decimal number to 2 decimal place number?
Example: I want to connvert 4.995 to 4.99 but javascript is returning 5.00.
var price=4.995;
var rounded_price=price.toFixed(2);
console.log(rounded_price);
I wouldn't call it rounding but you can achieve it by:
function trim2Dec(n) {
return Math.floor(n * 100) / 100;
}
alert(trim2Dec(4.995));
You can use regex for this as the following:
alert("4.995".replace(/(\d+(\.\d{1,2})?)\d*/, "$1"))
This is Pretty simple check out this code
var price=4.995;
var price1=4.985;
var rounded_price=(Math.round(price*100)/100);
var rounded_price1=(Math.round(price1*100)/100);
console.log("price : "+rounded_price+" price1 : "+rounded_price1);
here at first i am multiplying the price and then i have divided it with 100..just as we do to find the percentage of any number.

Javascript split integer and add decimal point

My integer value is 1210 and i want split this integer like 1 | 210 .Have to add decimal point on middle.
Eg:
var integer=1210;
Split this integer and add decimal value like this 1.210
Why don't you just divide the number by 1000
var x = 1210;
var y = 1210/1000; //1.210 number
var z = y+""; // 1.120 will be string here
console.log(y); // Will output 1.210
If you're always dealing with 4 digit numbers, dividing by 1000 will work (as mentioned in another answer) but you'll need to use toFixed to make sure javascript doesn't remove trailing zeros:
var x = 1210;
(x / 1000).toFixed(3) // => "1.210"
(x / 1000) + "" // => "1.21"
More generically you could use:
x=prompt('enter an integer');
xl=x.toString().length-1
alert((x/Math.pow(10,xl)).toFixed(xl));
(just make sure you enter an integer, preferably +ve, at the prompt)

How can I round a number in JavaScript? .toFixed() returns a string?

Am I missing something here?
var someNumber = 123.456;
someNumber = someNumber.toFixed(2);
alert(typeof(someNumber));
//alerts string
Why does .toFixed() return a string?
I want to round the number to 2 decimal digits.
Number.prototype.toFixed is a function designed to format a number before printing it out. It's from the family of toString, toExponential and toPrecision.
To round a number, you would do this:
someNumber = 42.008;
someNumber = Math.round( someNumber * 1e2 ) / 1e2;
someNumber === 42.01;
// if you need 3 digits, replace 1e2 with 1e3 etc.
// or just copypaste this function to your code:
function toFixedNumber(num, digits, base){
var pow = Math.pow(base||10, digits);
return Math.round(num*pow) / pow;
}
.
Or if you want a “native-like” function, you can extend the prototype:
Number.prototype.toFixedNumber = function(digits, base){
var pow = Math.pow(base||10, digits);
return Math.round(this*pow) / pow;
}
someNumber = 42.008;
someNumber = someNumber.toFixedNumber(2);
someNumber === 42.01;
//or even hexadecimal
someNumber = 0xAF309/256; //which is af3.09
someNumber = someNumber.toFixedNumber(1, 16);
someNumber.toString(16) === "af3.1";
However, bear in mind that polluting the prototype is considered bad when you're writing a module, as modules shouldn't have any side effects. So, for a module, use the first function.
I've solved this problem by changing this:
someNumber = someNumber.toFixed(2)
...to this:
someNumber = +someNumber.toFixed(2);
However this will convert the number to a string and parse it again, which will have a significant impact on performance. If you care about performance or type safety, check the the other answers as well.
It returns a string because 0.1, and powers thereof (which are used to display decimal fractions), are not representable (at least not with full accuracy) in binary floating-point systems.
For example, 0.1 is really 0.1000000000000000055511151231257827021181583404541015625, and 0.01 is really 0.01000000000000000020816681711721685132943093776702880859375. (Thanks to BigDecimal for proving my point. :-P)
Therefore (absent a decimal floating point or rational number type), outputting it as a string is the only way to get it trimmed to exactly the precision required for display.
Why not use parseFloat?
var someNumber = 123.456;
someNumber = parseFloat(someNumber.toFixed(2));
alert(typeof(someNumber));
//alerts number
I solved it with converting it back to number using JavaScript's Number() function
var x = 2.2873424;
x = Number(x.toFixed(2));
Of course it returns a string. If you wanted to round the numeric variable you'd use Math.round() instead. The point of toFixed is to format the number with a fixed number of decimal places for display to the user.
You can simply use a '+' to convert the result to a number.
var x = 22.032423;
x = +x.toFixed(2); // x = 22.03
May be too late to answer but you can multiple the output with 1 to convert to number again, here is an example.
const x1 = 1211.1212121;
const x2 = x1.toFixed(2)*1;
console.log(typeof(x2));
What would you expect it to return when it's supposed to format a number ? If you have a number you can't pretty much do anything with it because e.g.2 == 2.0 == 2.00 etc. so it has to be a string.
Because its primary use is displaying numbers? If you want to round numbers, use Math.round() with apropriate factors.
To supply an example of why it has to be a string:
If you format 1.toFixed(2) you would get '1.00'.
This is not the same as 1, as 1 does not have 2 decimals.
I know JavaScript isn't exactly a performance language, but chances are you'd get better performance for a rounding if you use something like:
roundedValue = Math.round(value * 100) * 0.01
You should use it like below.
var someNumber: number = 0.000000;
someNumber = Number(someNumber.toFixed(2))
Why not * the result by 1 i.e
someNumber.toFixed(2) * 1
Here's a slightly more functional version of the answer m93a provided.
const toFixedNumber = (toFixTo = 2, base = 10) => num => {
const pow = Math.pow(base, toFixTo)
return +(Math.round(num * pow) / pow)
}
const oneNumber = 10.12323223
const result1 = toFixedNumber(2)(oneNumber) // 10.12
const result2 = toFixedNumber(3)(oneNumber) // 10.123
// or using pipeline-operator
const result3 = oneNumber |> toFixedNumber(2) // 10.12
For others like me that happen upon this very old question, a modern solution:
const roundValue = (num, decimals = 2) => {
let scaling = 10 ** decimals;
return Math.round((num + Number.EPSILON) * scaling) / scaling;
}
ref: https://stackoverflow.com/a/11832950
Be careful using toFixed() and Math.round(), they can produce unexpected results due to the floating point number system:
function toFixedNumber(num, digits, base){
var pow = Math.pow(base||10, digits);
return Math.round(num*pow) / pow;
}
console.log(toFixedNumber(130.795, 2, 10));
// 130.79 (incorrect)
console.log(toFixedNumber(100.795, 2, 10));
// 100.8
console.log(+130.795.toFixed(2));
// 130.79 (incorrect)
console.log(+100.795.toFixed(2));
// 100.8
I recommend using Lodash's _.round() function: https://lodash.com/docs/4.17.15#round
_.round(130.795, 2);
// 130.8

Categories

Resources