Insert a Comma in the thousandths place in outputted number [duplicate] - javascript

This question already has answers here:
How to format a number with commas as thousands separators?
(50 answers)
Closed 6 years ago.
I have created a function that takes a number in Imperial units entered into a div and converts that value to metric units in another div. Being relatively new to js, I am now realizing that a thousandths place comma separator does not come standard. I've tried to apply many of the solutions (many of them reg ex's) that I've found but none suit my needs or have worked. Simply put, I am just looking to have both divs outputted numbers have commas separating the thousandths place. Ultimately, these numbers are elevation values expressed in Feet and Meters. Any insight would be greatly appreciated... thanks!
Here is my code:
<body>
<div id="feet" onload="calculateMeter()">2120</div>
<div id="meter"></div>
<script>
var feet = document.getElementById('feet');
var meter = document.getElementById('meter');
function calculateMeter() {
if (feet.innerHTML > 0) {
meter.innerHTML = (feet.innerHTML * 0.3048).toFixed(1);
feet.toString();
feet = feet.innerHTML.replace(/(\d)(\d{3})\,/, "$1,$2.");
}
}
calculateMeter();
</script>
</body>

Here is a simple RegEx solution
function calculateMeter() {
if (feet.innerHTML > 0) {
var m = (feet.innerHTML * 0.3048).toFixed(2);
meter.innerHTML = m.replace(/\B(?=(\d\d\d)+\b)/g, ",");
}
}

It seems your problem is actually just setting the content the DOM element. Using the solution in How to print a number with commas as thousands separators in JavaScript for formatting numbers, all you need is:
function calculateMeter() {
if (feet.innerHTML > 0) {
meter.innerHTML = numberWithCommas*(feet.innerHTML * 0.3048).toFixed(1));
feet.innerHTML = numberWithCommas(feet.innerHTML);
}
}

My function:
function formatNumberWithCommasDec(d) {
d += "";
var c = d.split(".");
var f = c[1];
var a = c.length > 1 ? c[0] + '.' : '.', flag = false;
var g = f.split('').reverse(), y = 1, s = '';
for (var i = g.length - 1; i >= 0; i--) {
flag = false;
var e = g[i];
var h = (y === 3) ? s = s + e + ',' : s = s + e;
console.log(e);
if(y === 3){
y = 1;
flag = true;
} else {
y = y + 1;
}
}
if(flag){
s = s.substring(0, s.length - 1);
} else {
s = s;
}
return a + s;
}
Fiddle: https://jsfiddle.net/6f0tL0ec/1/
Update: found some problems, but everythings good now

Related

which are alternative of tofixed() in javascript [duplicate]

Suppose I have a value of 15.7784514, I want to display it 15.77 with no rounding.
var num = parseFloat(15.7784514);
document.write(num.toFixed(1)+"<br />");
document.write(num.toFixed(2)+"<br />");
document.write(num.toFixed(3)+"<br />");
document.write(num.toFixed(10));
Results in -
15.8
15.78
15.778
15.7784514000
How do I display 15.77?
Convert the number into a string, match the number up to the second decimal place:
function calc(theform) {
var num = theform.original.value, rounded = theform.rounded
var with2Decimals = num.toString().match(/^-?\d+(?:\.\d{0,2})?/)[0]
rounded.value = with2Decimals
}
<form onsubmit="return calc(this)">
Original number: <input name="original" type="text" onkeyup="calc(form)" onchange="calc(form)" />
<br />"Rounded" number: <input name="rounded" type="text" placeholder="readonly" readonly>
</form>
The toFixed method fails in some cases unlike toString, so be very careful with it.
Update 5 Nov 2016
New answer, always accurate
function toFixed(num, fixed) {
var re = new RegExp('^-?\\d+(?:\.\\d{0,' + (fixed || -1) + '})?');
return num.toString().match(re)[0];
}
As floating point math in javascript will always have edge cases, the previous solution will be accurate most of the time which is not good enough.
There are some solutions to this like num.toPrecision, BigDecimal.js, and accounting.js.
Yet, I believe that merely parsing the string will be the simplest and always accurate.
Basing the update on the well written regex from the accepted answer by #Gumbo, this new toFixed function will always work as expected.
Old answer, not always accurate.
Roll your own toFixed function:
function toFixed(num, fixed) {
fixed = fixed || 0;
fixed = Math.pow(10, fixed);
return Math.floor(num * fixed) / fixed;
}
Another single-line solution :
number = Math.trunc(number*100)/100
I used 100 because you want to truncate to the second digit, but a more flexible solution would be :
number = Math.trunc(number*Math.pow(10, digits))/Math.pow(10, digits)
where digits is the amount of decimal digits to keep.
See Math.trunc specs for details and browser compatibility.
I opted to write this instead to manually remove the remainder with strings so I don't have to deal with the math issues that come with numbers:
num = num.toString(); //If it's not already a String
num = num.slice(0, (num.indexOf("."))+3); //With 3 exposing the hundredths place
Number(num); //If you need it back as a Number
This will give you "15.77" with num = 15.7784514;
Update (Jan 2021)
Depending on its range, a number in javascript may be shown in scientific notation. For example, if you type 0.0000001 in the console, you may see it as 1e-7, whereas 0.000001 appears unchanged (0.000001).
If your application works on a range of numbers for which scientific notation is not involved, you can just ignore this update and use the original answer below.
This update is about adding a function that checks if the number is in scientific format and, if so, converts it into decimal format. Here I'm proposing this one, but you can use any other function that achieves the same goal, according to your application's needs:
function toFixed(x) {
if (Math.abs(x) < 1.0) {
let e = parseInt(x.toString().split('e-')[1]);
if (e) {
x *= Math.pow(10,e-1);
x = '0.' + (new Array(e)).join('0') + x.toString().substring(2);
}
} else {
let e = parseInt(x.toString().split('+')[1]);
if (e > 20) {
e -= 20;
x /= Math.pow(10,e);
x += (new Array(e+1)).join('0');
}
}
return x;
}
Now just apply that function to the parameter (that's the only change with respect to the original answer):
function toFixedTrunc(x, n) {
x = toFixed(x)
// From here on the code is the same than the original answer
const v = (typeof x === 'string' ? x : x.toString()).split('.');
if (n <= 0) return v[0];
let f = v[1] || '';
if (f.length > n) return `${v[0]}.${f.substr(0,n)}`;
while (f.length < n) f += '0';
return `${v[0]}.${f}`
}
This updated version addresses also a case mentioned in a comment:
toFixedTrunc(0.000000199, 2) => "0.00"
Again, choose what fits your application needs at best.
Original answer (October 2017)
General solution to truncate (no rounding) a number to the n-th decimal digit and convert it to a string with exactly n decimal digits, for any n≥0.
function toFixedTrunc(x, n) {
const v = (typeof x === 'string' ? x : x.toString()).split('.');
if (n <= 0) return v[0];
let f = v[1] || '';
if (f.length > n) return `${v[0]}.${f.substr(0,n)}`;
while (f.length < n) f += '0';
return `${v[0]}.${f}`
}
where x can be either a number (which gets converted into a string) or a string.
Here are some tests for n=2 (including the one requested by OP):
0 => 0.00
0.01 => 0.01
0.5839 => 0.58
0.999 => 0.99
1.01 => 1.01
2 => 2.00
2.551 => 2.55
2.99999 => 2.99
4.27 => 4.27
15.7784514 => 15.77
123.5999 => 123.59
And for some other values of n:
15.001097 => 15.0010 (n=4)
0.000003298 => 0.0000032 (n=7)
0.000003298257899 => 0.000003298257 (n=12)
parseInt is faster then Math.floor
function floorFigure(figure, decimals){
if (!decimals) decimals = 2;
var d = Math.pow(10,decimals);
return (parseInt(figure*d)/d).toFixed(decimals);
};
floorFigure(123.5999) => "123.59"
floorFigure(123.5999, 3) => "123.599"
num = 19.66752
f = num.toFixed(3).slice(0,-1)
alert(f)
This will return 19.66
Simple do this
number = parseInt(number * 100)/100;
Just truncate the digits:
function truncDigits(inputNumber, digits) {
const fact = 10 ** digits;
return Math.floor(inputNumber * fact) / fact;
}
This is not a safe alternative, as many others commented examples with numbers that turn into exponential notation, that scenery is not covered by this function
// typescript
// function formatLimitDecimals(value: number, decimals: number): number {
function formatLimitDecimals(value, decimals) {
const stringValue = value.toString();
if(stringValue.includes('e')) {
// TODO: remove exponential notation
throw 'invald number';
} else {
const [integerPart, decimalPart] = stringValue.split('.');
if(decimalPart) {
return +[integerPart, decimalPart.slice(0, decimals)].join('.')
} else {
return integerPart;
}
}
}
console.log(formatLimitDecimals(4.156, 2)); // 4.15
console.log(formatLimitDecimals(4.156, 8)); // 4.156
console.log(formatLimitDecimals(4.156, 0)); // 4
console.log(formatLimitDecimals(0, 4)); // 0
// not covered
console.log(formatLimitDecimals(0.000000199, 2)); // 0.00
These solutions do work, but to me seem unnecessarily complicated. I personally like to use the modulus operator to obtain the remainder of a division operation, and remove that. Assuming that num = 15.7784514:
num-=num%.01;
This is equivalent to saying num = num - (num % .01).
I fixed using following simple way-
var num = 15.7784514;
Math.floor(num*100)/100;
Results will be 15.77
My version for positive numbers:
function toFixed_norounding(n,p)
{
var result = n.toFixed(p);
return result <= n ? result: (result - Math.pow(0.1,p)).toFixed(p);
}
Fast, pretty, obvious. (version for positive numbers)
The answers here didn't help me, it kept rounding up or giving me the wrong decimal.
my solution converts your decimal to a string, extracts the characters and then returns the whole thing as a number.
function Dec2(num) {
num = String(num);
if(num.indexOf('.') !== -1) {
var numarr = num.split(".");
if (numarr.length == 1) {
return Number(num);
}
else {
return Number(numarr[0]+"."+numarr[1].charAt(0)+numarr[1].charAt(1));
}
}
else {
return Number(num);
}
}
Dec2(99); // 99
Dec2(99.9999999); // 99.99
Dec2(99.35154); // 99.35
Dec2(99.8); // 99.8
Dec2(10265.985475); // 10265.98
The following code works very good for me:
num.toString().match(/.\*\\..{0,2}|.\*/)[0];
This worked well for me. I hope it will fix your issues too.
function toFixedNumber(number) {
const spitedValues = String(number.toLocaleString()).split('.');
let decimalValue = spitedValues.length > 1 ? spitedValues[1] : '';
decimalValue = decimalValue.concat('00').substr(0,2);
return '$'+spitedValues[0] + '.' + decimalValue;
}
// 5.56789 ----> $5.56
// 0.342 ----> $0.34
// -10.3484534 ----> $-10.34
// 600 ----> $600.00
function convertNumber(){
var result = toFixedNumber(document.getElementById("valueText").value);
document.getElementById("resultText").value = result;
}
function toFixedNumber(number) {
const spitedValues = String(number.toLocaleString()).split('.');
let decimalValue = spitedValues.length > 1 ? spitedValues[1] : '';
decimalValue = decimalValue.concat('00').substr(0,2);
return '$'+spitedValues[0] + '.' + decimalValue;
}
<div>
<input type="text" id="valueText" placeholder="Input value here..">
<br>
<button onclick="convertNumber()" >Convert</button>
<br><hr>
<input type="text" id="resultText" placeholder="result" readonly="true">
</div>
An Easy way to do it is the next but is necessary ensure that the amount parameter is given as a string.
function truncate(amountAsString, decimals = 2){
var dotIndex = amountAsString.indexOf('.');
var toTruncate = dotIndex !== -1 && ( amountAsString.length > dotIndex + decimals + 1);
var approach = Math.pow(10, decimals);
var amountToTruncate = toTruncate ? amountAsString.slice(0, dotIndex + decimals +1) : amountAsString;
return toTruncate
? Math.floor(parseFloat(amountToTruncate) * approach ) / approach
: parseFloat(amountAsString);
}
console.log(truncate("7.99999")); //OUTPUT ==> 7.99
console.log(truncate("7.99999", 3)); //OUTPUT ==> 7.999
console.log(truncate("12.799999999999999")); //OUTPUT ==> 7.99
Here you are. An answer that shows yet another way to solve the problem:
// For the sake of simplicity, here is a complete function:
function truncate(numToBeTruncated, numOfDecimals) {
var theNumber = numToBeTruncated.toString();
var pointIndex = theNumber.indexOf('.');
return +(theNumber.slice(0, pointIndex > -1 ? ++numOfDecimals + pointIndex : undefined));
}
Note the use of + before the final expression. That is to convert our truncated, sliced string back to number type.
Hope it helps!
truncate without zeroes
function toTrunc(value,n){
return Math.floor(value*Math.pow(10,n))/(Math.pow(10,n));
}
or
function toTrunc(value,n){
x=(value.toString()+".0").split(".");
return parseFloat(x[0]+"."+x[1].substr(0,n));
}
test:
toTrunc(17.4532,2) //17.45
toTrunc(177.4532,1) //177.4
toTrunc(1.4532,1) //1.4
toTrunc(.4,2) //0.4
truncate with zeroes
function toTruncFixed(value,n){
return toTrunc(value,n).toFixed(n);
}
test:
toTrunc(17.4532,2) //17.45
toTrunc(177.4532,1) //177.4
toTrunc(1.4532,1) //1.4
toTrunc(.4,2) //0.40
If you exactly wanted to truncate to 2 digits of precision, you can go with a simple logic:
function myFunction(number) {
var roundedNumber = number.toFixed(2);
if (roundedNumber > number)
{
roundedNumber = roundedNumber - 0.01;
}
return roundedNumber;
}
I used (num-0.05).toFixed(1) to get the second decimal floored.
It's more reliable to get two floating points without rounding.
Reference Answer
var number = 10.5859;
var fixed2FloatPoints = parseInt(number * 100) / 100;
console.log(fixed2FloatPoints);
Thank You !
My solution in typescript (can easily be ported to JS):
/**
* Returns the price with correct precision as a string
*
* #param price The price in decimal to be formatted.
* #param decimalPlaces The number of decimal places to use
* #return string The price in Decimal formatting.
*/
type toDecimal = (price: number, decimalPlaces?: number) => string;
const toDecimalOdds: toDecimal = (
price: number,
decimalPlaces: number = 2,
): string => {
const priceString: string = price.toString();
const pointIndex: number = priceString.indexOf('.');
// Return the integer part if decimalPlaces is 0
if (decimalPlaces === 0) {
return priceString.substr(0, pointIndex);
}
// Return value with 0s appended after decimal if the price is an integer
if (pointIndex === -1) {
const padZeroString: string = '0'.repeat(decimalPlaces);
return `${priceString}.${padZeroString}`;
}
// If numbers after decimal are less than decimalPlaces, append with 0s
const padZeroLen: number = priceString.length - pointIndex - 1;
if (padZeroLen > 0 && padZeroLen < decimalPlaces) {
const padZeroString: string = '0'.repeat(padZeroLen);
return `${priceString}${padZeroString}`;
}
return priceString.substr(0, pointIndex + decimalPlaces + 1);
};
Test cases:
expect(filters.toDecimalOdds(3.14159)).toBe('3.14');
expect(filters.toDecimalOdds(3.14159, 2)).toBe('3.14');
expect(filters.toDecimalOdds(3.14159, 0)).toBe('3');
expect(filters.toDecimalOdds(3.14159, 10)).toBe('3.1415900000');
expect(filters.toDecimalOdds(8.2)).toBe('8.20');
Any improvements?
Another solution, that truncates and round:
function round (number, decimals, truncate) {
if (truncate) {
number = number.toFixed(decimals + 1);
return parseFloat(number.slice(0, -1));
}
var n = Math.pow(10.0, decimals);
return Math.round(number * n) / n;
};
function limitDecimalsWithoutRounding(val, decimals){
let parts = val.toString().split(".");
return parseFloat(parts[0] + "." + parts[1].substring(0, decimals));
}
var num = parseFloat(15.7784514);
var new_num = limitDecimalsWithoutRounding(num, 2);
Roll your own toFixed function: for positive values Math.floor works fine.
function toFixed(num, fixed) {
fixed = fixed || 0;
fixed = Math.pow(10, fixed);
return Math.floor(num * fixed) / fixed;
}
For negative values Math.floor is round of the values. So you can use Math.ceil instead.
Example,
Math.ceil(-15.778665 * 10000) / 10000 = -15.7786
Math.floor(-15.778665 * 10000) / 10000 = -15.7787 // wrong.
Gumbo's second solution, with the regular expression, does work but is slow because of the regular expression. Gumbo's first solution fails in certain situations due to imprecision in floating points numbers. See the JSFiddle for a demonstration and a benchmark. The second solution takes about 1636 nanoseconds per call on my current system, Intel Core i5-2500 CPU at 3.30 GHz.
The solution I've written involves adding a small compensation to take care of floating point imprecision. It is basically instantaneous, i.e. on the order of nanoseconds. I clocked 2 nanoseconds per call but the JavaScript timers are not very precise or granular. Here is the JS Fiddle and the code.
function toFixedWithoutRounding (value, precision)
{
var factorError = Math.pow(10, 14);
var factorTruncate = Math.pow(10, 14 - precision);
var factorDecimal = Math.pow(10, precision);
return Math.floor(Math.floor(value * factorError + 1) / factorTruncate) / factorDecimal;
}
var values = [1.1299999999, 1.13, 1.139999999, 1.14, 1.14000000001, 1.13 * 100];
for (var i = 0; i < values.length; i++)
{
var value = values[i];
console.log(value + " --> " + toFixedWithoutRounding(value, 2));
}
for (var i = 0; i < values.length; i++)
{
var value = values[i];
console.log(value + " --> " + toFixedWithoutRounding(value, 4));
}
console.log("type of result is " + typeof toFixedWithoutRounding(1.13 * 100 / 100, 2));
// Benchmark
var value = 1.13 * 100;
var startTime = new Date();
var numRun = 1000000;
var nanosecondsPerMilliseconds = 1000000;
for (var run = 0; run < numRun; run++)
toFixedWithoutRounding(value, 2);
var endTime = new Date();
var timeDiffNs = nanosecondsPerMilliseconds * (endTime - startTime);
var timePerCallNs = timeDiffNs / numRun;
console.log("Time per call (nanoseconds): " + timePerCallNs);
Building on David D's answer:
function NumberFormat(num,n) {
var num = (arguments[0] != null) ? arguments[0] : 0;
var n = (arguments[1] != null) ? arguments[1] : 2;
if(num > 0){
num = String(num);
if(num.indexOf('.') !== -1) {
var numarr = num.split(".");
if (numarr.length > 1) {
if(n > 0){
var temp = numarr[0] + ".";
for(var i = 0; i < n; i++){
if(i < numarr[1].length){
temp += numarr[1].charAt(i);
}
}
num = Number(temp);
}
}
}
}
return Number(num);
}
console.log('NumberFormat(123.85,2)',NumberFormat(123.85,2));
console.log('NumberFormat(123.851,2)',NumberFormat(123.851,2));
console.log('NumberFormat(0.85,2)',NumberFormat(0.85,2));
console.log('NumberFormat(0.851,2)',NumberFormat(0.851,2));
console.log('NumberFormat(0.85156,2)',NumberFormat(0.85156,2));
console.log('NumberFormat(0.85156,4)',NumberFormat(0.85156,4));
console.log('NumberFormat(0.85156,8)',NumberFormat(0.85156,8));
console.log('NumberFormat(".85156",2)',NumberFormat(".85156",2));
console.log('NumberFormat("0.85156",2)',NumberFormat("0.85156",2));
console.log('NumberFormat("1005.85156",2)',NumberFormat("1005.85156",2));
console.log('NumberFormat("0",2)',NumberFormat("0",2));
console.log('NumberFormat("",2)',NumberFormat("",2));
console.log('NumberFormat(85156,8)',NumberFormat(85156,8));
console.log('NumberFormat("85156",2)',NumberFormat("85156",2));
console.log('NumberFormat("85156.",2)',NumberFormat("85156.",2));
// NumberFormat(123.85,2) 123.85
// NumberFormat(123.851,2) 123.85
// NumberFormat(0.85,2) 0.85
// NumberFormat(0.851,2) 0.85
// NumberFormat(0.85156,2) 0.85
// NumberFormat(0.85156,4) 0.8515
// NumberFormat(0.85156,8) 0.85156
// NumberFormat(".85156",2) 0.85
// NumberFormat("0.85156",2) 0.85
// NumberFormat("1005.85156",2) 1005.85
// NumberFormat("0",2) 0
// NumberFormat("",2) 0
// NumberFormat(85156,8) 85156
// NumberFormat("85156",2) 85156
// NumberFormat("85156.",2) 85156
Already there are some suitable answer with regular expression and arithmetic calculation, you can also try this
function myFunction() {
var str = 12.234556;
str = str.toString().split('.');
var res = str[1].slice(0, 2);
document.getElementById("demo").innerHTML = str[0]+'.'+res;
}
// output: 12.23
Here is what is did it with string
export function withoutRange(number) {
const str = String(number);
const dotPosition = str.indexOf('.');
if (dotPosition > 0) {
const length = str.substring().length;
const end = length > 3 ? 3 : length;
return str.substring(0, dotPosition + end);
}
return str;
}

How can I count the number of zero decimals in JavaScript?

How do I get the number of zero decimals behind the comma (but not the total)? So to illustrate an example:
0.00001 > 4
0.000015 > 4
0.0000105 > 4
0.001 > 2
I am looking for methods that are efficient (meaning that they optimize the calculation time).
You can use logarithms to find the magnitude of the number:
var x = 0.00195;
var m = -Math.floor( Math.log(x) / Math.log(10) + 1);
document.write(m); // outputs 2
Later versions of JavaScript have Math.log10, so it would be:
var x = 0.00195;
var m = -Math.floor( Math.log10(x) + 1);
document.write(m); // outputs 2
How using the base-10 logarithm of the numbers works:
x
Math.log10(x)
Math.floor(Math.log10(x) + 1 )
0.1
-1
0
0.01
-2
-1
0.015
-1.8239…
-1
0.001
-3
-2
0.00001
-5
-4
0.000015
-4.8239…
-4
0.0000105
-4.9788…
-4
Use a regex to match the number of zeros after a decimal point and then count them.
var zeros = float.toString().match(/(\.0*)/)[0].length - 1;
DEMO
Use this one:
function numberOfZeros(n) {
var c = 0;
while (!~~n) {
c++;
n *= 10;
}
return c - 1;
}
document.write(numberOfZeros(0.00065));
This code does the following: it multiplies the number by ten as long as it can be truncated to something not equal 0. The truncation operator "~~" is very performant, because it works with byte representation of the number directly.
It doesn't use any string operations and does exactly what you want: counts the zeros.
//my answer
function t1()
{
var num = 0.0000005323;
numOfZeroes = 0;
while(num < 1)
{
numOfZeroes++;
num *= 10;
}
}
//others
//Andrew Morton's answer
//https://stackoverflow.com/a/31002148/1115360
function t2()
{
var num = 0.0000005323;
var m = -Math.floor( Math.log10(num) + 1);
}
//Amy's Answer
//https://stackoverflow.com/a/31002087/4801298
function t3()
{
var r = 0.0000005323;
var count=0;
var splited = r.toString().split(".")[1];
for(var i=0;i<splited.length;i++)
{
if(splited[i]==0)
{
count++;
}
else
{
break;
}
}
}
//Ted's Answer
//https://stackoverflow.com/a/31002052/4801298
function t4()
{
var number = 0.0000005323;
var numberAsString = number.toString();
var decimalsAsString = numberAsString.substr(numberAsString.lastIndexOf('.')+1);
var leadingZeros = decimalsAsString.substr(0, decimalsAsString.lastIndexOf('0')+1).length;
}
//Bartłomiej Zalewski's answer
//https://stackoverflow.com/a/31001998/4801298
function t5()
{
var n = 0.0000005323;
var c = 0;
while (!~~n) {
c++;
n *= 10;
}
return c - 1;
}
//Andy 's answer
//https://stackoverflow.com/a/31002135/4801298
function t6()
{
var float = 0.0000005323;
var zeros = float.toString().match(/(\.0*)/)[0].length - 1;
}
//Praveen's answer
//https://stackoverflow.com/a/31002011/4801298
function t7()
{
var a = 0.0000005323;
return (a.toString().replace("0.", "").split("0").length - 1);
}
//benchmark function
function bench(func)
{
var times = new Array();
for(var t = 0; t < 100; t++)
{
var start = performance.now();
for(var i = 0; i < 10000; i++)
{
func();
}
var end = performance.now();
var time = end - start;
times.push(time);
}
var total = 0.0;
for(var i=0, l=times.length; i<l; i++)
total += times[i];
var avg = total / times.length;
return avg;
}
document.write('t1: ' + bench(t1) + "ms<BR>");
document.write('t2: ' + bench(t2) + "ms<BR>");
document.write('t3: ' + bench(t3) + "ms<BR>");
document.write('t4: ' + bench(t4) + "ms<BR>");
document.write('t5: ' + bench(t5) + "ms<BR>");
document.write('t6: ' + bench(t6) + "ms<BR>");
document.write('t7: ' + bench(t7) + "ms<BR>");
Note:
This would only work with numbers less than 1 of course. Otherwise, just remove numbers left of the decimal point first, like
num -= num % 1;
need to compare this to another way.
a while later...
I would like a better way to bench these function though. I might have my calculation wrong. I'm adding other peoples answers into the test. I'm now attempting to use the performance API
a bit later than before
AHA! Got it working. Here are some comparisons for you.
You can use something like this:
function num (a) {
return (a.toString().replace("0.", "").split("0").length - 1)
}
Here is a working example (a bit lengthy for clarity):
var number = 0.0004342;
var numberAsString = number.toString();
var decimalsAsString = numberAsString.substr(numberAsString.lastIndexOf('.')+1);
var leadingZeros = decimalsAsString.substr(0, decimalsAsString.lastIndexOf('0')+1).length;
// leadingZeros == 3
Convert the number in to a string and split it with the dot (.). Using the for loop to count the zeros occurrences.
var r = 0.0000107;
var count=0;
var splited = r.toString().split(".")[1];
for(var i=0;i<splited.length;i++)
{
if(splited[i]==0)
{
count++;
}
else
{
break;
}
}
console.log(count);
Node.js 9.0.0
I was looking for a solution without converting or the O(n) approach. Here is what solution I made by O(1).
Part of finding decimal by log – caught from #AndrewMorton, but it might be laggy with the divider: log(10) – 2.302585092994046.
Example
const normalize = (value, zeroCount) => {
const total = 10 ** zeroCount
const zeros = Math.floor(-Math.log10(value / total))
return value * (10 ** zeros)
}
Usage
normalize(1510869600, 13) // 1510869600000
normalize(1510869600, 10) // 1510869600

Limit numbers after decimal, add 0 if one digit

I'm trying to make a text field so that if there's a number 153.254, that becomes 153.25. And if the field contains 154.2, an extra 0 is added to fill two spots after decimal; 154.20.
toFixed() works great but I don't want the number rounded. Also came across other solutions where if I'm typing in 1.40, then if I move the cursor back after 1, I can't type anything in unless I clear the field and start over.
Is there a simple jQuery way to limit two characters after a decimal, and then if there's only one character after the decimal, add a zero to fill the two character limit?
(The field may receive value from database that's why the second part is required)
Solution Update: For those interested, I put this together to achieve what I wanted (Thanks to answers below and also other questions here on stackoverflow)
$('.number').each(function(){
this.value = parseFloat(this.value).toFixed(3).slice(0, -1);
});
$('.number').keyup(function(){
if($(this).val().indexOf('.')!=-1){
if($(this).val().split(".")[1].length > 2){
if( isNaN( parseFloat( this.value ) ) ) return;
this.value = parseFloat(this.value).toFixed(3).slice(0, -1);
}
}
return this; //for chaining
});
you could do myNumber.toFixed(3).slice(0, -1)
try this:
var num = 153.2
function wacky_round(number, places) {
var h = number.toFixed(2);
var r = number.toFixed(4) * 100;
var r2 = Math.floor(r);
var r3 = r2 / 100;
var r4 = r3.toFixed(2);
var hDiff = number - h;
var r4Diff = number - r3;
var obj = {};
obj[hDiff] = h;
obj[r4Diff] = r4;
if (r4Diff < 0) {
return h;
}
if (hDiff < 0) {
return r4;
}
var ret = Math.min(hDiff, r4Diff);
return obj[ret];
}
alert(wacky_round(num, 2))
How about
function doStuff(num){
var n = Math.floor(num * 100) / 100,
s = n.toString();
// if it's one decimal place, add a trailing zero:
return s.split('.')[1].length === 1 ? (s + '0') : n;
}
console.log(doStuff(1.1), doStuff(1.111)); // 1.10, 1.11
http://jsfiddle.net/NYnS8/

javascript timer with comma [duplicate]

This question already has answers here:
How to format numbers as currency strings
(67 answers)
Closed 9 years ago.
I want to display the dollar timer which goes from 1 to 2500. When the timer increases to 1000, I want to display it as $1,000 instead of $1000. I want commas in thousands place.Could someone help me with this JavaScript.
Thanks.
You could easily do this with a regular expression.
var friendlyNum = (num + "").replace(/^(\d)(\d{3})$/, "$1,$2");
Note that this will only handle 1000 places.
How it works is an exercise to the reader. For learning how they work, stat here.
Even though it's been written a thousand times, I felt like writing some JS.
var addCommas = function(number) {
number = '' + number;
var negative = false;
if (number.match(/^\-/)) {
negative = true;
}
number = number.replace(/[^0-9\.]/g, '');
number = number.split('.');
var before = number.shift()
, after = number.join('');
for (var i = (before.length - 3); i > 0; i -= 3) {
before = before.substr(0, i) + ',' + before.substr(i)
}
return (negative ? '-' : '') + before + (after ? '.' + after : '');
}
// 1,000.00
addCommas(1000.00);
// -1,234,567,890
addCommas('-1234567890');
Below is the approach to convert number format (comma separated)
HTML :-
<input type="text" onkeyup="convertNumberFormat(this.value)" />
JavaScript:-
function convertNumberFormat(inputValue)
{
inputValue = inputValue.toString();
inputValue = inputValue.replace( /\,/g, "");
var x = inputValue.split( '.' );
var intValue = x[0];
var floatValue = x.length > 1 ? '.' + x[1] : '';
var rgx = /(\d+)(\d{3})/;
while ( rgx.test(intValue) ) {
intValue = intValue.replace( rgx, '$1' + ',' + '$2' );
}
alert(intValue + floatValue);
}
In HTML template I am calling this function at "onkeyup" event.
you just need to call "convertNumberFormat" function whenever you want to validate your input value and pass current inserted value...
Example:-
convertNumberFormat('$2500');
Output:-
'$2,500' // in alert.
hope this can help you...

How can I add a comma to separate each group of three digits in a text input field?

I have a text input field for a form where users are meant to enter a number. I would like to automatically insert a comma after every third digit.
For example, entering '20' would result in '20'. Entering '100' would result in '100'. But if they were to enter '1000', a comma would be inserted between the 1 and the following 0's (e.g., 1,000). Obviously this behaviour would continue should the number reach 7 digits (e.g., 1,000,000).
Is there an easy way to do this? I'm a bit of a newb at all of this, so please answer like you're talking to a child :)
The following javascript:
function format(input)
{
var nStr = input.value + '';
nStr = nStr.replace( /\,/g, "");
var x = nStr.split( '.' );
var x1 = x[0];
var x2 = x.length > 1 ? '.' + x[1] : '';
var rgx = /(\d+)(\d{3})/;
while ( rgx.test(x1) ) {
x1 = x1.replace( rgx, '$1' + ',' + '$2' );
}
input.value = x1 + x2;
}
and the following HTML:
<input type="text" onkeyup="format(this)">
should solve your problem. The key is to use 'onkeyup'.
Try it here http://jsfiddle.net/YUSph/
for the fun of it:
'9876543210'
.split('') // flip the entire string so that we can break every
.reverse() // 3rd digit, starting from the end
.join('')
.split(/(...)/) // split on every 3rd
.reverse() // flip the string again, though now each group of 3 is
.join(',') // backwards
.replace(/,(?=,)|,$|^,/g, '') // remove extra ,
.replace(/(,|^)(\d)(\d)?(\d)?/g, '$1$4$3$2') // flip each group of digits
// 9,876,543,210
Anyone want to take a stab at making that better?
function addCommas(nStr){
nStr += '';
x = nStr.split('.');
x1 = x[0];
x2 = x.length > 1 ? '.' + x[1] : '';
var rgx = /(\d+)(\d{3})/;
while (rgx.test(x1)) {
x1 = x1.replace(rgx, '$1' + ',' + '$2');
}
return x1 + x2;
}
Pass the value of the input into function and set the input with the result returned. You can bind this to an onchange event.
Here is a working example that relies on jquery to bind the change event and set the value: http://jsfiddle.net/TYyfn/
Comma script is from: http://www.mredkj.com/javascript/nfbasic.html
Yes, it's not terribly difficult. I believe this reference may give you what you need.
Note that for this to be dynamic (as they type) you'd need to have this wired to the input field change handler. Otherwise, you can wire this to the input field blur handler (which will have the effect of putting the commas in the field when they leave the field).
Give this a try: it may need a little tweeking.
take the function from above: function addCommas(nStr){...} and put in a js file.
add a script link in the page header to jquery library with:
src="http://ajax.googleapis.com/ajax/libs/jquery/1.5/jquery.min.js"
be sure your text box has a unique id. ex: id="comma_input".
in the same js file add
$(document).ready(function(){
$('#comma_input').keyup(function(){
$(this).attr('value',addCommas($(this).attr('value')));
});
});
function addCommas(nStr){
var offset = nStr.length % 3;
if (offset == 0)
return nStr.substring(0, offset) + nStr.substring(offset).replace(/([0-9]{3})(?=[0-9]+)/g, "$1,");
else
return nStr.substring(0, offset) + nStr.substring(offset).replace(/([0-9]{3})/g, ",$1");
}
alert(addCommas("1234567"));
Another way to do it, no RegEx, just array manipulation:
function decimalMark(s) {
for (var a = s.split("").reverse(), b = [], i = 0; i < a.length; i++) {
if (i && i%3 === 0)
b.unshift(",");
b.unshift(a[i]);
}
return b.join("");
}
Be sure to pass a string to the function
decimalMark("1234")
Simple string solution in pure JS:
function addCommas(e) {
var tgt = e.target, val = tgt.value.replace(/,/g, ''),
amt = Math.ceil(val.length/3), newStr = '', x = 0;
while ( x <= amt ) {
newStr += val.slice(x*3,(x+1)*3);
newStr += ( x < amt-1 ) ? ',' : '';
x++
}
tgt.value = newStr;
}
document.getElementById('test').addEventListener('change', addCommas, false);
Demo: http://jsfiddle.net/kevinvanlierde/TYyfn/141/
You can use standart JavaScript functions. Example here;
http://jsfiddle.net/azur/jD5pa/
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>pure js solution</title>
<script type='text/javascript'>
function digitGroup(dInput) {
var output = "";
try {
dInput = dInput.replace(/[^0-9]/g, ""); // remove all chars including spaces, except digits.
var totalSize = dInput.length;
for (var i = totalSize - 1; i > -1; i--) {
output = dInput.charAt(i) + output;
var cnt = totalSize - i;
if (cnt % 3 === 0 && i !== 0) {
output = " " + output; // seperator is " "
}
}
} catch (err)
{
output = dInput; // it won't happen, but it's sweet to catch exceptions.
}
return output;
}
</script>
</head>
<body>
<input type="text" value="53" onkeyup="this.value = digitGroup(this.value);">
</body>
</html>
var formatNumber = function(num, type) {
var numSplit, int, dec, type;
num = Math.abs(num);
num = num.toFixed(2);
numSplit = num.split('.')
int = numSplit[0];
if (int.length >= 3) {
int = int.substr(0, int.length - 3) + ',' + int.substr(int.length - 3, 3);
}
dec = numSplit[1];
return (type === 'exp'? sign = '-' : '+') + ' ' + int + '.' + dec;
};

Categories