我是否错过了一个标准API调用,该调用从一个数字中移除尾随的不重要的零?
var x = 1.234000; // to become 1.234
var y = 1.234001; // stays 1.234001
Number.toFixed()和Number.toPrecision()不是我想要的。
我是否错过了一个标准API调用,该调用从一个数字中移除尾随的不重要的零?
var x = 1.234000; // to become 1.234
var y = 1.234001; // stays 1.234001
Number.toFixed()和Number.toPrecision()不是我想要的。
当前回答
如果由于任何原因(比如涉及到金钱浮动)不能使用float,并且已经从表示正确数字的字符串开始,您可以发现这个解决方案很方便。它将表示数字的字符串转换为表示数字的字符串,后面不带零。
function removeTrailingZeroes( strAmount ) {
// remove all trailing zeroes in the decimal part
var strDecSepCd = '.'; // decimal separator
var iDSPosition = strAmount.indexOf( strDecSepCd ); // decimal separator positions
if ( iDSPosition !== -1 ) {
var strDecPart = strAmount.substr( iDSPosition ); // including the decimal separator
var i = strDecPart.length - 1;
for ( ; i >= 0 ; i-- ) {
if ( strDecPart.charAt(i) !== '0') {
break;
}
}
if ( i=== 0 ) {
return strAmount.substring(0, iDSPosition);
} else {
// return INTPART and DS + DECPART including the rightmost significant number
return strAmount.substring(0, iDSPosition) + strDecPart.substring(0,i + 1);
}
}
return strAmount;
}
其他回答
当Django在文本字段中显示十进制类型的值时,我也需要解决这个问题。例如,当'1'是值时。它会显示“1.00000000”。如果'1.23'是值,它将显示'1.23000000'(在'decimal_places'设置为8的情况下)
使用parseFloat对我来说不是一个选项,因为它可能不会返回完全相同的值。toFixed不是一个选项,因为我不想四舍五入任何东西,所以我创建了一个函数:
function removeTrailingZeros(value) {
value = value.toString();
# if not containing a dot, we do not need to do anything
if (value.indexOf('.') === -1) {
return value;
}
# as long as the last character is a 0 or a dot, remove it
while((value.slice(-1) === '0' || value.slice(-1) === '.') && value.indexOf('.') !== -1) {
value = value.substr(0, value.length - 1);
}
return value;
}
如果你使用toFixed(n)其中n > 0,一个更简单和稳定(没有更多的浮点运算)的解决方案可以是:
(+n).toFixed(2).replace(/(\.0+|0+)$/, '')
// 0 => 0
// 0.1234 => 0.12
// 0.1001 => 0.1
// 1 => 1
// 1.1234 => 1.12
// 1.1001 => 1.1
// 100 => 100
// 100.1234 => 100.12
// 100.1001 => 100.1
PS:如果你使用toFixed(0),那么不需要更换。
我首先使用了matti-lyra和gary的答案的组合:
r=(+n).toFixed(4).replace(/\.0+$/,'')
结果:
1234870.98762341:“1234870.9876” 1230009100:“1230009100” 0.0012234:“0.0012” 0.1200234:“0.12” 0.000001231:“0” 0.10001:“0.1000” "asdf": "NaN"(所以没有运行时错误)
有点问题的情况是0.10001。我最终使用了这个更长的版本:
r = (+n).toFixed(4);
if (r.match(/\./)) {
r = r.replace(/\.?0+$/, '');
}
1234870.98762341:“1234870.9876” 1230009100:“1230009100” 0.0012234:“0.0012” 0.1200234:“0.12” 0.000001231:“0” 0.10001:“0.1” "asdf": "NaN"(所以没有运行时错误)
更新:这是加里的新版本(见评论):
r=(+n).toFixed(4).replace(/([0-9]+(\.[0-9]+[1-9])?)(\.?0+$)/,'$1')
这将得到与上面相同的结果。
在阅读了所有的答案和评论后,我得出了这样的结论:
function isFloat(n) {
let number = (Number(n) === n && n % 1 !== 0) ? eval(parseFloat(n)) : n;
return number;
}
我知道使用eval在某种程度上是有害的,但这帮助了我很多。
So:
isFloat(1.234000); // = 1.234;
isFloat(1.234001); // = 1.234001
isFloat(1.2340010000); // = 1.234001
如果你想限制小数点后的位置,可以使用toFixed()。
let number = (Number(n) === n && n % 1 !== 0) ? eval(parseFloat(n).toFixed(3)) : n;
就是这样。
对于非常小的数,这些解都不适用。http://numeraljs.com/为我解决了这个问题。
parseFloat(0.00000001.toFixed(8));
// 1e-8
numeral(0.00000001).format('0[.][00000000]');
// "0.00000001"