77百科网
当前位置: 首页 生活百科

js正数转负数的函数(负数转16进制依据的规则)

时间:2023-06-02 作者: 小编 阅读量: 1 栏目名: 生活百科

为什么要做js位运算呢?ECMAScript整数有两种类型,即:,接下来我们就来聊聊关于js正数转负数的函数?以下内容大家不妨参考一二希望能帮到您!因为最近在学习hash算法,里面用到了大量的位运算另外网上也找了很多资料,但大都比较片面,没有说明特殊情况时的处理,换几组数据计算结果就出错。有符号整数使用31位表示整数的数值,用第32位表示整数的符号,0表示正数,1表示负数。数值范围从-2147483647到2147483647。

js正数转负数的函数?为什么要做js位运算呢?ECMAScript 整数有两种类型,即:,接下来我们就来聊聊关于js正数转负数的函数?以下内容大家不妨参考一二希望能帮到您!

js正数转负数的函数

背景

为什么要做js位运算呢?

  • 因为最近在学习hash算法,里面用到了大量的位运算
  • 另外网上也找了很多资料,但大都比较片面,没有说明特殊情况时的处理,换几组数据计算结果就出错。

重温整数

ECMAScript 整数有两种类型,即:

  • 有符号整数(允许用正数和负数)
  • 无符号整数(只允许用正数) 在 ECMAScript 中,所有整数字面量默认都是有符号整数,这意味着什么呢?

有符号整数使用 31 位表示整数的数值,用第 32 位表示整数的符号,0 表示正数,1 表示负数。

数值范围从 -2147483647 到 2147483647。

位运算会把二进制数限制在32位,超出部分会被舍弃

调试位运算常用的几个方法

toString(2)

转换成2进制字符串

var a = 1732584193;a.toString(2); // 1100111010001010010001100000001

parseInt(‘11001’, 2)

将2进制字符串转换成10进制数

parseInt('11001', 2) // 25

padStart(32, ‘0’)

字符串总长度,左边不足位数补0

'1100000001'.padStart(32, 0) // 00000000000000000000001100000001

源码、反码、补码

源码

将数字转换成的2进制数, 最左边表示符号位,1负数,0正数

5 源码: 0101-10 源码:11010

反码

正数的反码与其原码相同

负数的反码,除符号位外,其他位取反

5 源码:0101反码:0101-10源码:11010 反码:10101

补码

正整数的补码与其原码相同

负整数的补码,取反码+1

5源码:0101补码:0101-10源码:11010补码:10110

ok,现在开始正题

位运算符

  • 非(~)
  • 与(&)
  • 或(|)
  • 异或(^)
  • 带符号左移(<<)
  • 带符号右移(>>)
  • 无符号右移(>>>)

位运算符:非(~)

运算步骤:

  1. 将该数字取负数
  2. 然后减1
~25 // -26

过程:

  • 25取负:-25
  • 减1:-26
~1// -2~-1 // 0~100 // -101~-100 // 99

位运算符:与(&)

运算步骤:

  1. 把两个数转换成2进制补码
  2. 相同位置进行比较(同为1,结果为1,否则为0)
  3. 如果计算结果是负数,还要再做补码处理

如果位数不够,正数左边补0,负数补1

正正运算

10 & 3 // 2

过程:

  • 10 补码:1010
  • 3 补码:0011
  • 结果:0010,即 2

正负运算(1)

14 & -13 // 2

过程:

  • 14 补码:01110(补一位符号位)
  • -13 源码:11101,补码:10011
  • 与运算:00010,即 2

正负运算(2)

88 & -19 // 72

过程:

  • 88 补码:01011000(补一位符号位)
  • -19 源码:110011,补码:101100
  • 01011000 & 101100
  • 负数(101100)位数不够,左边补1,即11101100
  • 也就是 01011000 & 11101100
  • 结果为:01001000,即:72

负负运算

-12 & -5 // -16

过程:

  • -12 补码:10100
  • -5 补码:11011
  • 与运算:10000
  • 结果为负,再取一次补码: 110000:-16

练习

3 & 7-21 & 16-271733879 & -17325841941125899778533470 & 81293020 & 0xF48192342 & 0xFFFF

位运算符:或(|)

运算步骤:

  1. 把两个数字转换成2进制补码
  2. 相同位置进行比较(有一个是1,结果即为1)
  3. 如果计算结果是负数,还要再做补码处理

正正运算

10 | 3 // 11

过程:

  • 10 源码:1010
  • 3 源码:0011
  • 结果:1011,即 11

正负运算

10 | -3 // -1

过程:

  • 10补码:01010
  • -3补码:11101
  • 或运算:11111
  • 结果为负,再取码:10001,即:-1

负负运算

-15 | -21 // -5

过程:

  • -15 补码:110001
  • -21 补码:101011
  • 或运算:111011
  • 结果为负再取补码:10101,即:-5

练习

15 | 2040 | -14-271733879 | 1732584193(-271733879 & -1732584194) | (~-271733879 & 271733878)

位运算符:异或(^)

运算步骤:

  1. 把两个数转换成2进制补码
  2. 相同位置进行比较(必须是0和1或者1和0,结果才为1)
  3. 如果结果为负,再取补码

正正异或

10 ^ 3 // 9

过程:

  • 10 补码:1010
  • 3 补码:0011
  • 结果:1001,即 9

正负异或

10 ^ -3 // -9

过程:

  • 10 补码: 01010
  • -3 补码:11101
  • 异或运算:10111
  • 结果为负,再取补码:11001,即-9

负负异或

-10 ^ -3 // 11

过程:

  • -10 补码:10110
  • -3 补码:11101
  • 异或运算:01011,即:11

练习

5 ^ 8-10 ^ 9-13 ^ -20-271733879 ^ -1732584194 ^ 271733878

位运算符:带符号左移(<<)

运算步骤:

  1. 把数字转换成2进制补码
  2. 左移指定位数,右边补0
  3. 如果结果未负数,再取补码

超过32位的部分舍弃

正数左移

1 << 2 // 补码:00000001 左移2位, 即 00000100,结果为:45 << 3 // 补码:00000101 左移3位, 即 00101000,结果为:40 

可以看出,正数带符号左移,即 a << n,其实是 a * 2的n次幂

负数左移

-3 << 4
  • -3 补码:101
  • 左移4位 1010000
  • 标志位为负,取补码:1110000,即-48
-6 << 3// 1010 << 3 等于 1010000,取补码,1110000 即:-48-11 << 4 // 10101 << 4 等于 101010000,取补码,110110000 即:-176

边缘情况

情况1:正数变负数

1732584193 << 2// -1659597820

计算过程

  • 1732584193转换成2进制源码:1100111010001010010001100000001(31位)
  • 左移2位,补2个0:110011101000101001000110000000100(33位)
  • 移除左边多余的1位:10011101000101001000110000000100(32位)
  • 变为负数,取补码:11100010111010110111001111111100
  • 即:-1659597820

情况2:负数变正数

-1732584193 << 2// 1659597820

计算过程

  • -1732584193转换成2进制:11100111010001010010001100000001(32位)
  • 负数,取补码:10011000101110101101110011111111(32位)
  • 左移2位:1001100010111010110111001111111100(34位)
  • 多余部分舍弃:01100010111010110111001111111100(32位)
  • 符号位为正,无需再补码,即:1659597820

练习

1 << 32 1 << 33 1 << 402147483648 << 21732584193 << 6

位运算符:带符号右移(>>)

运算步骤:

  1. 取数字二进制补码
  2. 右移指定位数,左边补位与符号位一致
  3. 多余位被舍弃
  4. 如果计算结果为负,再取补码

正数右移

5 >> 1 // 0101 右移1位 0010,即 21 >> 2 // 0001 右移1位 0000,即 0

正数右移比较简单,移出的内容直接舍弃即可,左边用0补充

负数右移

-5 >> 2 // -2

分析:

  • -5 补码:1011
  • 右移2位:1110
  • 结果为负,取补码:1010,即-2

练习

5 + 64 >> 91732584193 >> 4

位运算符:无符号右移(>>>)

运算步骤:

  1. 把数字转换成32位2进制补码
  2. 连同符号位,右移动指定的位数
  3. 向右被移出的位被丢弃,左侧用0填充

因为符号位变成了 0,所以结果总是正的

正数右移

正数时候 >> 和 >>> 结果是一样的

5 >> 2 // 101 右移2位 001 即:15 >>> 2 // 101 右移2位 001 即:1

负数右移

-5 >>> 2 // 1073741822

过程:

  • -5 源码: 10000000 00000000 00000000 00000101
  • 补码:11111111 11111111 11111111 11111011
  • 右移两位:00111111 11111111 11111111 11111110
  • 转换成十进制即为:1073741822

问题:为什么这个要补满32位,而之前的运算都没有?

因为之前的运算,正数补的都是0,负数虽然补1,但计算后要做补码,补位的数最终不影响计算

而无符号右移,则会影响运算。所以需要补全

练习

-23 >>> 245678765 >>> 31

关于位运算的核心思路

  • 运算前要取补码
  • 运算结果导致负数,再取一次补码

以上内容都是个人收集、以及多次尝试整理的。

因为网上看到的很多文章计算方式都不对,虽然举的例子没问题,但换机组数字就计算错误。

    推荐阅读
  • 白夜行一样好看的小说(白夜行终于读完了)

    警方在她家发现了吃过之后丢弃的包装盒,于是警方断定桐原洋介那天来过雪穗家。西本母女两人居住,雪穗的父亲七年前在工地上发生意外去世了。警方猜测桐原洋介和西本文代的关系不一般,不巧的是西本文代却有完美的不在场的证明。寺崎忠夫承认了他和西本文代确实在交往。这时的警方,推测桐原洋介可能是胁迫西本文代,而寺崎忠夫无法忍受,便将其杀害的,又不巧的是,这个时候,寺崎忠夫发生了意外,疲劳驾驶意外死亡。

  • 昀怎么读什么意思(昀读音和解释)

    跟着小编一起来看一看吧!昀怎么读什么意思昀是一个汉语汉字,读音为yún。释义为日光,出自于《玉篇》――昀,日光也。多用于人名,纪昀,即纪晓岚。《玉篇》日光也。昀部首:日昀笔画:8

  • 屋顶被火球砸死(神秘火球坠落挪威首都)

    NMN当地时间7月25日午夜,挪威首都奥斯陆的一些市民被空中传来的巨响惊醒。研究人员推测,这个火球是一颗火流星。根据监控,研究人员推断这颗火流星最终落入了距奥斯陆市区约60公里的Finnemarka森林中,并在流星坠落后进行了搜寻。这颗火流星的本体有卡车般大,释放出的能量相当于广岛原子弹爆炸的30倍左右。它坠落后给当地的建筑造成了一定程度的破坏,并使大约1200人不同程度地受伤神秘火球午夜坠落挪威的森林。

  • 帝豪s和帝豪gs有什么区别(帝豪s跟帝豪gs)

    近日,小编经常收到小伙伴们关于“帝豪S和帝豪GS有什么区别”的相关留言,现在为大家讲解。帝豪s和帝豪gs都是吉列汽车旗下的SUV车型。帝豪s和帝豪gs两者的主要区别在于:1,产品售价对比,帝豪s的定价比帝豪gs稍微高一些;2,产品定位对比,帝豪s虽然跟帝豪gs在车型还有很多方面很类似,但是帝豪s更注重在年轻运动、时尚感、科技感方面的品牌升级。买车究竟是买轿车好呢?其实,这个关键还是要看买车的目的是什么。

  • 普通翡翠怎么让它水头好点(如果你不懂翡翠的)

    当欣赏翡翠的水头时,联想起女人如水这句话,都有那么一种类似的感觉,清新雅致,显得是那样的纯净而动人、单纯、和平之美别具韵味。水头是翡翠业内的行家通过长时期的观察总结出来的一种比拟性的表述。说到翡翠的水头,大家都知道透明度好的翡翠,水头就好,水头就是翡翠的透明度,这种说法不完全正确。水头的好坏直接关系到成品的质量,是评价翡翠的重要因素之一。

  • 鲜红的太阳在徐徐上升改成比喻句(什么是比喻句)

    我们一起去了解并探讨一下这个问题吧!鲜红的太阳在徐徐上升改成比喻句徐徐上升的太阳像鲜红的一团火。鲜红的太阳在徐徐上升,像一个硕大的火球。比喻句,是一种常用修辞手法,意思是打比方,用浅显、具体、生动的事物来代替抽象、难理解的事物。

  • 金乡定亲风俗(文化费县之婚嫁习俗篇)

    费县民间关于婚嫁的习俗讲究也特别多,操办起来也是力求热闹。不过了解费县这些习俗还是很有意义的,既是对传统文化的传承,很多礼节的设定本来也具有实用价值。费县的很多婚嫁习俗也是这样,看似落后的无价值的仪式,有一部分因为生活习惯变化太大没有操作必要了,但大部分还是有价值的。今天首先介绍费县婚嫁习俗当中的定亲仪式,明天介绍送日子习俗,欢迎继续关注。

  • 隔离乳可以直接涂吗(怎么使用)

    隔离乳的主要作用是隔绝皮肤和彩妆,以及空气中的污染物,虽然它里面也含有一定物质,可以滋养肌肤,但单靠这些是不能够满足肌肤要求的,所以在使用隔离乳之前要做好基础护肤工作。一般情况下最简单的步骤是在使用完爽肤水以及乳液之后涂抹隔离乳,如果是本身肌肤比较容易出油,或是夏天容易出汗的情况下,可以选择拍完水之后使用隔离乳。隔离乳的主要作用是保护肌肤,使用完隔离乳之后,就可以使用其他彩妆产品了。

  • 等一个人的说说(20条等一个人的说说心情短语)

    死缠烂打的样子特别丑,所以我选择自己走。如果有一天,我走进你的心里,我也会哭,因为那里没有我。

  • 要请病假的证明怎么开?(请病假需要怎么开证明)

    第三条企业职工因患病或非因工负伤,需要停止工作医疗时,根据本人实际参加工作年限和在本单位工作年限,给予三个月到二十四个月的医疗期:(一)实际工作年限十年以下的,在本单位工作年限五年以下的为三个月;五年以上的为六个月。