在 Javascript 中将 double 转换为 int 而不进行舍入

在 C # 中,下面的代码返回2:

double d = 2.9;
int i = (int)d;
Debug.WriteLine(i);

然而,在 Javascript 中,将“ double”转换为“ int”的唯一方法是使用 Math.round/floor/toFix 等。在 Javascript 中有没有一种不用舍入就可以转换为 int 的方法?我知道 Number ()对性能的影响,所以如果可能的话,我宁愿避免将其转换为字符串。

191931 次浏览

只要使用 parseInt(),并确保包括基数,这样你就可以得到可预测的结果:

parseInt(d, 10);

使用 parseInt()

var num = 2.9
console.log(parseInt(num, 10)); // 2

也可以使用 |

var num = 2.9
console.log(num | 0); // 2

在 Javascript 中没有 int这种东西。所有的 Numbers实际上都是后台的两倍,所以你不能像 C 或 C # 那样依赖类型系统为你发出舍入顺序。

您不需要担心精度问题(因为双精度正确地表示任何直到2 ^ 53的整数) ,但是如果您想四舍五入到最接近的整数,那么您实际上必须使用 Math.floor (或其他等效技巧)。


* 大多数 JS 引擎在可能的情况下使用本机 int,但是所有的 JS 数字仍然必须具有双重语义。

我发现“ parseInt”建议非常有趣,因为“ parseInt”是在 绳子上设计的。这就是为什么它的名字里有“解析”这个词。

完全避免函数调用的一个技巧是

var truncated = ~~number;

“ ~”一元运算符的双重应用程序将使您得到一个双精度值的截断版本。然而,这个值被限制在32位精度,就像所有其他的 JavaScript 操作一样,这些操作隐含地将数字视为整数(比如数组索引和位运算符)。

编辑 & mash; 在稍后的更新中,~~技巧的另一种替代方法是按位-OR 值为零:

var truncated = number|0;

类似于 C # 转换到 (int),只需使用标准库:

Math.trunc(1.6) // 1
Math.trunc(-1.6) // -1

正如@Quentin 和@Pointy 在他们的评论中指出的那样,使用 parseInt()不是一个好主意,因为它的设计目的是将字符串转换为整数。当您向它传递一个十进制数时,它首先将数字转换为一个字符串,然后将其强制转换为一个整数。我建议你使用 Math.trunc()Math.floor()~~num~~vnum | 0num << 0,或 num >> 0根据你的需要。 这个性能测试 显示了 parseInt()Math.floor()性能的差异。 此外,这篇文章解释了提出的方法之间的区别。

完全避免函数调用的截断技巧是

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也是如此。四舍五入模式的这种变体也称为 银行家的四舍五入

神奇的数字 6755399441055744.0在堆栈溢出后 解释了一种将双精度整数舍入为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))}`);
});

这个怎么样:

if (stringToSearch.IndexOfAny( ".,;:?!".ToCharArray() ) == -1) { ... }

我认为最简单的解决方案是两次使用按位不运算符:

const myDouble = -66.7;
console.log(myDouble); //-66.7
const myInt = ~~myDouble;
console.log(myInt); //-66
const myInt = ~~-myDouble;
console.log(myInt); //66