js在數字操做時總會取更高精度的結果,例如1234/10
結果就是123.4
,可是在c或者java中整數除以10的結果仍是整數,小數部分被捨去,不只如此 *
,%
等運算符也會出現這種結果,但咱們有時候更但願捨去取整javascript
Math標準庫提供了Math.floor():向下取整Math.ceil():向上取整Math.round():四捨五入
這三種取整方法,效率也不錯,可是在進行一些操做時,總感受彆扭,並且效率會偏低,查看了v8中Math部分的源碼後發現須要進行很是多的操做後才能獲得結果java
//builtins-math-gen.cc文件中聲明瞭math庫的全部方法 // ES6 #sec-math.floor TF_BUILTIN(MathFloor, MathBuiltinsAssembler) { TNode<Context> context = CAST(Parameter(Descriptor::kContext)); TNode<Object> x = CAST(Parameter(Descriptor::kX)); MathRoundingOperation(context, x, &CodeStubAssembler::Float64Floor); } // code-stub-assembler.cc文件中進行了floor操做 TNode<Float64T> CodeStubAssembler::Float64Floor(SloppyTNode<Float64T> x) { if (IsFloat64RoundDownSupported()) { return Float64RoundDown(x); } TNode<Float64T> one = Float64Constant(1.0); TNode<Float64T> zero = Float64Constant(0.0); TNode<Float64T> two_52 = Float64Constant(4503599627370496.0E0); TNode<Float64T> minus_two_52 = Float64Constant(-4503599627370496.0E0); VARIABLE(var_x, MachineRepresentation::kFloat64, x); Label return_x(this), return_minus_x(this); // Check if {x} is greater than zero. Label if_xgreaterthanzero(this), if_xnotgreaterthanzero(this); Branch(Float64GreaterThan(x, zero), &if_xgreaterthanzero, &if_xnotgreaterthanzero); BIND(&if_xgreaterthanzero); { // Just return {x} unless it's in the range ]0,2^52[. GotoIf(Float64GreaterThanOrEqual(x, two_52), &return_x); // Round positive {x} towards -Infinity. var_x.Bind(Float64Sub(Float64Add(two_52, x), two_52)); GotoIfNot(Float64GreaterThan(var_x.value(), x), &return_x); var_x.Bind(Float64Sub(var_x.value(), one)); Goto(&return_x); } BIND(&if_xnotgreaterthanzero); { // Just return {x} unless it's in the range ]-2^52,0[ GotoIf(Float64LessThanOrEqual(x, minus_two_52), &return_x); GotoIfNot(Float64LessThan(x, zero), &return_x); // Round negated {x} towards -Infinity and return the result negated. TNode<Float64T> minus_x = Float64Neg(x); var_x.Bind(Float64Sub(Float64Add(two_52, minus_x), two_52)); GotoIfNot(Float64LessThan(var_x.value(), minus_x), &return_minus_x); var_x.Bind(Float64Add(var_x.value(), one)); Goto(&return_minus_x); } BIND(&return_minus_x); var_x.Bind(Float64Neg(var_x.value())); Goto(&return_x); BIND(&return_x); return TNode<Float64T>::UncheckedCast(var_x.value()); }
在進行Math.floor操做時會進行不少操做,複雜度較高,有不少層遞歸才能得到結果less
按位運算符中的~
是將數字按位取反,位運算是js中計算較快的操做符,把浮點數兩次按位取反後能夠得到捨去取整的結果即Math.floor(5.6)==~~5.6)
這是目前已知的最快解決方法
示例代碼函數
/** * @param {number} x * @return {number} */ var reverse = function (x) { let ans = 0; while (x !== 0) { ans = ans * 10 + ~~(x % 10); x = ~~(x / 10); } return (ans >= (2 ** 31) || ans <= -(2 ** 31)) ? 0 : ans; }; /** * @param {number} x * @return {number} */ var reverse = function (x) { let ans = 0; while (x !== 0) { ans = ans * 10 + Math.floor(x % 10); x = Math.floor(x / 10); } return (ans >= (2 ** 31) || ans <= -(2 ** 31)) ? 0 : ans; };
以上兩個函數獲取的結果徹底同樣ui