显示两位小数,不舍入

假设我有一个值15.7784514,我想显示它15.77没有四舍五入。

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)); 

结果是 –

 15.8 15.78 15.778 15.7784514000 

我如何显示15.77?

将数字转换为一个string,将数字匹配到小数点后第二位:

 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> 

2016年11月5日更新

新的答案,总是准确的

 function toFixed(num, fixed) { var re = new RegExp('^-?\\d+(?:\.\\d{0,' + (fixed || -1) + '})?'); return num.toString().match(re)[0]; } 

由于JavaScript中的浮点math总是有边缘情况,以前的解决scheme在大多数情况下是准确的,这是不够好的。 有一些像num.toPrecision , BigDecimal.js和accounting.js这样的解决scheme。 然而,我相信只是parsingstring将是最简单的,总是准确的。

基于由@Gumbo接受的答案写得很好的正则expression式的更新,这个新的toFixed函数将始终按预期方式工作。


旧的答案,并不总是准确的。

自己动手修复function:

 function toFixed(num, fixed) { fixed = fixed || 0; fixed = Math.pow(10, fixed); return Math.floor(num * fixed) / fixed; } 

我select写这个,而不是手动删除string的余数,所以我不必处理与数字来的math问题:

 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 

这会给你“15.77”num = 15.7784514;

parseInt比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" 

这些解决scheme确实奏效,但对我来说似乎不必要的复杂。 我个人喜欢使用模运算符来获得除法运算的其余部分,并删除它。 假设num = 15.7784514:

 num-=num%.01; 

这相当于说num = num – (num%.01)。

这里的答案并没有帮助我,它一直在四舍五入或给我错误的小数。

我的解决scheme将您的小数转换为一个string,提取字符,然后返回整个事情作为一个数字。

 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 

你可以得到精确到N小数的位置(使用更多的效果更好),然后删除string值中最后不需要的字符:

 var num = parseFloat(15.7784514); var str = num.toFixed(20); str = str.substring(0, str.length-7); // str = 15.77 

以下代码对我来说非常有用:

 num.toString().match(/.\*\\..{0,2}|.\*/)[0]; 

我的版本:

 function toFixed_norounding(n,p) { result = n.toFixed(p); return result <= n ? result: (result - Math.pow(0.1,p)).toFixed(p); } 

快,漂亮,明显。

这个给你。 答案显示了另一种解决问题的方法:

 // 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)); } 

注意在最终expression式之前使用+。 这是将我们截断的切片的string转换回数字types。

希望它有帮助!

2017年10月

一般的解决方法是将任意数字截尾(不舍入)到第n个十进制数字,并将其转换为正好有n个十进制数字的string,对于任何n≥0。

 function toFixedTrunc(value, n) { const v = value.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}` } 

以下是一些n = 2的testing(包括OP所要求的testing):

 0 => 0.00 0.01 => 0.01 0.2372 => 0.23 0.5839 => 0.58 0.999 => 0.99 1 => 1.00 1.01 => 1.01 2 => 2.00 2.551 => 2.55 2.5 => 2.50 2.99999 => 2.99 4.27 => 4.27 15.7784514 => 15.77 123.5999 => 123.59 

请注意,虽然上述工作总是 ,纯粹的数字方法不会。 例如,考虑以下function(或任何类似的function):

 function toFixedTrunc(value, n) { const f = Math.pow(10, n); return (Math.trunc(value*f)/f).toFixed(n); } 

虽然在概念上是正确的,但由于数字在内部被表示的方式,会有一些不合理的数字,例如中间人注意到的4.27。

把你自己的固定function:正值Math.floor工作正常。

 function toFixed(num, fixed) { fixed = fixed || 0; fixed = Math.pow(10, fixed); return Math.floor(num * fixed) / fixed; } 

对于负值, Math.floor是值的四舍五入。 所以你可以使用Math.ceil来代替。

例,

 Math.ceil(-15.778665 * 10000) / 10000 = -15.7786 Math.floor(-15.778665 * 10000) / 10000 = -15.7787 // wrong. 

与正则expression式相比,Gumbo的第二个解决scheme确实有效,但是由于正则expression式而缓慢。 由于浮点数不精确,Gumbo的第一个解决scheme在某些情况下失败。 查看JSFiddle的演示和基准。 第二种解决scheme在我目前的系统上,每次通话大约需要1636纳秒,而Intel Core i5-2500 CPU则是3.30 GHz。

我写的解决scheme涉及到添加一个小的补偿来照顾浮点不精确。 它基本上是瞬时的,即在纳秒量级。 我每次调用的时钟为2纳秒,但JavaScript定时器不是非常精确或精确。 这里是JS小提琴和代码。

 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); 

我用(num-0.05).toFixed(1)来获得第二个小数位。

 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 

build立在David D的答案上:

 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 

感谢Martin Varmus

 function floorFigure(figure, decimals){ if (!decimals) decimals = 2; var d = Math.pow(10,decimals); return ((figure*d)/d).toFixed(decimals); }; floorFigure(123.5999) => "123.59" floorFigure(123.5999, 3) => "123.599" 

我做了一个简单的更新,我得到了适当的四舍五入。 更新如下

 return ((figure*d)/d).toFixed(decimals); 

删除parseInt()函数

这里是另一个保存.toFixed([digits])function的变体,没有四舍五入的浮点variables:

 Number.prototype.toRealFixed = function(digits) { return Math.floor(this.valueOf() * Math.pow(10, digits)) / Math.pow(10, digits); }; 

并呼吁:

 var float_var = 0.02209062; float_var.toRealFixed();