我想在JavaScript中将float转换为整数 . 实际上,我想知道如何同时执行标准转换:截断和舍入 . 并且有效,而不是通过转换为字符串和解析 .
在你的情况下,当你想要一个字符串到最后(为了插入逗号),你也可以使用Number.toFixed()函数,但是,这将执行舍入 .
var intvalue = Math.floor( floatvalue ); var intvalue = Math.ceil( floatvalue ); var intvalue = Math.round( floatvalue ); // `Math.trunc` was added in ECMAScript 6 var intvalue = Math.trunc( floatvalue );
Math object reference
Positive
value = 5.5 Math.floor(value) // 5 Math.ceil(value) // 6 Math.round(value) // 6 Math.trunc(value) // 5 parseInt(value) // 5 ~~value // 5 value | 0 // 5 value >> 0 // 5 value >>> 0 // 5 value - value % 1 // 5
Negative
value = -5.5 Math.floor(value) // -6 Math.ceil(value) // -5 Math.round(value) // -5 Math.trunc(value) // -5 parseInt(value) // -5 value | 0 // -5 ~~value // -5 value >> 0 // -5 value >>> 0 // 4294967291 value - value % 1 // -5
Positive - Larger numbers
value = Number.MAX_SAFE_INTEGER/10 // 900719925474099.1 Math.floor(value) // 900719925474099 Math.ceil(value) // 900719925474100 Math.round(value) // 900719925474099 Math.trunc(value) // 900719925474099 parseInt(value) // 900719925474099 value | 0 // 858993459 ~~value // 858993459 value >> 0 // 858993459 value >>> 0 // 858993459 value - value % 1 // 900719925474099
Negative - Larger numbers
value = Number.MAX_SAFE_INTEGER/10 * -1 // -900719925474099.1 Math.floor(value) // -900719925474100 Math.ceil(value) // -900719925474099 Math.round(value) // -900719925474099 Math.trunc(value) // -900719925474099 parseInt(value) // -900719925474099 value | 0 // -858993459 ~~value // -858993459 value >> 0 // -858993459 value >>> 0 // 3435973837 value - value % 1 // -900719925474099
您可以使用parseInt方法进行舍入 . 由于0x(十六进制)和0(八进制)前缀选项,请注意用户输入 .
var intValue = parseInt(floatValue, 10);
注意:您不能使用 Math.floor() 替换truncate,因为 Math.floor(-3.1) = -4 而不是 -3 !!
Math.floor()
Math.floor(-3.1) = -4
-3
truncate的正确替换将是:
function truncate(value) { if (value < 0) { return Math.ceil(value); } return Math.floor(value); }
这里有很多建议 . 到目前为止,按位OR似乎是最简单的 . 这是另一个简短的解决方案,它使用模数运算符也可以使用负数 . 它可能比按位OR更容易理解:
intval = floatval - floatval%1;
此方法也适用于高值数字,其中“| 0”,“~~”和“>> 0”都不能正常工作:
> n=4294967295; > n|0 -1 > ~~n -1 > n>>0 -1 > n-n%1 4294967295
截断:
var intvalue = Math.floor(value);
圆形:
var intvalue = Math.round(value);
至 truncate :
// Math.trunc() is part of the ES6 spec Math.trunc( 1.5 ); // returns 1 Math.trunc( -1.5 ); // returns -1 // Math.floor( -1.5 ) would return -2, which is probably not what you wanted
至 round :
Math.round( 1.5 ); // 2 Math.round( 1.49 ); // 1 Math.round( -1.6 ); // -2 Math.round( -1.3 ); // -1
如果您正在使用angularjs,那么简单的解决方案如下所示在HTML模板绑定中
{{val | number:0}}
它会将val转换为整数
通过这个链接docs.angularjs.org/api/ng/filter/number
双bitwise not运算符可用于截断浮点数 . 您提到的其他操作可通过Math.floor,Math.ceil和Math.round获得 .
> ~~2.5 2 > ~~(-1.4) -1
More details courtesy of James Padolsey.
我只是想指出,你想要圆润,而不是截断 . 因为4.999452 * 100四舍五入会给你5分,更有代表性的答案 .
最重要的是,不要忘记banker's rounding,这是一种抵消直接舍入给出的略微正面偏见的方法 - 您的财务应用程序可能需要它 .
Gaussian/banker's rounding in JavaScript
另一种可能的方法 - 使用XOR操作:
console.log(12.3 ^ 0); // 12 console.log("12.3" ^ 0); // 12 console.log(1.2 + 1.3 ^ 0); // 2 console.log(1.2 + 1.3 * 2 ^ 0); // 3 console.log(-1.2 ^ 0); // -1 console.log(-1.2 + 1 ^ 0); // 0 console.log(-1.2 - 1.3 ^ 0); // -2
按位运算的优先级低于数学运算的优先级,它很有用 . 试试https://jsfiddle.net/au51uj3r/
Bit shift by 0 which is equivalent to division by 1
// >> or >>> 2.0 >> 0; // 2 2.0 >>> 0; // 2
按位或运算符可用于截断浮点数,它适用于正数和负数:
function float2int (value) { return value | 0; }
结果
float2int(3.1) == 3 float2int(-3.1) == -3 float2int(3.9) == 3 float2int(-3.9) == -3
我创建了一个JSPerf test来比较以下两者之间的性能:
Math.floor(val)
val | 0 按位OR
val | 0
~~val 按位NOT
~~val
parseInt(val)
只适用于正数 . 在这种情况下,您可以安全地使用按位运算和 Math.floor 函数 .
Math.floor
但是如果你需要你的代码 work with positives as well as negatives ,那么按位运算是最快的(OR是首选的) . This other JSPerf test比较相同的地方很明显,因为四个附加符号检查 Math is now the slowest .
如评论中所述,BITWISE运算符在有符号的32位整数上运算,因此将转换大数字,例如:
1234567890 | 0 => 1234567890 12345678901 | 0 => -539222987
13 回答
在你的情况下,当你想要一个字符串到最后(为了插入逗号),你也可以使用Number.toFixed()函数,但是,这将执行舍入 .
Math object reference
例子
Positive
Negative
Positive - Larger numbers
Negative - Larger numbers
您可以使用parseInt方法进行舍入 . 由于0x(十六进制)和0(八进制)前缀选项,请注意用户输入 .
注意:您不能使用
Math.floor()
替换truncate,因为Math.floor(-3.1) = -4
而不是-3
!!truncate的正确替换将是:
这里有很多建议 . 到目前为止,按位OR似乎是最简单的 . 这是另一个简短的解决方案,它使用模数运算符也可以使用负数 . 它可能比按位OR更容易理解:
此方法也适用于高值数字,其中“| 0”,“~~”和“>> 0”都不能正常工作:
截断:
圆形:
至 truncate :
至 round :
如果您正在使用angularjs,那么简单的解决方案如下所示在HTML模板绑定中
{{val | number:0}}
它会将val转换为整数
通过这个链接docs.angularjs.org/api/ng/filter/number
双bitwise not运算符可用于截断浮点数 . 您提到的其他操作可通过Math.floor,Math.ceil和Math.round获得 .
More details courtesy of James Padolsey.
我只是想指出,你想要圆润,而不是截断 . 因为4.999452 * 100四舍五入会给你5分,更有代表性的答案 .
最重要的是,不要忘记banker's rounding,这是一种抵消直接舍入给出的略微正面偏见的方法 - 您的财务应用程序可能需要它 .
Gaussian/banker's rounding in JavaScript
另一种可能的方法 - 使用XOR操作:
按位运算的优先级低于数学运算的优先级,它很有用 . 试试https://jsfiddle.net/au51uj3r/
Bit shift by 0 which is equivalent to division by 1
按位OR运算符
按位或运算符可用于截断浮点数,它适用于正数和负数:
结果
性能比较?
我创建了一个JSPerf test来比较以下两者之间的性能:
Math.floor(val)
val | 0
按位OR~~val
按位NOTparseInt(val)
只适用于正数 . 在这种情况下,您可以安全地使用按位运算和
Math.floor
函数 .但是如果你需要你的代码 work with positives as well as negatives ,那么按位运算是最快的(OR是首选的) . This other JSPerf test比较相同的地方很明显,因为四个附加符号检查 Math is now the slowest .
注意
如评论中所述,BITWISE运算符在有符号的32位整数上运算,因此将转换大数字,例如: