位运算

JavaScript 位运算笔记

我与影子孤独终老i 提交于 2020-01-08 16:33:43
【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>> 之前一直以为,在js的位运算中,双精度浮点数在内部会先被转成32位整数,再执行位运算,然后再转为64位数值,因此效率极低。今天实验发现,对浮点执行位运算只会导致数值不准确,而不会导致效率低下,相比乘法,左移位要快66%(其实就是浮点运算与整数运算的差距)。 以下结果在 IE 7 ~ IE 10 上测试得出 技巧1:移位运算比乘除法快(当因数是2的幂数) <!-- lang: js --> b = a << 1; 大概快 6.8% 技巧2:奇偶判断 <!-- lang: js --> b = a & 1; 0位与1相与,相比于 x % 2,大概快 35% 技巧3:判断两个数符号是否相同 <!-- lang: js --> (a ^ b) >= 0 相比于 <!-- lang: js --> if ( a == 0 ) return 1; else if ( a > 0 ) return b >= 0; else return b <= 0; 其效率基本一样,但更简洁。 相比于 <!-- lang: js --> (a * b) >= 0; 不会有溢出问题。 技巧4:判断一个数是否为2的幂 <!-- lang: js --> (a & (a - 1)) == 0; 来源: oschina 链接: https:/

位运算技巧

六月ゝ 毕业季﹏ 提交于 2020-01-08 16:18:51
【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>> Compute the sign of an integer int v; // we want to find the sign of v int sign; // the result goes here // CHAR_BIT is the number of bits per byte (normally 8). sign = -(v < 0); // if v < 0 then -1, else 0. // 或者,避免在具有标志寄存器(IA32)的CPU上分支 sign = -(int)((unsigned int)((int)v) >> (sizeof(int) * CHAR_BIT - 1)); // or, for one less instruction (but not portable): sign = v >> (sizeof(int) * CHAR_BIT - 1); The last expression above evaluates to sign = v >> 31 for 32-bit integers. This is one operation faster than the obvious way, sign = -(v < 0). This trick works

HashMap初始化容量过程

依然范特西╮ 提交于 2020-01-08 13:41:40
集合是Java开发日常开发中经常会使用到的,而作为一种典型的K-V结构的数据结构,HashMap对于Java开发者一定不陌生。在日常开发中,我们经常会像如下方式以下创建一个HashMap: Map<String, String> map = new HashMap<String, String>(); 但是,大家有没有想过,上面的代码中,我们并没有给HashMap指定容量,那么,这时候一个新创建的HashMap的默认容量是多少呢?为什么呢?本文就来分析下这个问题。 什么是容量 在Java中,保存数据有两种比较简单的数据结构:数组和链表。数组的特点是:寻址容易,插入和删除困难;而链表的特点是:寻址困难,插入和删除容易。HashMap就是将数组和链表组合在一起,发挥了两者的优势,我们可以将其理解为链表的数组。在HashMap中,有两个比较容易混淆的关键字段:size和capacity ,这其中capacity就是Map的容量,而size我们称之为Map中的元素个数。简单打个比方你就更容易理解了:HashMap就是一个“桶”,那么容量(capacity)就是这个桶当前最多可以装多少元素,而元素个数(size)表示这个桶已经装了多少元素。 如以下代码: Map<String, String> map = new HashMap<String, String>();map.put(

位运算——异或运算

只谈情不闲聊 提交于 2020-01-07 21:04:25
今天刷题时遇到一个题,本以为是暴力+大模拟,结果看完别人的AC代码后人都傻了,竟然是位运算。其中用到了异或 ^ 这种运算符。 先上原题连接 : 传送门 题目意思很好理解,有无限多个路灯,编号为1.2.3…刚开始时都是关着的,每次对一盏灯的操作都会改变它的状态(即开变成关,关变成开)。每次操作会给你一个实数a和一个整数b,一次操作是一次从1到b的k次循环,编号为a*k的实数部分的灯会改变状态。问,最后剩下的灯的编号为多少。 这是个很简单的模拟+暴力题,因为数据保证不超过2e6,所以我也用暴力的方法AC了 暴力AC代码: # include <stdio.h> # include <cstring> # include <iostream> # include <string> # include <cmath> # include <algorithm> # include <cstdlib> # include <queue> using namespace std ; int ans ; int tong [ 2000005 ] ; int main ( ) { int n ; double a , b ; cin >> n ; for ( int i = 0 ; i < n ; i ++ ) { cin >> a >> b ; for ( int j = 1 ; j <= b

位运算

北城以北 提交于 2020-01-04 17:24:16
左移,右移 位运算 最近在用findbugs扫描代码中的规范问题时,看到了位运算的用处,记录一下 /** * 位运算 */ @Test public void testUnsignedOperateAverage ( ) { int beginIndex = 3 ; int endIndex = 5 ; int midIndex1 = ( beginIndex + endIndex ) / 2 ; System . out . println ( "两个数求平均值:" + midIndex1 ) ; System . out . println ( "使用左移操作得到的值:" + ( ( beginIndex + endIndex ) << 1 ) ) ; System . out . println ( "使用右移操作得到的值:" + ( ( beginIndex + endIndex ) >> 1 ) ) ; } 运行结果: ↓...start test...↓ 两个数求平均值:4 使用左移操作得到的值:16 使用右移操作得到的值:4 ↑...end test...↑ Process finished with exit code 0 重点: <<:左移运算符,number<<1,相当于number*2; >>:左移运算符,number>>1,相当于number/2; >>>

[位运算]签到题

坚强是说给别人听的谎言 提交于 2019-12-26 03:32:45
题目描述 作为一道签到题,自然只能包含最基本的算法。本题的任务很简单,给定一个长度为n的序列a,你要将其排序。 由于出题人很菜,不会排序算法,他决定自己编一个。他想找到一个数x,使得序列中的所有数字都异或上x后序列恰好按从小到大排列。 顺带,这个序列会被进行若干次修改,每次修改后你需要回答当前是否存在一个x满足序列中数字异或上x后按从小到大排列,如果有,请你给出最小的x。 输入 第一行一个正整数n。 第二行n个非负整数,表示序列a。 第三行一个非负整数q,表示修改次数。 接下来q行,每行一个正整数x和一个非负整数y,表示将序列中第x个元素修改为y 输出 输出q+1行,每行一个整数,第一行表示一开始最小的合法x,之后q行依次表示每次修改后最小的合法x,如果不存在则这一行输出−1。 样例输入 复制样例数据 3 0 1 4 3 2 7 3 3 1 4 样例输出 0 2 -1 4 提示 对于100%的数据,n,m≤106,所有数字不超过230。 请注意输入输出效率对程序运行时间的影响。 两个数的大小差异在于其二者二进制位相异的最高一位,若在这一位异或1,两数的大小关系能得到反转,在除这位外的任何一位异或0/1,大小关系不会改变 #include <iostream> #include<cstdio> #include<cstring> #include<algorithm> using

位运算

不想你离开。 提交于 2019-12-23 06:01:03
二进制 我们日常使用的是十进制,而计算机中则使用的是二进制 十进制:逢十进一 二进制:逢二进一 常用位运算 1) 位与 & (1&1=1 0&0=0 1&0=0) 如果两个相应的二进制位都为1,则该位的结果值为1,否则为0 2) 位或 | (1|1=1 0|0=0 1|0=1) 两个相应的二进制位中只要有一个为1,该位的结果值为1 3) 位非 ~ (~1=0 ~0=1) ~是一元运算符,用来对一个二进制数按位取反,即将0变1,将1 4) 位异或^ (1^1=0 1^0=1 0^0=0) 若参加运算的两个二进制位值相同则为0,否则为1 有符号右移 >> (若为正数,高位补0,负数,高位补1) 有符号左移 <<(右补0) 无符号右移 >>>(不论正负,高位均补0) 特殊性质:取模 a%(2^n) 等价于a&(2^n -1), map里数组个数一定为2的乘方数,计算key值在哪个元素中的时候,就用位运算来快速定位。 位运算应用场景 Java中的类修饰符,成员变量修饰符,方法修饰符 Java容器中的HashMap和ConcurrentHashMap的实现 权限控制或者商品属性 简单可逆加密(1^1=0;0^1=1) 将位运算用在权限控制、商品属性上 节省代码量,效率高,属性变动影响小,不直观 public class Permission { private static final

位运算的基本操作【转载】

泄露秘密 提交于 2019-12-23 06:00:02
https://blog.csdn.net/mengzhengjie/article/details/80611422 leetcode 总结 位运算小结(按位与、按位或、按位异或、取反、左移、右移) 位运算不管是在 Java 语言,还是在C语言中,或者其他语言,都是经常会用到的,所以本文也就不固定以某种语言来举例子了,原始点就从0、1开始。位运算主要包括按位与(&)、按位或(|)、按位异或(^)、取反(~)、左移(<<)、右移(>>)这几种,其中除了取反(~)以外,其他的都是二目运算符,即要求运算符左右两侧均有一个运算量。 1、补码 在总结按位运算前,有必要先介绍下补码的知识,我们知道当将一个十进制正整数转换为二进制数的时候,只需要通过除2取余的方法即可,但是怎么将一个十进制的负整数转换为二进制数呢?其实,负数是以补码的形式表示,其转换方式,简单的一句话就是:先按正数转换,然后取反加1。 1 2 3 4 5 6 7 要将十进制的-10用二进制表示,先将10用二进制表示: 0000 0000 0000 1010 取反: 1111 1111 1111 0101 加1: 1111 1111 1111 0110 所以,-10的二进制表示就是:1111 1111 1111 0110 2、按位与(&) 参加运算的两个数,换算为二进制(0、1)后,进行与运算。只有当相应位上的数都是1时

位运算解决N-皇后问题

巧了我就是萌 提交于 2019-12-22 09:13:29
位运算的简单操作: 描述: 位运算是定义在整数上的运算。但在做位运算的时候,并不把整数看作整数,而是将它们看做一系列二进制数字,逐位进行运算。位运算有6种,他们的名称,运算符及运算规则如下: 与 (and): 5 & 6 = 4 (101 & 110 = 100) 或 (or): 5 | 6 = 7 (101 | 110 = 111) 异或 (xor): 5 ^ 6 = 3 (101 ^ 110 = 011) 取反 (not / complement): ~5 = -6 (~00000101 = 11111010) 左移 (shift left): 5 << 2 = 20 (101 << 2 = 10100) 右移 (shift right): 5 >> 2 = 1 (101 >> 2 = 1) 说明: 与,或,异或都是二元运算符,逐位进行逻辑运算。 取反是一元运算符,它把一个整数的所有二进制位都取反。负数在计算中用补码表示,求一个数的相反数的操作是 :取反加一,取反本身的效果是将 x变为 -1-x ,无论 x 本身的符号如何。 左移时右侧添0顶位,在左侧不溢出的情况下,左移 k 位相当于乘以2^k(无论正负数); -右移时右侧移出的位均舍弃,左侧则有两种选择。如果一律添0顶位,则成为 逻辑右移,若重复原数的符号位,则称为算术右移。算术右移 k 位等价于除以 2^k 再向下取整

Java中的位运算

烂漫一生 提交于 2019-12-20 00:29:42
  最近饶有兴致,看了一些java源代码,发现源码里面一些精巧的实现是通过位运算实现的,比如十进制整数转成十六进制形式字符串输出: 1 public static String toHexString(int i) 2 { 3 return toUnsignedString(i, 4); 4 } 5 6 private static String toUnsignedString(int i, int shift) { 7 char[] buf = new char[32]; 8 int charPos = 32; 9 int radix = 1 << shift; 10 int mask = radix - 1; 11 do { 12 buf[--charPos] = digits[i & mask]; 13 i >>>= shift; 14 } while (i != 0); 15 16 return new String(buf, charPos, (32 - charPos)); 17 } 18 19 final static char[] digits = { 20 '0' , '1' , '2' , '3' , '4' , '5' , 21 '6' , '7' , '8' , '9' , 'a' , 'b' , 22 'c' , 'd' , 'e' , 'f' , 'g