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

tem*_*pid 179 javascript

假设我的值为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));
Run Code Online (Sandbox Code Playgroud)

结果是 -

15.8
15.78
15.778
15.7784514000 
Run Code Online (Sandbox Code Playgroud)

我如何显示15.77?

Gum*_*mbo 211

将数字转换为字符串,将数字与第二个小数位匹配:

function calc(theform) {
    var num = theform.original.value, rounded = theform.rounded
    var with2Decimals = num.toString().match(/^-?\d+(?:\.\d{0,2})?/)[0]
    rounded.value = with2Decimals
}
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)

toFixed在某些情况下toString,该方法不同,所以要非常小心.

  • 如果值= 4.27严重,Math.floor(值*100)/ 100将无效,请尝试. (23认同)
  • +1应该解决舍入问题.我仍然使用`toFixed`输出上面的结果,所以:`(Math.floor(value*100)/ 100).toFixed(2)`.正如您可能知道的那样,浮点值可能会出现奇怪的精确事物(如果数字恰好为15,则听起来就像是15'那样). (22认同)
  • @DarkHippo多数民众赞成因为4.27实际上是4.26999999999,Math.round通常是一个更好的解决方案,虽然不是原始问题的答案.实际上,给定输出是一个字符串,这应该使用字符串操作而不是具有所有浮点弱点的数字解决方案来完成. (3认同)
  • ......听起来不对劲.在任何情况下,不同类型之间的转换似乎是迂回和不安全的.除非一个真正高级的程序员认为"所有类型只是流"或其他东西. (2认同)
  • @AnubhavGupta要使其在小数点之前没有值的情况下工作,只需将正则表达式中的+更改为*,这样你就得到: `match(/^-?\d*(?:\.\d{0,2})?/ )` (2认同)

guy*_*uya 58

2016年11月5日更新

新答案,始终准确

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

由于javascript中的浮点数学将始终具有边缘情况,因此以前的解决方案在大多数情况下都是准确的,这是不够好的.对于这个像一些解决方案num.toPrecision,BigDecimal.jsaccounting.js.然而,我相信仅仅解析字符串将是最简单且始终准确的.

基于@Gumbo接受的答案中写得好的正则表达式的更新,这个新的toFixed函数将始终按预期工作.


老答案,并不总是准确的.

滚动你自己的固定功能:

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

  • toFixed(4.56,2)= 4.55 (5认同)
  • 如果数字足够大或足够小,以至于 javascript 可以用科学记数法表示,则更新的答案将失败。`toFixed(0.0000000052, 2)` 产生“5.2”。这可以通过使用“return num.toFixed(fixed+1).match(re)[0];”来修复,请注意,我使用 toFixed 在目标上方保留一位小数以避免四舍五入,然后运行正则表达式匹配 (5认同)
  • 这些答案中有很多都在Math.floor()函数中有一个乘法.对于某些数字,这将失败!浮点运算不准确,您需要使用不同的方法. (2认同)

ベンノ*_*ノスケ 31

我选择写这个来手动删除字符串的余数,所以我不必处理数字带来的数学问题:

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
Run Code Online (Sandbox Code Playgroud)

这将给你"15.77"与num = 15.7784514;

  • 如果您没有强制使用小数,则可能需要添加条件以防遇到整数.像这样:num = num.toString(); if(num.indexOf(".")> 0){num = num.slice(0,(num.indexOf("."))+ 3)}; 号(NUM); (5认同)
  • @Vasanth 如果数字为 0.00000052,则返回“0.00”。也许从那以后答案已被编辑 (2认同)

rem*_*dej 31

另一个单线解决方案:

number = Math.trunc(number*100)/100
Run Code Online (Sandbox Code Playgroud)

我使用 100 是因为您想截断到第二个数字,但更灵活的解决方案是:

number = Math.trunc(number*Math.pow(10, digits))/Math.pow(10, digits)
Run Code Online (Sandbox Code Playgroud)

其中digits 是要保留的十进制数字的数量。

有关详细信息和浏览器兼容性,请参阅Math.trunc 规范

  • @T.Junghans 抱歉,但这不起作用:(4.27, 2) =&gt; 4.26,无论 IE11 或任何其他浏览器如何,都会发生这种情况。 (4认同)
  • 如果您不必支持 IE11,这是最好的答案。 (3认同)

SC1*_*000 15

2017年10月

对于任何n≥0,将任意数字截断(不舍入)到第n个十进制数字并将其转换为精确n个十进制数字的字符串的一般解决方案.

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}`
}
Run Code Online (Sandbox Code Playgroud)

以下是n = 2的一些测试(包括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
0.000000199 => 1.99 *
Run Code Online (Sandbox Code Playgroud)

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

15.001097   => 15.0010 (n=4)
0.000003298 => 0.0000032 (n=7)
0.000003298257899 => 0.000003298257 (n=12)
Run Code Online (Sandbox Code Playgroud)

虽然在概念上是正确的,但由于数字在内部表示的方式,这会因一些无理数而失败,例如4.27.

  • `toFixedTrnc(0.000000199, 2) // 1.99 ` (3认同)

小智 13

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"
Run Code Online (Sandbox Code Playgroud)

  • floorFigure(4.56,2)= 4.55 (3认同)
  • 它失败了1234567.89 (2认同)

Ara*_*oca 8

只需截断数字:

function truncDigits(inputNumber, digits) {
  const fact = 10 ** digits;
  return Math.floor(inputNumber * fact) / fact;
}
Run Code Online (Sandbox Code Playgroud)


小智 7

我使用以下简单的方法修复了 -

var num = 15.7784514;
Math.floor(num*100)/100;
Run Code Online (Sandbox Code Playgroud)

结果将为15.77


小智 6

num = 19.66752
f = num.toFixed(3).slice(0,-1)
alert(f)
Run Code Online (Sandbox Code Playgroud)

这将返回19.66

  • (4.9999).toFixed(3).slice(0,-1)返回5.00,预期结果为4.99。 (3认同)
  • 我建议使用 .toFixed(6).slice(0, -4) 之类的东西代替。 (3认同)

Imr*_*lob 6

这很简单

number = parseInt(number * 100)/100;
Run Code Online (Sandbox Code Playgroud)

  • parseInt(8.2 * 100)= 819 (2认同)

jtr*_*ick 5

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

num-=num%.01;
Run Code Online (Sandbox Code Playgroud)

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


Dav*_*d D 5

这里的答案没有帮助我,它继续四舍五入或给我错误的小数.

我的解决方案将您的小数转换为字符串,提取字符然后将整个事物作为数字返回.

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
Run Code Online (Sandbox Code Playgroud)


Alp*_*ega 5

我的正数版本:

function toFixed_norounding(n,p)
{
    var result = n.toFixed(p);
    return result <= n ? result: (result - Math.pow(0.1,p)).toFixed(p);
}
Run Code Online (Sandbox Code Playgroud)

快速,漂亮,显而易见。(版本为正数)


San*_*aru 5

这对我来说效果很好。我希望它也能解决您的问题。

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
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)
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;
}
Run Code Online (Sandbox Code Playgroud)


Rub*_*lix 5

function formatLimitDecimals(value, decimals) {
  value = value.toString().split('.')

  if (value.length === 2) {
    return Number([value[0], value[1].slice(0, decimals)].join('.'))
  } else {
    return Number(value[0]);
  }
}

console.log(formatLimitDecimals(4.156, 2)); // 4.15
console.log(formatLimitDecimals(4.156, 8)); // 4.156
console.log(formatLimitDecimals(4.156, 0)); // 4
Run Code Online (Sandbox Code Playgroud)


小智 5

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);
Run Code Online (Sandbox Code Playgroud)