将数字截断为两位小数而不进行舍入

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.toPrecisionBigDecimal.jsaccounting.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.

以上是关于将数字截断为两位小数而不进行舍入的主要内容,如果未能解决你的问题,请参考以下文章

JS实现浮点数精确舍入小数点

只保留小数点后的前两位数字,不四舍五入[重复]

不能将小数舍入到R中的两位小数

excel截取小数点前的函数,例如:500.00,我要截取500

T-SQL如何保留两位小数而不四舍五入[重复]

如何在不自动舍入的情况下在 SQL Server 中返回具有两位小数的数字