当 .toFixed(2) 在小数点后给出零时,如何将浮点数格式化为整数?
How to format a float as integer when .toFixed(2) gives zeros after the decimal point?
我想知道实现以下目标的最短且最安全的方法是什么:
假设我有一个值为 1.200123
的浮点变量。在我们的可视化中,我想用两位小数来显示这个值,所以我现在使用 myFloat.toFixed(2);
,这给了我 1.20
.
没关系。但是,如果结果输出的小数位只有零怎么办?例如值 1.000043
变为 1.00
.
对于上述情况:如何省略小数点和零并仅将 1
作为输出,最好不解析和操作来自 .toFixed(2)
的字符串?
...preferrably without parsing and manipulating the string that comes out of .toFixed(2)?
嗯,你可以用数字来做,尽管我担心在数字逻辑和 toFixed
's logic 之间得到完美匹配,给定 [=13] 的定义=] 包括像这样的短语:
Let n be an integer for which the exact mathematical value of n ÷ 10f - x is as close to zero as possible. If there are two such n, pick the larger n.
所以我可能只是更新字符串,这不是很多工作:
function formatNumber(num) {
return num.toFixed(2).replace(/\.00$/, "");
}
function test(num) {
console.log(num, "=>", formatNumber(num));
}
test(1.01);
test(1.43);
test(23.7);
test(1.200123);
test(1.000043);
test(1.007);
test(1.0007);
但这里有一个近似数值方法,它至少与上述测试用例的结果相匹配:
function formatNumber(num) {
var check = Math.round(num * 100) / 100;
var rounded = Math.round(check);
if (rounded == check) {
return String(rounded);
}
return num.toFixed(2);
}
function formatNumberViaToFixed(num) {
return num.toFixed(2).replace(/\.00$/, "");
}
function test(num) {
var formatted = formatNumber(num);
var viaToFixed = formatNumberViaToFixed(num);
if (formatted == viaToFixed) {
console.log(num, "=>", formatted);
} else {
console.log(num, "=>", formatted, "ERROR: Should be", viaToFixed);
}
}
test(1.01);
test(1.43);
test(23.7);
test(1.200123);
test(1.000043);
test(1.007);
test(1.0007);
.as-console-wrapper {
max-height: 100% !important;
}
您可以使用 Number(myFloat.toFixed(2))
.
虽然这会生成类型为 number
而不是 string
的值,但您可以在字符串表达式中使用它(隐式调用其 .toString()
方法),或调用 .toString()
显式地生成您想要的字符串格式。
由于 Number.toString()
没有特殊格式,将字符串转换为数字然后返回会从 .toFixed()
生成的舍入值中删除尾随零。
此方法的缺点是它将 1.10
转换为 "1.1"
而不是 "1.10"
,这可能是也可能不是您想要的可视化效果。
我会在 Number
原型中创建这个有条件的 toFixed
方法,它最终会调用 this.toFixed
方法,这样你就可以保持原来的行为,只调整传递给它的数字数量 - 使用 Math.pow
和 Math.trunc
.
可以轻松完成
Object.defineProperty(Number.prototype, 'toConditionalFixed', {
enumerable: false,
writable: false,
configurable: false,
value: function(digits) {
let comp = Math.pow(10, digits);
return this.toFixed(Math.trunc(this * comp) % comp === 0 ? 0 : digits);
}
});
console.log(
(1.200123).toConditionalFixed(2),
'|',
(1.200123).toConditionalFixed(3),
'|',
(1.200123).toConditionalFixed(4),
'|',
(1.000043).toConditionalFixed(2),
'|',
(1.000043).toConditionalFixed(3),
'|',
(1.000043).toConditionalFixed(4),
'|',
(1.000043).toConditionalFixed(5)
);
编辑
为了完整起见,Number.prototype
中与 RegExp 一起使用的相同方法:
Object.defineProperty(Number.prototype, 'toConditionalFixed', {
enumerable: false,
writable: false,
configurable: false,
value: function(digits) {
let re = new RegExp("\." + "0".repeat(digits) + "$");
return this.toFixed(digits).replace(re, "");
}
});
console.log(
(1.200123).toConditionalFixed(2),
'|',
(1.200123).toConditionalFixed(3),
'|',
(1.200123).toConditionalFixed(4),
'|',
(1.000043).toConditionalFixed(2),
'|',
(1.000043).toConditionalFixed(3),
'|',
(1.000043).toConditionalFixed(4),
'|',
(1.000043).toConditionalFixed(5)
);
我想知道实现以下目标的最短且最安全的方法是什么:
假设我有一个值为 1.200123
的浮点变量。在我们的可视化中,我想用两位小数来显示这个值,所以我现在使用 myFloat.toFixed(2);
,这给了我 1.20
.
没关系。但是,如果结果输出的小数位只有零怎么办?例如值 1.000043
变为 1.00
.
对于上述情况:如何省略小数点和零并仅将 1
作为输出,最好不解析和操作来自 .toFixed(2)
的字符串?
...preferrably without parsing and manipulating the string that comes out of .toFixed(2)?
嗯,你可以用数字来做,尽管我担心在数字逻辑和 toFixed
's logic 之间得到完美匹配,给定 [=13] 的定义=] 包括像这样的短语:
Let n be an integer for which the exact mathematical value of n ÷ 10f - x is as close to zero as possible. If there are two such n, pick the larger n.
所以我可能只是更新字符串,这不是很多工作:
function formatNumber(num) {
return num.toFixed(2).replace(/\.00$/, "");
}
function test(num) {
console.log(num, "=>", formatNumber(num));
}
test(1.01);
test(1.43);
test(23.7);
test(1.200123);
test(1.000043);
test(1.007);
test(1.0007);
但这里有一个近似数值方法,它至少与上述测试用例的结果相匹配:
function formatNumber(num) {
var check = Math.round(num * 100) / 100;
var rounded = Math.round(check);
if (rounded == check) {
return String(rounded);
}
return num.toFixed(2);
}
function formatNumberViaToFixed(num) {
return num.toFixed(2).replace(/\.00$/, "");
}
function test(num) {
var formatted = formatNumber(num);
var viaToFixed = formatNumberViaToFixed(num);
if (formatted == viaToFixed) {
console.log(num, "=>", formatted);
} else {
console.log(num, "=>", formatted, "ERROR: Should be", viaToFixed);
}
}
test(1.01);
test(1.43);
test(23.7);
test(1.200123);
test(1.000043);
test(1.007);
test(1.0007);
.as-console-wrapper {
max-height: 100% !important;
}
您可以使用 Number(myFloat.toFixed(2))
.
虽然这会生成类型为 number
而不是 string
的值,但您可以在字符串表达式中使用它(隐式调用其 .toString()
方法),或调用 .toString()
显式地生成您想要的字符串格式。
由于 Number.toString()
没有特殊格式,将字符串转换为数字然后返回会从 .toFixed()
生成的舍入值中删除尾随零。
此方法的缺点是它将 1.10
转换为 "1.1"
而不是 "1.10"
,这可能是也可能不是您想要的可视化效果。
我会在 Number
原型中创建这个有条件的 toFixed
方法,它最终会调用 this.toFixed
方法,这样你就可以保持原来的行为,只调整传递给它的数字数量 - 使用 Math.pow
和 Math.trunc
.
Object.defineProperty(Number.prototype, 'toConditionalFixed', {
enumerable: false,
writable: false,
configurable: false,
value: function(digits) {
let comp = Math.pow(10, digits);
return this.toFixed(Math.trunc(this * comp) % comp === 0 ? 0 : digits);
}
});
console.log(
(1.200123).toConditionalFixed(2),
'|',
(1.200123).toConditionalFixed(3),
'|',
(1.200123).toConditionalFixed(4),
'|',
(1.000043).toConditionalFixed(2),
'|',
(1.000043).toConditionalFixed(3),
'|',
(1.000043).toConditionalFixed(4),
'|',
(1.000043).toConditionalFixed(5)
);
编辑
为了完整起见,Number.prototype
中与 RegExp 一起使用的相同方法:
Object.defineProperty(Number.prototype, 'toConditionalFixed', {
enumerable: false,
writable: false,
configurable: false,
value: function(digits) {
let re = new RegExp("\." + "0".repeat(digits) + "$");
return this.toFixed(digits).replace(re, "");
}
});
console.log(
(1.200123).toConditionalFixed(2),
'|',
(1.200123).toConditionalFixed(3),
'|',
(1.200123).toConditionalFixed(4),
'|',
(1.000043).toConditionalFixed(2),
'|',
(1.000043).toConditionalFixed(3),
'|',
(1.000043).toConditionalFixed(4),
'|',
(1.000043).toConditionalFixed(5)
);