(1)!+-<<>>|&^

低质量解答,大佬们轻点拷打,,(感觉要被盒了

 

1.implication

 * implication - given input x and y, which are binary
 * (taking  the values 0 or 1), return x -> y in propositional logic -
 * 0 for false, 1 for true
 *
 * Below is a truth table for x -> y where A is the result
 *
 * |-----------|-----|
 * |  x  |  y  |  A  |
 * |-----------|-----|
 * |  1  |  1  |  1  |
 * |-----------|-----|
 * |  1  |  0  |  0  |
 * |-----------|-----|
 * |  0  |  1  |  1  |
 * |-----------|-----|
 * |  0  |  0  |  1  |
 * |-----------|-----|
 *
 *
 *   Example: implication(1L,1L) = 1L
 *            implication(1L,0L) = 0L
 *   Rating: 2
 */

用位运算硬凑,经过几次尝试之后可得答案 

long implication(long x, long y) {
    return (((!x) ^ y) | y);
}

2.leastBitPos

/*
 * leastBitPos - return a mask that marks the position of the
 *               least significant 1 bit. If x == 0, return 0
 *   Example: leastBitPos(96L) = 0x20L
 *   Rating: 2
 */
long leastBitPos(long x) {
    return x & (-x);
}
/*

lowbit操作

3.distinctNegation

/*
 * distinctNegation - returns 1 if x != -x.
 *     and 0 otherwise
 *   Rating: 2
 */
long distinctNegation(long x) {
    // only 0  and tmin

    return !((!x) | !(~(x ^ (x - 1))));
}

 如果x不等于-x就返回1。

在数学认识下只有0=-0,但是在二进制补码表示中,tmin=0x8000000000000000。

-tmin为tmin除符号位以外取反+1,仍等于tmin。

因此,如果x==0||x==tmin就返回1。判断x是0,可以用!运算。

判断x是tmin,则需要运用tmin的性质。tmin-1由于溢出是tmax,tmin^tmax==-1,-1取反为0。

(应该没有别的数还满足这个性质8,没细想

4.fitsBits

/*
 * fitsBits - return 1 if x can be represented as an
 *  n-bit, two's complement integer.
 *   1 <= n <= 64
 *   Examples: fitsBits(5,3) = 0L, fitsBits(-4,3) = 1L
 *   Rating: 2
 */
long fitsBits(long x, long n) {
    x >>= (n - 1);

    return (!x) | !(x + 1);
}

一个数如果可以被表达为n—bits。则这个数右移n-1位后,正数为0,负数全是1,即-1。

5.trueFiveEighths

/*
 * trueFiveEighths - multiplies by 5/8 rounding toward 0,
 *  avoiding errors due to overflow
 *  Examples:
 *    trueFiveEighths(11L) = 6L
 *    trueFiveEighths(-9L) = -5L
 *    trueFiveEighths(0x3000000000000000L) = 0x1E00000000000000L (no overflow)
 *  Rating: 4
 */
long trueFiveEighths(long x) {
    long b = x & 7;
    long backup = x;
    x >>= 3;
    // negative number << will [] if  b!=0
    return ((x << 2) + x) + (((b << 2) + b) >> 3) +
           ((!!b) & (!!(backup >> 63)));
}

一个数除以8向下取整等价于右移3位。一个数乘以5等价于乘(101)b,即x=x<<2+x。

 最简单思路:先乘5再除以8,显然会溢出。

也就是必须先除以8。这里特别注意除以8之后,x/8的余数直接被舍去了。这个余数最大是7,7乘以5除以8向下取整等于4,不等于0。也就是说答案还要加上余数的影响:gif.latex?ans%3D%5B%5Cfrac%7Bx%7D%7B8%7D%5D*5&plus;%5B%5Cfrac%7Bx%258*5%7D%7B8%7D%5D

然后开开心心的btest。结果报错,发现输入tmin时,结果等于答案-1。再读题,发现需要向0取整,也就是说当x是负数的时候需要向上取整,而不是向下取整。

没想到什么别的好方法,直接使x是负数且模8不为0时,答案+1。

6.addOK

/*
 * addOK - Determine if can compute x+y without overflow
 *   Example: addOK(0x8000000000000000L,0x8000000000000000L) = 0L,
 *            addOK(0x8000000000000000L,0x7000000000000000L) = 1L,
 *   Rating: 3
 */
long addOK(long x, long y) {
    long a = (x >> 63) & 1;
    long b = (y >> 63) & 1;
    long res = x + y;
    long c = (res >> 63) & 1;

    return (a ^ b) | (!(c ^ a));
}

异号相加不会溢出。

同号相加可能溢出,溢出时结果数和x,y符号不同。

7.isPower2

/*
 * isPower2 - returns 1 if x is a power of 2, and 0 otherwise
 *   Examples: isPower2(5L) = 0L, isPower2(8L) = 1L, isPower2(0) = 0L
 *   Note that no negative number is a power of 2.
 *   Rating: 3
 */
long isPower2(long x) {
    // x-x&(-x)==0 and x != tmin
    long lowbit = x & (-x);
    int sign = (x >> 63) & 1;
    return (!!x) & (!(x - lowbit)) & (!sign);
}

判断x是否是2的n次幂。n为1~64

注意负数不会是2的n次幂。

如果是,则x的二进制表示只有一个1,因此x==lowbit(x)。但是tmin也满足这个条件,因此再排除掉所有负数即可。

8.rotateLeft

/*
 * rotateLeft - Rotate x to the left by n
 *   Can assume that 0 <= n <= 63
 *   Examples:
 *      rotateLeft(0x8765432187654321L,4L) = 0x7654321876543218L
 *   Rating: 3
 */
long rotateLeft(long x, long n) {
    long a = (x >> (64 - n)) & ((1l << n) - 1);
    x = (x << n) + a;
    return x;
}

题意分析:x左移n位,原来左边的n位放到右边。

被移走的 直接 ‘’与 ‘’左移出的那一堆0就行

9.isPalindrome

/*
 * isPalindrome - Return 1 if bit pattern in x is equal to its mirror image
 *   Example: isPalindrome(0x6F0F0123c480F0F6L) = 1L
 *   Rating: 4
 */
long isPalindrome(long x) {
    // divide-and-conquer strategy
    long a1 = 0xaaaaaaaaaaaaaaaa;
    long a2 = 0xcccccccccccccccc;
    long a3 = 0xf0f0f0f0f0f0f0f0;
    long a4 = 0xff00ff00ff00ff00;
    long a5 = 0xffff0000ffff0000;
    long a6 = 0xffffffff00000000;
    long backup = x;
    x = ((x << 32) & a6) | ((x >> 32) & (~a6));
    x = ((x << 16) & a5) | ((x >> 16) & (~a5));
    x = ((x << 8) & a4) | ((x >> 8) & (~a4));
    x = ((x << 4) & a3) | ((x >> 4) & (~a3));
    x = ((x << 2) & a2) | ((x >> 2) & (~a2));
    x = ((x << 1) & a1) | ((x >> 1) & (~a1));

    return !(backup ^ x);
}

题意:判断x在2的补码表示下是否是一个回文数(包括前导0)

判断回文数,我个人已知的方法只有倒着扣出所有数,与原数比较。

一个个扣不现实,因此我个人考虑分治策略能不能成功:要把原数倒着扣出来,可以通过以下步骤:

  1. 把前32位和后32位交换,然后把两部分分别倒过来
  2. 把1~16位和17~32位交换,然后分别倒过来。把33~48位和49~64交换,然后分别倒过来
  3. .......
  4. 把奇数位和偶数位交换

发现分治策略可行,接下来考虑怎么交换。直觉告诉我们会用到左移右移运算。

做第一步,假设这个数是xxxxyyyy,我们可能会考虑变成xxxx0000+0000yyyy(也可能是1111yyyy)。接下来思考怎么整出这两个数即可。盯这这个数本身做位运算得到这两个数,个人觉得很难,因此被迫借助11110000来帮助我们。xxxx0000&11110000=xxxx0000。

1111yyyy&(00001111)=0000yyyy,发现00001111实际上就是11110000的反。因此定义1个这样的数就行。

第一步解决了,剩下几步同理

10.bitParity

/*
 * bitParity - returns 1 if x contains an odd number of 0's
 *   Examples: bitParity(5L) = 0L, bitParity(7L) = 1L
 *   Rating: 4
 */
long bitParity(long x) {
    // Add all 1 to the first bit without considering the rounding
    // So it can use ' ^ '
    x = (x >> 32) ^ x;
    x = (x >> 16) ^ x;
    x = (x >> 8) ^ x;
    x = (x >> 4) ^ x;
    x = (x >> 2) ^ x;
    x = (x >> 1) ^ x;
    x = (x & 1);
    return x;
}

判断x的二进制表示是否有奇数个0。异或不改变奇偶性。

11.absVal

/*
 * absVal - absolute value of x
 *   Example: absVal(-1) = 1.
 *   You may assume -TMax <= x <= TMax
 *   Rating: 4
 */
long absVal(long x) {

    long sign = !!(x >> 63);
    return (x ^ (-sign)) + sign;
}

-x=~x+1。呃呃呃判断一下符号位就完事了,不知道为什么这道题4分。

个人做题时发现的小tips

-1=11111111
tmin=10000000
tmax=01111111
only !0=1
>>  //表示除以2的几次方  下取整 对正负数通用
sign=(x>>63)&1
-x=~x+1
//负数原码求补码  非符号位取反 +1 ,补码求原码同样
//因为对位运算还是不熟练,还有好多tips忘了  无所谓,我会开摆

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值