[ 问题描述 ]

在网上看到了两种设置随机颜色的取值代码。但不知道"~~"是干什么用的?

var a = (~~(Math.random() * 255));           //"~~"是什么运算符?
var b = Math.floor((Math.random() * 255));

[ 符号用法 ]

首先,颜色rgb值的三个参数都是0~255的整数。而~~Math.floor()的作用都是将小数转化为整数。但是对于负数它们的运算结果会有一些不同。

  • Math.floor() 方法:将数字向下舍入到最接近的整数,并返回结果。如果传递的参数是整数,则该值不会被舍入。
  • ~~ 两个按位非操作符,作用是干掉数字的小数部分。和强制类型转换的结果基本一样。

若想获得更好的可读性,使用Math.floor。若想最小化它,使用波浪号~~ 。

~(5.5)   // => -6
~(-6)    // => 5
~~5.5    // => 5  (same as Math.trunc(5.5) and Math.floor(5.5))
~~(-5.5) // => -5 (same as Math.trunc(-5.5) but NOT the same as Math.floor(-5.5), which would give -6 )
<script>//Math.floor(): 该方法将数字向下舍入到最接近的整数,并返回结果。如果传递的参数是整数,则该值不会被舍入。console.log( Math.floor( 8.0), Math.floor( 8.4), Math.floor( 8.5), Math.floor( 8.6) ); // 8 8 8 8console.log( Math.floor(-8.0), Math.floor(-8.4), Math.floor(-8.5), Math.floor(-8.6) ); // -8 -9 -9 -9console.log( Math.floor( 0.0), Math.floor( 0.5), Math.floor(-0.0), Math.floor(-0.4), Math.floor(-0.6) ); // 0 0 -0 -1 -1//~~: 做两次按位取反的操作(和强制类型转换基本一样)console.log( ~~( 8.0), ~~( 8.4), ~~( 8.5), ~~( 8.6) ); //8 8 8 8console.log( ~~(-8.0), ~~(-8.4), ~~(-8.5), ~~(-8.6) ); //-8 -8 -8 -8console.log( ~~( 0.0), ~~( 0.5), ~~(-0.0), ~~(-0.4), ~~(-0.6) ); // 0 0 0 0 0
</script>

[ 原理讲解 ]

1. 按位取反(~)的结果

先来复习一下原码/反码/补码:
– - 真值位正时:原码、反码和补码与真值完全相同(最高位是符号位 正: 0; 负: 1);
– - 真值位负时:原码与真值相等;反码是真值的数值位取反;补码是反码的最低为加一。

正整数取反:~(8) = ?   (正数:原码、反码和补码与真值完全相同;)
原/反/补码:0000 1000
----------------------
按位取反 ~:1111 0111 (补码符号位是1 => 真值为负数 => 原码才是真值)1111 0110 (反码)1000 1001 (原码 => 真值为-9)∴ ~8 = -9
=====================================================================================
负整数取反:~(-8) = ?  (负数:原码、反码和补码与真值完全相同;)原 码 :1000 1000反 码 :1111 0111补 码 :1111 1000
----------------------
按位取反 ~:0000 0111 (补码符号位是0 => 真值为正数 => 补码就是真值 => 真值为7)∴ ~(-8) = 7
=====================================================================================
负整数取反:~(0) = ?  (负数:原码、反码和补码与真值完全相同;)
原/反/补码:0000 0000
----------------------
按位取反 ~:1111 1111 (补码符号位是1 => 真值为负数 => 原码才是真值)1111 1110 (反码)1000 0001 (原码 => 真值为-9)∴ ~0 = -1

可以得出两个结论:

  1. 假设x是一个整数,无论是正数还是负数,~x = -(x+1)
  2. 假设x是一个整数,无论是正数还是负数,~~x = x

2. JavaScript 中数字的存储方式

根据 ECMAScript 标准,JavaScript 中只有一种数字类型Number:一种64位双精度浮点型的数字数据类型(基于 IEEE 754 标准) (double-precision 64-bit floating point format) 。
取值范围:-(253-1) 到 253-1
JavaScript 并没有为整数给出一种特定的类型。除了能够表示浮点数外,还有一些带符号的值:+Infinity-InfinityNaN (非数值,Not-a-Number)。

3. JavaScript 中位运算的操作数:32位有符号整数

JavaScript 将数字存储为 64位双精度浮点数,但在执行位运算之前,会将数字转换为 32位有符号整数。超过 32 位的数字将丢弃其最高有效位。

如下例子中,超过 32 位的整数转换为 32 位整数:

Before: 11100110111110100000000000000110000000000001
After:              10100000000000000110000000000001

然后,将运算符应用于每对位,按位构造结果。执行按位操作后,将结果转换回 64 位数。

 9 (base 10) = 00000000000000000000000000001001 (base 2)--------------------------------
~9 (base 10) = 11111111111111111111111111110110 (base 2) = -10 (base 10)

⚠️:由于使用32位表示形式,所以 ~-1~4294967295 (232-1) 的结果均为0

const a = 5;           // 00000000000000000000000000000101
const b = -3;          // 11111111111111111111111111111101
const c = -1;          // 11111111111111111111111111111111
const d = 4294967295;  // 01111111111111111111111111111111console.log(~a);       // 11111111111111111111111111111010   // expected output: -6
console.log(~b);       // 00000000000000000000000000000010   // expected output: 2
console.log(~c);       // 00000000000000000000000000000000   // expected output: 0
console.log(~d);       // 10000000000000000000000000000000   // expected output: 0

[ 参考资料 ]

  1. JavaScript 位运算符 https://www.w3school.com.cn/js/js_bitwise.asp
  2. 按位非 (~)
    https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Bitwise_NOT
  3. JavaScript 数据类型和数据结构
    https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Data_structures
  4. ECMAScript® 2022 Language Specification 语言规范
    https://tc39.es/ecma262/#sec-bitwise-not-operator
  5. What is the “double tilde” (~~) operator in JavaScript?
    https://stackoom.com/question/P3Ur

JavaScript:双波浪号“~~“ 与 Math.floor()相关推荐

  1. (转载)JavaScript:双波浪号“~~“ 与 Math.floor()

    [ 问题描述 ] 在网上看到了两种设置随机颜色的取值代码.但不知道"~~"是干什么用的? var a = (~~(Math.random() * 255)); //"~~ ...

  2. 什么是JavaScript中的“双波浪号”(~~)运算符? [重复]

    本文翻译自:What is the "double tilde" (~~) operator in JavaScript? [duplicate] This question al ...

  3. Javascript的~(波浪号)用法

    原理 js中在变量名前加"~" 是位运算NOT,按位取反. var iNum1 = 25; //25 二进制原码等于 0000000000000000000000000001100 ...

  4. js的向下取整_【转载】Javascript使用Math.floor方法向下取整

    在Javascript的数值运算中,很多时候需要对最后计算结果向下取整,Math.floor是javascript中对计算结果向下取整的函数,它总是将数值向下舍入为最接近的整数.此外Math.ceil ...

  5. JavaScript中双叹号(!!)和单叹号(!)

    转自:JavaScript中双叹号(!!)作用 经常看到这样的例子: var a: var b=!!a; a默认是undefined.!a是true,!!a则是false,所以b的值是false,而不 ...

  6. Javascript Math.ceil与Math.round与Math.floor区别

    Javascript Math.ceil()与Math.round()与Math.floor()区别: Math.ceil()向上舍入 alert(Math.ceil(20.1)) //输出 21 a ...

  7. JavaScript 的 Math.floor() 函数

    Math.floor() 返回小于或等于一个给定数字的最大整数. 可以理解 Math.floor()为向下取整. 与其相对的是 Math.ceil() ,这个是向上取整. 如下面的代码: Math.f ...

  8. JavaScript Math floor

    JavaScript Math floor var floor = Math.floor(5.5); console.log(floor);//5

  9. 如何使用JavaScript Math.floor生成范围内的随机整数-已解决

    快速解决方案 (Quick Solution) function randomRange(myMin, myMax) {return Math.floor(Math.random() * (myMax ...

最新文章

  1. osgEarth3.0 加载天地图
  2. zk如何实现watch
  3. windows之实现3D立体效果的三种方法
  4. 用数据驱动思想来设计游戏-读《游戏编程精粹1》
  5. html文档主体的根标签,2 HTML简介标签嵌套和并列关系文档声明
  6. Linux安装Ncurses库
  7. MySQL通过添加索引解决线上数据库服务器压力大问题
  8. ZZULIOJ 1085: 求奇数的乘积(多实例测试)
  9. 独家专访@爱可可-爱生活:如何做好科学研究(干货满满)
  10. MATLAB结构模态分析
  11. 怎么把电脑上的文件迁移到另一台电脑?
  12. 用python爬取网易云音乐评论
  13. 利用5次shift漏洞破解win7密码
  14. Dell PowerEdge全系服务器RAID卡驱动程序 下载地址
  15. 贵州省委常委、宣传部部长、省委网络安全与信息化领导小组副组长慕德贵一行莅临云宏,考察云计算关键核心技术发展情况
  16. Scrum立会报告+燃尽图(Beta阶段第五次)
  17. 我的Qt作品(1)高仿海康威视MVS主界面
  18. 无限循环抛出 No method found for class [B 这个异常
  19. 求解,某M1水卡数据计算分析/大神们求指导!
  20. Linux I/O原理和零拷贝Zero-copy技术全面揭秘

热门文章

  1. 代码审计文章资源汇总
  2. (4)统一流程管理平台----企业中存在的流
  3. IntelliJ IDEA 安装使用教程以及激活码
  4. JVM 堆(heap)详解
  5. 行为树 Behavior3go
  6. 视频剪辑新手必备的几款软件
  7. oracle 共享磁盘阵列,共享磁盘阵列双机热备实战配置教程配置手册.docx
  8. 为数据披上隐形“斗篷”,如何收回部分数据隐私?
  9. mac 旋转时间屏保_如何在Mac上旋转视频
  10. DeDecms 标签运行php