将数字截断为两位小数而不进行舍入
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了将数字截断为两位小数而不进行舍入相关的知识,希望对你有一定的参考价值。
假设我的值为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?
将数字转换为字符串,将数字与第二个小数位匹配:
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>
这些解决方案确实有效,但对我来说似乎不必要地复杂化。我个人喜欢使用模运算符来获得除法运算的剩余部分,并删除它。假设num = 15.7784514:
num-=num%.01;
这相当于说num = num - (num%.01)。
以下代码对我非常有用:
num.toString().match(/.*\..{0,2}|.*/)[0];
我使用以下简单方法修复 -
var num = 15.7784514;
Math.floor(num*100)/100;
结果将是15.77
这个给你。答案显示了另一种解决问题的方法:
// 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));
}
注意在最终表达式之前使用+。那就是将截断的切片字符串转换回数字类型。
希望能帮助到你!
截断没有零
function toTrunc(value,n){
return Math.floor(value*Math.pow(10,n))/(Math.pow(10,n));
}
要么
function toTrunc(value,n){
x=(value.toString()+".0").split(".");
return parseFloat(x[0]+"."+x[1].substr(0,n));
}
测试:
toTrunc(17.4532,2) //17.45
toTrunc(177.4532,1) //177.4
toTrunc(1.4532,1) //1.4
toTrunc(.4,2) //0.4
用零截断
function toTruncFixed(value,n){
return toTrunc(value,n).toFixed(n);
}
测试:
toTrunc(17.4532,2) //17.45
toTrunc(177.4532,1) //177.4
toTrunc(1.4532,1) //1.4
toTrunc(.4,2) //0.40
一个简单的方法是下一步,但必须确保amount参数以字符串形式给出。
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
我使用(num-0.05).toFixed(1)
得到第二个小数点。
另一个单线解决方案:
number = Math.trunc(number*100)/100
我使用100因为你想要截断到第二个数字,但更灵活的解决方案是:
number = Math.trunc(number*Math.pow(10, digits))/Math.pow(10, digits)
其中digits是要保留的小数位数。
这对我很有用。我希望它也能解决你的问题。
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>
只是截断数字:
function truncDigits(inputNumber, digits) {
const fact = 10 ** digits;
return Math.floor(inputNumber * fact) / fact;
}
Update 5 Nov 2016
新答案,始终准确
function toFixed(num, fixed) {
var re = new RegExp('^-?\d+(?:.\d{0,' + (fixed || -1) + '})?');
return num.toString().match(re)[0];
}
由于floating point math in javascript总是有边缘情况,以前的解决方案在大多数时间都是准确的,这还不够好。有一些解决方案,如num.toPrecision
,BigDecimal.js和accounting.js。然而,我相信仅仅解析字符串将是最简单且始终准确的。
基于@Gumbo接受的答案中写得好的正则表达式的更新,这个新的toFixed函数将始终按预期工作。
老答案,并不总是准确的。
滚动你自己的固定功能:
function toFixed(num, fixed) {
fixed = fixed || 0;
fixed = Math.pow(10, fixed);
return Math.floor(num * fixed) / fixed;
}
滚动你自己的toFixed
功能:对于正值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.
Gumbo的第二个解决方案,使用正则表达式,确实有效,但由于正则表达式,它很慢。由于浮点数不精确,Gumbo的第一个解决方案在某些情况下失败。请参阅JSFiddle进行演示和基准测试。第二种解决方案在我当前的系统上每次呼叫大约需要1636纳秒,即3.30 GHz的英特尔酷睿i5-2500 CPU。
我写的解决方案涉及添加一个小补偿来处理浮点不精确。它基本上是瞬时的,即在纳秒级。我每次调用时钟为2纳秒,但javascript定时器不是非常精确或粒度。这是JS Fiddle和代码。
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.以上是关于将数字截断为两位小数而不进行舍入的主要内容,如果未能解决你的问题,请参考以下文章