ChatGPT解决这个技术问题 Extra ChatGPT

将数字格式化为始终显示 2 位小数

我想将我的数字格式化为始终显示 2 位小数,并在适用的情况下四舍五入。

例子:

number     display
------     -------
1          1.00
1.341      1.34
1.345      1.35

我一直在使用这个:

parseFloat(num).toFixed(2);

但它将 1 显示为 1,而不是 1.00

我的意思是如果我输入 1 它不会将数字显示为 1.00,但是如果我输入 1.345 那么它将显示 1.35
我已将您的问题改写为我相信您正在寻找的内容。请检查以确保我对您的理解正确。
带有 ie 支持的精确舍入。 gist.github.com/ArminVieweg/28647e735aa6efaba401

C
Corey
(Math.round(num * 100) / 100).toFixed(2);

现场演示

var num1 = "1"; document.getElementById('num1').innerHTML = (Math.round(num1 * 100) / 100).toFixed(2); var num2 = "1.341"; document.getElementById('num2').innerHTML = (Math.round(num2 * 100) / 100).toFixed(2); var num3 = "1.345"; document.getElementById('num3').innerHTML = (Math.round(num3 * 100) / 100).toFixed(2);跨度{边框:1px实心#000;边距:5px;填充:5px; }

请注意,它将四舍五入到小数点后 2 位,因此输入 1.346 将返回 1.35


@Kooilnc:OP 希望 1 显示为 1.00,而 1.341 显示为 1.34
无需使用 round(),因为 toFixed() 会对其进行舍入。
toFixed() 确实对它进行了四舍五入,但不要忘记它返回一个字符串......所以这个方法实际上只对显示有用。如果要对舍入值执行进一步的数学计算,请不要使用 toFixed()。
根据 MDN,由于舍入误差,Math.round 并不总是给出准确的结果。我用 1.005 对此进行了测试,它应该四舍五入到 1.01,但它给出了 1.00。使用我的答案以获得一致的准确性:stackoverflow.com/a/34796988/3549440
整个答案可以简化为 (+num).toFixed(2)。它甚至保留了原始的舍入错误,请参见 Nate's answer
F
Florian
Number(1).toFixed(2);         // 1.00
Number(1.341).toFixed(2);     // 1.34
Number(1.345).toFixed(2);     // 1.34 NOTE: See andy's comment below.
Number(1.3450001).toFixed(2); // 1.35

document.getElementById('line1').innerHTML = Number(1).toFixed(2); document.getElementById('line2').innerHTML = Number(1.341).toFixed(2); document.getElementById('line3').innerHTML = Number(1.345).toFixed(2); document.getElementById('line4').innerHTML = Number(1.3450001).toFixed(2);



@Andre,Chrome 29.0.1547.57 给了我 1.34 来表达 Number(1.345).toFixed(2)
toFixed 确实会进行四舍五入,您几乎可以在每个测试编号上看到它。
在完成之前意外提交了最后一条评论.. 1.345 是一个无法以浮点数精确存储的数字的示例,所以我认为它没有按您期望的那样四舍五入的原因是它实际上存储为一个略小于 1.345 的数字,向下舍入。如果您使用 (1.34500001).toFixed(2) 进行测试,那么您会看到它正确地四舍五入到 1.35
很晚了,但为了阐明“5”的四舍五入,它总是四舍五入到最接近的偶数。 1.345 将四舍五入为 1.34,但 1.335 也是如此。一半时间 5 上升,一半时间 5 下降。
@Bardicer,1.335 轮到 1.33 使用 toFixed(2)
r
razu

如果 value = 1.005This answer 将失败。

作为更好的解决方案,可以通过使用指数符号表示的数字来避免舍入问题:

Number(Math.round(1.005+'e2')+'e-2'); // 1.01

@Kon 和原作者建议的更简洁的代码:

Number(Math.round(parseFloat(value + 'e' + decimalPlaces)) + 'e-' + decimalPlaces)

您可以在末尾添加 toFixed() 以保留小数点,例如:1.00 但请注意它将作为字符串返回。

Number(Math.round(parseFloat(value + 'e' + decimalPlaces)) + 'e-' + decimalPlaces).toFixed(decimalPlaces)

学分:Rounding Decimals in JavaScript


令人惊讶的是,这里的其他人都没有看到 toFixed 存在舍入问题。你的答案应该是被接受的。
刚刚测试看看是否仍然如此。您对于 Chrome 版本 59.0.3071.115 仍然是正确的 您的解决方案将四舍五入为 1.005 (1.01) 并向下舍入为 1.00499999 (1.00)
jsfiddle.net/Artistan/qq895bnp/28 toFixed 有时会起作用,但非常不一致。 :)
parseFloat 中的环绕 Number 是它的返回字符串
这是一个可靠的答案。我能想到的一些改进:(1)VS Code(TypeScript 文件)不喜欢 Math.round() 传递字符串。 (2) 使小数位数动态化(未硬编码为 2)。 (3) toFixed() 似乎没有必要。所以我想出的是Number(Math.round(parseFloat(value + 'e' + decimalPlaces)) + 'e-' + decimalPlaces)
h
holmis83

对于现代浏览器,请使用 toLocaleString

var num = 1.345;
num.toLocaleString(undefined, { maximumFractionDigits: 2, minimumFractionDigits: 2 });

指定一个语言环境标记作为第一个参数来控制 decimal separator。对于点,例如使用英语美国语言环境:

num.toLocaleString("en-US", { maximumFractionDigits: 2, minimumFractionDigits: 2 });

这使:

1.35

欧洲的大多数国家/地区都使用逗号作为小数分隔符,因此如果您使用瑞典语/瑞典语语言环境:

num.toLocaleString("sv-SE", { maximumFractionDigits: 2, minimumFractionDigits: 2 });

它会给:

1,35


m
mplungjan

var num = 新数字(14.12); console.log(num.toPrecision(2)); //输出 14 console.log(num.toPrecision(3)); //输出 14.1 console.log(num.toPrecision(4)); //输出 14.12 console.log(num.toPrecision(5)); //输出 14.120


这会产生意想不到的结果,如果你的数字可以是 1.4、23.654 和 0,你会采用什么精度?
请注意,OP 要求“在适用的情况下进行四舍五入”toPrecision 仅将数字格式化为特定的小数位数,只是省略了多余的位,但不四舍五入。当然,这也可能非常有用,但了解其中的区别很重要。
根据 Mozilla 的说法,实际上 toPrecision 确实是圆的。测试:(20.55).toPrecision(3) "20.6"
如果要 strip trailing zeros,请在使用 toFixed 后将其转换为数字或浮点数:const formattedVal = Number(val.toFixed(2)); 不要使用 toPrecision,因为它在使用精度参数时会计算非十进制数字。
I
Imbro

我建议你使用

new Intl.NumberFormat('de-DE', { minimumFractionDigits: 2, maximumFractionDigits: 2 }).format(num)

这样,您还将拥有您指定的国家/地区的本地格式,而且它会保证显示精确的 2 位小数(无论 num 是 1 还是 1.12345,它将分别显示 1.00 和 1.12)

在此示例中,我使用了德语本地化,因为我希望我的数字以千位分隔符显示,所以这将是一些输出:

1 => 1,00
1.12 => 1,12
1.1234 => 1,12
1234 => 1.234,00
1234.1234 => 1.234,12

被低估的答案。此方法可以格式化所有您想要的格式,从千位格式到小数位数
Ich küsse deine Augen。
很好的答案。谢谢你。作为旁注:这个英文版本使用:'en-US'而不是'de-DE'
@Dave 正如我解释的那样,我故意使用德语进行非典型格式来表达观点。可以使用任何想要的本地化,有数百个。另一个英文例子是'en-GB'
非常感谢,我在搜索如何格式化愚蠢的数字时浪费了两个小时。德姆
m
mplungjan

为获得最精确的舍入,创建此函数并使用它舍入到小数点后 2 位:

函数 round(value, decimals) { return Number(Math.round(value + 'e' + decimals) + 'e-' + decimals).toFixed(decimals); } console.log("寻求" + round(1.005, 2));

> 1.01

感谢 Razuthis 文章和 MDN's Math.round reference


1.0049999999999998934 呢?
它不超过 2 dp
jsfiddle.net/Artistan/qq895bnp 测试,这是我见过的唯一一致的方法。谢谢。
m
macio.Jun

最简单的答案:

var num = 1.2353453;
num.toFixed(2); // 1.24

示例:http://jsfiddle.net/E2XU7/


嗯,stackoverflow.com/a/13292833/218196 中已经建议了 toFixed。您的问题提供了哪些额外信息?
该答案不包括圆形功能,我的答案包括寿。
呃?这是完全相同的答案。在号码上呼叫 toFixed
正确,相同的功能,但该答案的结果具有误导性,我只是通过表达圆形功能来纠正它。
问题指出:“......在适用的情况下四舍五入”。您的答案不涉及四舍五入。
P
PirateApp

四舍五入到 N 位的更通用的解决方案

function roundN(num,n){
  return parseFloat(Math.round(num * Math.pow(10, n)) /Math.pow(10,n)).toFixed(n);
}


console.log(roundN(1,2))
console.log(roundN(1.34,2))
console.log(roundN(1.35,2))
console.log(roundN(1.344,2))
console.log(roundN(1.345,2))
console.log(roundN(1.344,3))
console.log(roundN(1.345,3))
console.log(roundN(1.3444,3))
console.log(roundN(1.3455,3))

Output

1.00
1.34
1.35
1.34
1.35
1.344
1.345
1.344
1.346

此 alswer 失败,某些数字接近 0,roundN(-3.4028230607370965e+38,2) 返回 "-3.4028230607370965e+38" 而不是预期的 0.00
有趣的@Ferrybig 我会测试你提到的数字并想一个解决方法,谢谢你的测试
请注意,前面提到的数字不应该显示为零,而是一个巨大的数字,这只是我大脑中的一个错误。但它仍然不起作用,因为它仍然不显示 2 位小数
m
mplungjan

https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/NumberFormat

变量编号 = 123456.789; console.log(new Intl.NumberFormat('en-IN', { maximumFractionDigits: 2 }).format(number));


S
Sam Sehnert

如果您已经在使用 jQuery,则可以考虑使用 jQuery Number Format 插件。

该插件可以将格式化的数字作为字符串返回,您可以设置小数和千位分隔符,您可以选择显示的小数位数。

$.number( 123, 2 ); // Returns '123.00'

您还可以获得jQuery Number Format from GitHub


使用“只是为了具有固定长度的小数部分”的插件是矫枉过正的。
@Lashae,当然,如果这就是你想做的一切。我发布了这个,以防 OP 或其他任何人也想要插件提供的额外功能。
如果问题的海报当然添加了jQuery标签;)
m
mplungjan

你没有给我们全貌。

当我将 javascript:alert(parseFloat(1).toFixed(2)) 粘贴到地址栏中时,它会在我的浏览器中显示 1.00。但是,如果您之后对其进行操作,它将恢复。

alert(parseFloat(1).toFixed(2)) var num = 2 document.getElementById('spanId').innerHTML = (parseFloat(num).toFixed(2) - 1)

shows 1 and not 1.00

适用于 FF 50、Chrome 49 和 IE 8
K
KooiInc

你是这个意思吗?

[edit 20200530] 答案 @razu provided 是最好的恕我直言。所以这里有一个稍微重构的版本。

片段代码仍然不会为 showAsFloat(2.3346) 之类的东西返回正确的值(结果 2.33,但应该是 2.34)。所以,see also

const showAsFloat = (input, decimals = 2, asString = false) => { if (input === null || input.constructor === Boolean || isNaN(+input)) { return input; } const 转换 = +( `${Math.round( parseFloat( `${input}e${decimals}` ) )}e-${decimals}` );返回字符串? convert.toFixed(decimals) : 转换 }; document.querySelector('#result').textContent = ['command |结果', ' - - - - - - - - - - - - - - - - - - - - - - - -', 'showAsFloat(1); | ' + showAsFloat(1), 'showAsFloat(1.314); | ' + showAsFloat(1.314), 'showAsFloat(\'notanumber\') | ' + showAsFloat('notanumber'), 'showAsFloat(\'23.44567\', 3) | ' + showAsFloat('23.44567', 3), 'showAsFloat(2456198, 5, true)| ' + showAsFloat('24568', 5, true), 'showAsFloat(2456198, 5) | ' + showAsFloat('24568', 5), 'showAsFloat(0, 2, true); | ' + showAsFloat(0, 2, true), 'showAsFloat(1.345); | ' + showAsFloat(1.345), 'showAsFloat(0.005); | ' + showAsFloat(0.005), 'showAsFloat(null); | ' + showAsFloat(null), ].join('\n');


                			                   			


请注意,此解决方案在某些情况下将无法正确舍入:1.005 出现在 1.00 中,而 1.345 出现在 1.34 中。
这就是为什么@razu 的答案应该被接受的原因......
m
mplungjan

你在找地板吗?

变量数 = 1.42482;变量 num2 = 1; var fnum = Math.floor(num).toFixed(2); var fnum2 = Math.floor(num2).toFixed(2); console.log(fnum + " 和 " + fnum2); //两个值都是1.00


我认为他不想四舍五入到最接近的整数。
是的,从描述中我不确定,但我只是把它扔在那里以防万一
B
Behnam Mohammadi

将数字转换为字符串,只保留两位小数:

var num = 5.56789;
var n = num.toFixed(2);

n 的结果将是:

5.57

d
dota2pro

刚刚遇到这个最长的线程,下面是我的解决方案:

parseFloat(Math.round((parseFloat(num * 100)).toFixed(2)) / 100 ).toFixed(2)

让我知道是否有人可以戳一个洞


A
ArNo
function currencyFormat (num) {
    return "$" + num.toFixed(2).replace(/(\d)(?=(\d{3})+(?!\d))/g, "$1,")
}

console.info(currencyFormat(2665));   // $2,665.00
console.info(currencyFormat(102665)); // $102,665.00

M
Minas Mina

这里还有一个可以格式化为任意小数位的通用函数:

function numberFormat(val, decimalPlaces) {

    var multiplier = Math.pow(10, decimalPlaces);
    return (Math.round(val * multiplier) / multiplier).toFixed(decimalPlaces);
}

R
RobG

在需要特定格式的地方,您应该编写自己的例程或使用满足您需要的库函数。基本的 ECMAScript 功能通常不足以显示格式化数字。

此处是对舍入和格式的详尽解释:http://www.merlyn.demon.co.uk/js-round.htm#RiJ

作为一般规则,舍入和格式化只应作为输出前的最后一步执行。提前这样做可能会引入意外的大错误并破坏格式。


有时我会因为自己的选择而摇头,以至于最近如此深入地参与到整个 JS/Ecma 平台中。 :( “在需要特定格式的情况下,您应该编写自己的例程或使用库函数来满足您的需要。基本的 ECMAScript 功能通常不足以显示格式化的数字。”多么愚蠢的声明 - 不是你做的,但因为这个事实存在。只是伤心。开始吧,Javascript!:)
R
Ropali Munshi

这是仅使用下限进行舍入的另一种解决方案,这意味着确保计算的金额不会大于原始金额(有时交易需要):

Math.floor(num* 100 )/100;

L
Leonardo Filipe

function number_format(string,decimals=2,decimal=',',thousands='.',pre='R$',pos='Reais'){ var numbers = string.toString().match(/\d+/ g).join([]); numbers = numbers.padStart(decimals+1, "0"); var splitNumbers = numbers.split("").reverse(); var 掩码 = ''; splitNumbers.forEach(function(d,i){ if (i == decimals) { mask = decimal + mask; } if (i>(decimals+1) && ((i-2)%(decimals+1))= =0) { 掩码 = 千 + 掩码; } 掩码 = d + 掩码; });返回前+掩码+位置; } var element = document.getElementById("format"); var money= number_format("10987654321",2,',','.'); element.innerHTML = 钱; #format{ 显示:内联块;填充:10px;边框:1px 实心#ddd;背景:#f5f5f5; }

测试123456789


N
Nayana_Das

试试下面的代码:

function numberWithCommas(number) { 

   var newval = parseFloat(Math.round(number * 100) / 100).toFixed(2);

   return newval.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}

A
Allan Pereira
var quantity = 12;

var import1 = 12.55;

var total = quantity * import1;

var answer = parseFloat(total).toFixed(2);

document.write(answer);

v
vitek

在进行 toFixed() 调用之前,我必须在 parseFloat() 和 Number() 转换之间做出决定。这是捕获用户输入后数字格式的示例。

HTML:

<input type="number" class="dec-number" min="0" step="0.01" />

事件处理程序:

$('.dec-number').on('change', function () {
     const value = $(this).val();
     $(this).val(value.toFixed(2));
});

上面的代码会导致 TypeError 异常。请注意,虽然 html 输入类型是“数字”,但用户输入实际上是“字符串”数据类型。但是,toFixed() 函数只能在数字对象上调用。

我的最终代码如下所示:

$('.dec-number').on('change', function () {
     const value = Number($(this).val());
     $(this).val(value.toFixed(2));
});

我喜欢使用 Number() 与 parseFloat() 进行转换的原因是因为我不必对空输入字符串或 NaN 值执行额外的验证。 Number() 函数会自动处理一个空字符串并将其转换为零。


k
ksav

var num1 = "0.1"; document.getElementById('num1').innerHTML = (Math.round(num1 * 100) / 100).toFixed(2); var num2 = "1.341"; document.getElementById('num2').innerHTML = (Math.round(num2 * 100) / 100).toFixed(2); var num3 = "1.345"; document.getElementById('num3').innerHTML = (Math.round(num3 * 100) / 100).toFixed(2);跨度{边框:1px实心#000;边距:5px;填充:5px; }


这段代码足以满足您的要求parseFloat(num.toFixed(2))
K
Kamil Kiełczewski

RegExp - 替代方法

在输入时你有字符串(因为你使用解析)所以我们可以通过只使用字符串操作和整数计算来获得结果

让 toFix2 = (n) => n.replace(/(-?)(\d+)\.(\d\d)(\d+)/, (_,s,i,d,r)=> { 让k= (+r[0]>=5)+ +d - (r==5 && s=='-'); return s + (+i+(k>99)) + "." + ((k >99)?"00":(k>9?k:"0"+k)); }) // 测试 console.log(toFix2("1")); console.log(toFix2("1.341")); console.log(toFix2("1.345")); console.log(toFix2("1.005"));

解释

是符号,i 是整数部分,d 是点后的前两位数字,r 是其他数字(我们使用 r[0] 值来计算舍入)

k 包含关于最后两位数字的信息(表示为整数)

如果 r[0] >=5,那么我们将 1 添加到 d - 但是如果我们有负数 (s=='-') 并且 r 正好等于 5,那么在这种情况下我们减去 1(出于兼容性原因- 以同样的方式 Math.round 适用于负数,例如 Math.round(-1.5)==-1)

之后,如果最后两位数 k 大于 99,那么我们将整数部分 i 加 1


Y
Yuichi

我真的很喜欢:

var num = 12.749;
parseFloat((Math.round(num * 100) / 100).toFixed(2)); // 123.75

用 2 个小数点对数字进行四舍五入,然后确保使用 parseFloat() 对其进行解析以返回数字,而不是字符串,除非您不在乎它是字符串还是数字。


我想如果目的是以 2 位小数精度显示,解析浮点数会搞砸。例如parseFloat("1.00") // 1
b
bortunac

用精度方法扩展数学对象

Object.defineProperty(Math, 'precision',{ value: function (value,precision,type){ var v = parseFloat(value), p = Math.max(precision,0)||0, t = type||'回合'; 返回 (Math[t](v*Math.pow(10,p))/Math.pow(10,p)).toFixed(p); } }); console.log( Math.precision(3.1,3), // 圆 3 位 Math.precision(0.12345,2,'ceil'), // ceil 2 位 Math.precision(1.1) // 整数部分 )


l
lefrost

您可以使用 numeral.js

numeral(1.341).format('0.00') // 1.34
numeral(1.345).format('0.00') // 1.35

n
nageen nayak
<script src="https://code.jquery.com/jquery-3.6.0.js" integrity="sha256-H+K7U5CnXl1h5ywQfKtSj8PCmoN9aaq30gDh27Xc0jk=" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.mask/1.14.16/jquery.mask.min.js" integrity="sha512-pHVGpX7F/27yZ0ISY+VVjyULApbDlD0/X0rgGbTqCE7WFW5MezNTWG/dnhtbBuICzsd0WQPgpE4REBLv+UqChw==" crossorigin="anonymous"></script>


<input type="text" class = 'item_price' name="price" min="1.00" placeholder="Enter Price" value="{{ old('price') }}" step="">

<script> 
$(document).ready(function() {
    $('.item_price').mask('00000.00', { reverse: true });
});
</script>

您不需要包含两个巨大的、不必要的仅浏览器库、响应 DOM 事件和操作 DOM 来格式化数字。在发布之前,您应该通读其他一些答案。