javascript 解决默认取整的坑(目前已知的最佳解决方案)
javascript 解决默认取整的坑(目前已知的最佳解决方案)
复现该问题
js在数字操作时总会取更高精度的结果,例如1234/10
结果就是123.4
,但是在c或者java中整数除以10的结果还是整数,小数部分被舍去,不仅如此 *
,%
等运算符也会出现这种结果,但我们有时候更希望舍去取整
使用Math标准库
Math标准库提供了Math.floor():向下取整Math.ceil():向上取整Math.round():四舍五入
这三种取整方法,效率也不错,但是在进行一些操作时,总感觉别扭,而且效率会偏低,查看了v8中Math部分的源码后发现需要进行非常多的操作后才能得到结果
//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操作时会进行很多操作,复杂度较高,有很多层递归才能获得结果
使用按位运算符
按位运算符中的~
是将数字按位取反,位运算是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;
};
以上两个函数获取的结果完全一样
javascript 解决默认取整的坑(目前已知的最佳解决方案)的更多相关文章
- 你可能不知道的 JavaScript 中数字取整
网上方法很多,标题党一下,勿拍 ^_^!实际开发过程中经常遇到数字取整问题,所以这篇文章收集了一些方法,以备查询. 常用的直接取整方法 直接取整就是舍去小数部分. 1.parseInt() parse ...
- JavaScript 的 parseInt 取整
http://www.neoease.com/javascript-get-integer-via-parseint/ JavaScript 是弱类型语言, 为了保证数值的有效性, 在处理数值的时候, ...
- javaScript中小数取整,四种方法的比较
1.parseInt:只取整数位例如:parseInt(3.7) 取整结果为:3parseInt(-1.1) 取整结果为:-1 2.Math.floor :向下去整,取大的整数例如:Math.floo ...
- javascript除法如何取整
Math.round(x) 四舍五入,如Math.round(0.60),结果为1:Math.round(0.49),结果为0: Math.floor(x) 向下舍入,如Math.floor(0.60 ...
- js 除法 取整
js 除法 取整 1.丢弃小数部分,保留整数部分 js:parseInt(7/2) 2.向上取整,有小数就整数部分加1 js: Math.ceil(7/2) 3,四舍五入. js: Math.roun ...
- php浮点数计算比较及取整不准确解决方法
原文:php浮点数计算比较及取整不准确解决方法 php有意思的现象,应该是很多编程语言都会有这样的现象.这个是因为计算机的本身对浮点数识别的问题..... $f = 0.58; var_dump(in ...
- JavaScript四种数值取整方法
一.Math.trunc() 1.定义 Math.trunc()方法去除数字的小数部分,保留整数部分. 2.语法 Math.trunc(value) 3.示例 console.log(Math.tru ...
- JavaScript随机数组(数组、随机、取整、取值的过程)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&q ...
- javascript中按位操作的应用,如何快速取整 判断字符串是否是包含某字符串
最近在看最基础的<javascript高级程序设计>看的灰常慢,看到按位运算这里,突然反思,这种鬼操作到底有什么实际的应用呢? 按位运算符有6个 & 按位与:a & b | ...
随机推荐
- HeidiSQL、Navicat、mysql命令和source命令导入sql脚本的速度比较
一.四种导入方式的比较 1.heidisql客户端是一条一条插入的,速度最慢,而且很脆弱比较容易崩溃: 2.mysql命令导入380万记录用时1小时13分(属于前台运行的命令,ctrl+c就可以结束) ...
- drf框架中所有视图及用法
0909自我总结 drf框架中所有视图及用法 一.drf框架中的所有视图类 from django.views import View from rest_framework import views ...
- 像智能手机一样管理云端应用:阿里云联合微软全球首发开放应用模型(OAM)
2019 年 10 月 17 日上午 9 点 15 分,阿里巴巴合伙人.阿里云智能基础产品事业部总经理蒋江伟在 QCon 上海<基于云架构的研发模式演进>主题演讲中,正式宣布: " ...
- 服务器端 SOCKET 编程
使用 Socket 的程序在使用 Socket 之前必须调用 WSAStartup() 函数, 此函数在应用程序中用来初始化 Windows Socket DLL, 只有此函数调用成功后,应用程序才可 ...
- 实验吧之【因缺思汀的绕过】(group by with rollup的注入利用)
打开页面,查看源代码,发现存在source.txt(http://ctf5.shiyanbar.com/web/pcat/source.txt),如下: <?php error_reportin ...
- Ubuntu 16.04 集成安装Apache+PHP+Kerberos+LDAP+phpLDAPadmin
一.安装Apache 1.1.安装Apache apt-get update apt-get install apache2 过程如下: root@duke01:~# apt-get update命中 ...
- 关于Linux中的 localhost 默认地址简单介绍
大家都知道localhost指的是本机的IP地址:127.0.0.1 用于回路测试,那能不能修改localhost呢,答案肯定是可以的 打开终端--->输入: vim /etc/host 然后 ...
- 百万年薪python之路 -- 基本数据类型
整数 -- 数字(int) 用于比较和运算 32位 2 ** 31 ~ 2 ** 31-1 64位 -2 ** 63 ~ 2 ** 63- 1 + - * / // ** % python2 整型 ...
- $.ajax.html
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <link rel= ...
- vue 踩坑--项目名称不能与插件名称一样
今天webpack搭建,命令行一直报错 百度说是项目名称为:vue npm 拒绝安装 后来才发现是 package.json的name名称也设成了vue 所以 修改一下就可以了.