在Javascript中将双精度型转换为整型,不需要舍入
Converting a double to an int in Javascript without rounding
在c#中,下面的代码返回2:
double d = 2.9;
int i = (int)d;
Debug.WriteLine(i);
然而,在Javascript中,我所知道的将"double"转换为"int"的唯一方法是使用Math。轮/地面/toFixed等等。有没有一种方法转换成int在Javascript没有四舍五入?我知道Number()的性能影响,所以如果可能的话,我宁愿避免将其转换为字符串。
使用parseInt()
var num = 2.9
console.log(parseInt(num, 10)); // 2
您也可以使用|
var num = 2.9
console.log(num | 0); // 2
我发现"parseInt"的建议是相当奇怪的,因为"parseInt"操作字符串设计。这就是为什么它的名字中有"parse"这个词。
完全避免函数调用的技巧是
var truncated = ~~number;
"~"一元操作符的双重应用将为您留下双精度值的截断版本。然而,该值被限制为32位精度,因为所有其他JavaScript操作都隐含地将数字视为整数(如数组索引和按位操作符)。
编辑本;在相当长一段时间后的更新中,~~
技巧的另一种替代方法是将值与零按位或:
var truncated = number|0;
类似于c#转换为(int)
,只是使用标准库:
Math.trunc(1.6) // 1
Math.trunc(-1.6) // -1
只使用parseInt()
,并确保包含基数,以便您得到可预测的结果:
parseInt(d, 10);
在Javascript中没有int
这样的东西。所有的Numbers
实际上都是在后台的double,所以你不能像在C或c#中那样依赖类型系统为你发出舍入命令。
你不需要担心精度问题(因为double正确地表示2^53以内的任何整数),但你真的要使用Math。如果你想四舍五入到最接近的整数
*大多数JS引擎在可能的情况下使用原生整型,但所有JS数字仍然必须具有双语义
截断完全避免函数调用的技巧是
var number = 2.9
var truncated = number - number % 1;
console.log(truncated); // 2
要将浮点数四舍五入到最接近的整数,使用addition/subtraction
技巧。这适用于绝对值<2 ^ 51.
var number = 2.9
var rounded = number + 6755399441055744.0 - 6755399441055744.0; // (2^52 + 2^51)
console.log(rounded); // 3
注意:
使用"四舍五入"将中间值四舍五入到最接近的偶数;作为决胜局规则。例如,+23.5变成+24,+24.5也变成+24。这种四舍五入模式的变体也称为银行家四舍五入。
幻数6755399441055744.0
在stackoverflow post中有解释;解释了一种将双精度浮点数舍入为32位整型的快速方法;
// Round to whole integers using arithmetic operators
let trunc = (v) => v - v % 1;
let ceil = (v) => trunc(v % 1 > 0 ? v + 1 : v);
let floor = (v) => trunc(v % 1 < 0 ? v - 1 : v);
let round = (v) => trunc(v < 0 ? v - 0.5 : v + 0.5);
let roundHalfEven = (v) => v + 6755399441055744.0 - 6755399441055744.0; // (2^52 + 2^51)
console.log("number floor ceil round trunc");
var array = [1.5, 1.4, 1.0, -1.0, -1.4, -1.5];
array.forEach(x => {
let f = x => (x).toString().padStart(6," ");
console.log(`${f(x)} ${f(floor(x))} ${f(ceil(x))} ${f(round(x))} ${f(trunc(x))}`);
});
正如@Quentin和@Pointy在他们的评论中指出的那样,使用parseInt()
不是一个好主意,因为它被设计为将字符串转换为整数。当您向它传递一个十进制数字时,它首先将该数字转换为字符串,然后将其强制转换为整数。我建议您根据需要使用Math.trunc()
, Math.floor()
, ~~num
, ~~v
, num | 0
, num << 0
或num >> 0
。这个性能测试演示了parseInt()
和Math.floor()
性能的差异。此外,这篇文章还解释了所提出的方法之间的区别。
我认为最简单的解决方案是使用两次按位not操作符:
const myDouble = -66.7;
console.log(myDouble); //-66.7
const myInt = ~~myDouble;
console.log(myInt); //-66
const myInt = ~~-myDouble;
console.log(myInt); //66
这个呢:
if (stringToSearch.IndexOfAny( ".,;:?!".ToCharArray() ) == -1) { ... }
- 如何在不需要单击按钮的情况下获取选项的值
- Javascript不需要的关闭行为
- 删除客户端浏览器上不需要的内容
- 不允许在字段中输入不需要的字符
- 不需要的JSON响应
- 如何使图像适合TD,而不需要包装在不同的屏幕分辨率上
- 使用一个Javascript函数提交多个表单可以在FF中工作,而不需要其他浏览器
- jQuery自动完成显示不需要的动态html标记
- 在Knockout js中创建一个包含多行的表,而不需要推送
- AngularJs正在解码HTML字符(不需要)
- jQuery regex从文本链接-添加不需要的域到链接
- 防止从浏览器到应用商店的不需要的重定向
- 外部解析RSS提要,不需要像谷歌和服务器端那样的任何库
- 不需要的异步事件调度
- 是否有任何不需要后端的验证码角度指令
- Ajax 请求给出不需要的响应
- 尝试将无符号长整型的 ARGB 数据绘制到 HTML 画布
- 在Javascript中将双精度型转换为整型,不需要舍入
- 基于整型而不是字符串以升序排序数组
- 正则表达式问题-替换浮点数,而不是整型