我是否错过了一个标准的API调用,可以从一个数字中删除尾随无效的零?
实施例
var x = 1.234000 // to become 1.234;
var y = 1.234001; // stays 1.234001
Number.toFixed()和Number.toPrecision()并不是我想要的。
答案 0 :(得分:179)
我有一个类似的实例,我想在必要时使用.toFixed()
,但是当它不是时我不想要填充。所以我最终将parseFloat与toFixed一起使用。
toFixed without padding
parseFloat(n.toFixed(4));
另一种做同样事情的选择
This answer may help your decision
Number(n.toFixed(4));
toFixed
会将数字舍入/填充到特定长度,但也会将其转换为字符串。将其转换回数字类型不仅可以使数字更安全地使用算术,还可以自动删除任何尾随0。例如:
var n = "1.234000";
n = parseFloat(n);
// n is 1.234 and in number form
因为即使您定义了一个尾随零的数字,它们也会被删除。
var n = 1.23000;
// n == 1.23;
答案 1 :(得分:109)
如果将它转换为字符串,它将不会显示任何尾随的零,因为它是作为数字而不是字符串创建的,所以它们不会首先存储在变量中。
var n = 1.245000
var noZeroes = n.toString() // "1.245"
答案 2 :(得分:23)
我首先使用了matti-lyra和gary的答案组合:
r=(+n).toFixed(4).replace(/\.0+$/,'')
结果:
有些问题的案例是0.10001。我最终使用了这个更长的版本:
r = (+n).toFixed(4);
if (r.match(/\./)) {
r = r.replace(/\.?0+$/, '');
}
更新:这是Gary的新版本(见评论):
r=(+n).toFixed(4).replace(/([0-9]+(\.[0-9]+[1-9])?)(\.?0+$)/,'$1')
这给出了与上面相同的结果。
答案 3 :(得分:11)
如果需要,toFixed
方法将进行适当的舍入。它还会添加尾随零,这并不总是理想的。
(4.55555).toFixed(2);
//-> "4.56"
(4).toFixed(2);
//-> "4.00"
如果将返回值强制转换为数字,那么将删除那些尾随零。这比进行自己的舍入或截断数学更简单。
+(4.55555).toFixed(2);
//-> 4.56
+(4).toFixed(2);
//-> 4
答案 4 :(得分:6)
当Django在文本字段中显示Decimal类型值时,我也需要解决这个问题。例如。当' 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;
}
答案 5 :(得分:5)
我有基本相同的要求,并发现此功能没有内置机制。
除了修剪尾随零之外,我还需要对用户当前语言环境(即123,456.789)的输出进行舍入和格式化。
我对此的所有工作都已作为prettyFloat.js(MIT许可)包含在GitHub上:https://github.com/dperish/prettyFloat.js
用法示例:
prettyFloat(1.111001, 3) // "1.111"
prettyFloat(1.111001, 4) // "1.111"
prettyFloat(1.1111001, 5) // "1.1111"
prettyFloat(1234.5678, 2) // "1234.57"
prettyFloat(1234.5678, 2, true) // "1,234.57" (en-us)
更新日期 - 2018年8月
所有现代浏览器现在都支持ECMAScript Internationalization API,它提供语言敏感的字符串比较,数字格式以及日期和时间格式。
let formatters = {
default: new Intl.NumberFormat(),
currency: new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD', minimumFractionDigits: 0, maximumFractionDigits: 0 }),
whole: new Intl.NumberFormat('en-US', { style: 'decimal', minimumFractionDigits: 0, maximumFractionDigits: 0 }),
oneDecimal: new Intl.NumberFormat('en-US', { style: 'decimal', minimumFractionDigits: 1, maximumFractionDigits: 1 }),
twoDecimal: new Intl.NumberFormat('en-US', { style: 'decimal', minimumFractionDigits: 2, maximumFractionDigits: 2 })
};
formatters.twoDecimal.format(1234.5678); // result: "1,234.57"
formatters.currency.format(28761232.291); // result: "$28,761,232"
对于旧版浏览器,您可以使用此polyfill:https://cdn.polyfill.io/v2/polyfill.min.js?features=Intl.~locale.en
答案 6 :(得分:5)
正则表达式纯答案
n.replace(/(\.[0-9]*[1-9])0+$|\.0*$/,'$1');
我想知道为什么没人给一个!
答案 7 :(得分:3)
您可以尝试使用此方法来最小化浮点数
var n = 0.0000;
n = parseFloat(n.toString());
//output n = 0;
// n = 3.14000; --> n = 3.14;
答案 8 :(得分:2)
这些解决方案对我来说都不是很有用。 http://numeraljs.com/为我解决了这个问题。
parseFloat(0.00000001.toFixed(8));
// 1e-8
numeral(0.00000001).format('0[.][00000000]');
// "0.00000001"
答案 9 :(得分:2)
如何才能像这样乘以?
var x = 1.234000*1; // becomes 1.234
var y = 1.234001*1; // stays as 1.234001
答案 10 :(得分:2)
如果在n> 0的情况下使用toFixed(n)
,则可以使用以下更简单和稳定的解决方案(不再进行浮点运算):
(+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)
,则不需要replace
。
答案 11 :(得分:1)
如果由于任何原因(例如涉及的资金浮动)而无法使用浮动货币,并且已经从代表正确数字的字符串开始,则可以轻松找到此解决方案。它将代表数字的字符串转换为代表无尾随数字的数字的字符串。
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;
}
答案 12 :(得分:0)
我是这样做的:
parseFloat(number.toString());
这也是解决 TypeScript 错误的好方法。在某些情况下将数字更改为字符串的错误。
答案 13 :(得分:0)
如果我们有一个数字的s
字符串表示形式(例如,可以使用.toFixed(digits)
method of Number(或通过任何其他方式)来获得,则用于删除无关紧要的尾随我们可以使用s
字符串中的零:
s.replace(/(\.0*|(?<=(\..*))0*)$/, '')
/**********************************
* Results for various values of s:
**********************************
*
* "0" => 0
* "0.000" => 0
*
* "10" => 10
* "100" => 100
*
* "0.100" => 0.1
* "0.010" => 0.01
*
* "1.101" => 1.101
* "1.100" => 1.1
* "1.100010" => 1.10001
*
* "100.11" => 100.11
* "100.10" => 100.1
*/
上面在{{1}中使用的正则表达式在下面解释:
replace()
运算符,该运算符表示“ OR”,因此,|
方法将从replace()
中删除两个可能的值种类的子字符串,由s
部分或(\.0*)$
部分匹配。((?<=(\..*))0*)$
部分与一个点符号匹配,后跟所有零,直到(\.0*)$
的末尾。例如,可能是s
(0.0
被匹配并删除),.0
(1.0
被匹配并删除),.0
(0.000
匹配并删除)或任何类似的字符串,其点后的所有零都为零,因此,如果这部分正则表达式匹配,则所有尾随零和点本身都将被删除。.000
部分仅匹配尾随零(它们位于点符号后,且在连续尾随零开始之前位于任意数量的任何符号之后)。例如,这可能是((?<=(\..*))0*)$
(匹配并删除了跟踪0.100
),00
(最后一个0.010
被匹配并删除了,请注意,0
部分没有得益于“正向隐式断言”,即0.01
,它位于正则表达式此部分(?<=(\..*))
的前面),0*
(最后一个1.100010
是匹配并删除),等等。0
或100
等。因此,如果输入没有任何尾随零,则它保持不变。 使用100.11
的更多示例(以下示例中使用字母值“ 1000.1010”,但我们可以采用变量):
.toFixed(digits)
要使用let digits = 0; // Get `digits` from somewhere, for example: user input, some sort of config, etc.
(+"1000.1010").toFixed(digits).replace(/(\.0*|(?<=(\..*))0*)$/, '');
// Result: '1000'
(+"1000.1010").toFixed(digits = 1).replace(/(\.0*|(?<=(\..*))0*)$/, '');
// Result: '1000.1'
(+"1000.1010").toFixed(digits = 2).replace(/(\.0*|(?<=(\..*))0*)$/, '');
// Result: '1000.1'
(+"1000.1010").toFixed(digits = 3).replace(/(\.0*|(?<=(\..*))0*)$/, '');
// Result: '1000.101'
(+"1000.1010").toFixed(digits = 4).replace(/(\.0*|(?<=(\..*))0*)$/, '');
// Result: '1000.101'
(+"1000.1010").toFixed(digits = 5).replace(/(\.0*|(?<=(\..*))0*)$/, '');
// Result: '1000.101'
(+"1000.1010").toFixed(digits = 10).replace(/(\.0*|(?<=(\..*))0*)$/, '');
// Result: '1000.101'
中使用的上述正则表达式,我们可以访问:https://regex101.com/r/owj9fz/1
答案 14 :(得分:0)
我需要删除所有结尾的零,但至少保留2个小数,包括任何零。
我正在使用的数字是.toFixed(6)生成的6个十进制数字字符串。
预期结果:
var numstra = 12345.000010 // should return 12345.00001
var numstrb = 12345.100000 // should return 12345.10
var numstrc = 12345.000000 // should return 12345.00
var numstrd = 12345.123000 // should return 12345.123
解决方案:
var numstr = 12345.100000
while (numstr[numstr.length-1] === "0") {
numstr = numstr.slice(0, -1)
if (numstr[numstr.length-1] !== "0") {break;}
if (numstr[numstr.length-3] === ".") {break;}
}
console.log(numstr) // 12345.10
逻辑:
如果字符串的最后一个字符为零,则运行循环函数。
删除最后一个字符并更新字符串变量。
如果更新的字符串的最后一个字符不为零,则结束循环。
如果将更新后的字符串倒数第二个字符是浮点,则结束循环。
答案 15 :(得分:0)
阅读所有答案和评论后,我得出了以下结论:
If Me.ExpName And Me.ExpAmount <> "" Then
MsgBox "there is data in the fields"
End If
我知道使用function isFloat(n) {
let number = (Number(n) === n && n % 1 !== 0) ? eval(parseFloat(n)) : n;
return number;
}
可能有害,但这对我很有帮助。
所以:
eval
如果要限制小数位数,请使用isFloat(1.234000); // = 1.234;
isFloat(1.234001); // = 1.234001
isFloat(1.2340010000); // = 1.234001
,如其他人指出的那样。
toFixed()
就是这样。
答案 16 :(得分:-1)
只是使用toFixed
function truncateNumber( num, precision ){
let c = Math.pow(10,precision);
return Math.trunc( num*c )/c;
}
console.log( truncateNumber(1234.5678, 4) );
console.log( truncateNumber(1234.56, 4) );
答案 17 :(得分:-1)
这是一个可能的解决方案:
var x = 1.234000 // to become 1.234;
var y = 1.234001; // stays 1.234001
eval(x) --> 1.234
eval(y) --> 1.234001