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 解决默认取整的坑(目前已知的最佳解决方案)的更多相关文章

  1. 你可能不知道的 JavaScript 中数字取整

    网上方法很多,标题党一下,勿拍 ^_^!实际开发过程中经常遇到数字取整问题,所以这篇文章收集了一些方法,以备查询. 常用的直接取整方法 直接取整就是舍去小数部分. 1.parseInt() parse ...

  2. JavaScript 的 parseInt 取整

    http://www.neoease.com/javascript-get-integer-via-parseint/ JavaScript 是弱类型语言, 为了保证数值的有效性, 在处理数值的时候, ...

  3. javaScript中小数取整,四种方法的比较

    1.parseInt:只取整数位例如:parseInt(3.7) 取整结果为:3parseInt(-1.1) 取整结果为:-1 2.Math.floor :向下去整,取大的整数例如:Math.floo ...

  4. javascript除法如何取整

    Math.round(x) 四舍五入,如Math.round(0.60),结果为1:Math.round(0.49),结果为0: Math.floor(x) 向下舍入,如Math.floor(0.60 ...

  5. js 除法 取整

    js 除法 取整 1.丢弃小数部分,保留整数部分 js:parseInt(7/2) 2.向上取整,有小数就整数部分加1 js: Math.ceil(7/2) 3,四舍五入. js: Math.roun ...

  6. php浮点数计算比较及取整不准确解决方法

    原文:php浮点数计算比较及取整不准确解决方法 php有意思的现象,应该是很多编程语言都会有这样的现象.这个是因为计算机的本身对浮点数识别的问题..... $f = 0.58; var_dump(in ...

  7. JavaScript四种数值取整方法

    一.Math.trunc() 1.定义 Math.trunc()方法去除数字的小数部分,保留整数部分. 2.语法 Math.trunc(value) 3.示例 console.log(Math.tru ...

  8. JavaScript随机数组(数组、随机、取整、取值的过程)

      <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&q ...

  9. javascript中按位操作的应用,如何快速取整 判断字符串是否是包含某字符串

    最近在看最基础的<javascript高级程序设计>看的灰常慢,看到按位运算这里,突然反思,这种鬼操作到底有什么实际的应用呢? 按位运算符有6个 & 按位与:a & b | ...

随机推荐

  1. Django中CKEditor富文本编译器的使用

    CKEditor富文本编辑器 1. 安装 pip install django-ckeditor 2. 添加应用 在INSTALLED_APPS中添加 INSTALLED_APPS = [ ... ' ...

  2. drf框架安装配置及其功能概述

    0902自我总结 drf框架安装配置及其功能概述 一.安装 pip3 install djangorestframework 二.配置 # 注册drf app NSTALLED_APPS = [ # ...

  3. [CF467D] Fedor and Essay

    After you had helped Fedor to find friends in the «Call of Soldiers 3» game, he stopped studying com ...

  4. opencv::opencv_createsamples.exe

    opencv_createsamples.exe 用来生成正样本vec的,用来准备训练用的正样本数据和测试数据.他的输出为以 *.vec 为扩展名的文件,该文件以二进制方式存储图像. Usage: o ...

  5. docker实验--redis集群搭建

    背景介绍: 我经常在做一些小项目的时候,采用了Redis来做缓存,但是都是基于单节点的,一旦redis挂了,整个项目就挂了.于是乎,想到了多节点集群的方式来使用,就开始折腾着怎么去搭建这个集群.在网上 ...

  6. WebSocket学习简书

    1.什么是Websocket? WebSocket 是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议. 2.单工,半双工和全双工通信? 在单工通信中,通信的信道是单向的,发送端 ...

  7. spark运行java-jar:Exception in thread "main" java.io.IOException: No FileSystem for scheme: hdfs

    今天碰到的一个 spark问题,困扰好久才解决 首先我的spark集群部署使用的部署包是官方提供的 spark-1.0.2-bin-hadoop2.tgz 部署在hadoop集群上. 在运行java ...

  8. 说说Object类下面有几种方法呢?

    今天说一道基础题型,不过很多人会忽略或者至少说不完整,但是面试时被问到的几率还是很大的. 面试题 Object有几种方法呢? Java语言是一种单继承结构语言,Java中所有的类都有一个共同的祖先.这 ...

  9. Ubuntu18.04 安装PGSQL

    关系数据库管理系统是许多网站和应用程序的关键组成部分.它们提供了一种结构化的方式来存储,组织和访问信息. PostgreSQL或Postgres是一个关系数据库管理系统,提供SQL查询语言的实现.它是 ...

  10. 再谈 APISIX 高性能实践

    2019 年 8 月 31 日,OpenResty 社区联合又拍云,举办 OpenResty × Open Talk 全国巡回沙龙·成都站,APISIX 主要作者王院生在活动上做了<APISIX ...