lab1 Data lab

第一题 
用 &与~ 来完成 '异或运算符' 的功能 
 好像跟数学有关系  德摩根定律 搞半天
非(P 且 Q) = (非 P) 或 (非 Q)//离散数学等值演算
NAND = ~(P & Q) = ~P | ~Q    // 就是这个 直接用这个公式反推一下就可以了 
 //这个公式有点难理解(数学逻辑运算) 直接背算了 
NOR = ~(P | Q)  = ~P & ~Q
非(P 或 Q) = (非 P) 且 (非 Q)
异或运算符 长这样  中间不能用或  然后再用 德摩根定律套用就可以
//a⊕b = (¬a ∧ b) ∨ (a ∧¬b)
/* 
 * bitXor - x^y using only ~ and & 
 *   Example: bitXor(4, 5) = 1
 *   Legal ops: ~ &
 *   Max ops: 14
 *   Rating: 1
 */
int bitXor(int x, int y) {
  return ~(x & y) & (~(~x & ~y));
}

推导过程如图
在这里插入图片描述
58113)

第二题

求整型数补码所表示的最小值

注意实现这道题所用到的常数不能超过8bit

32位的虚拟机  说明 最多有 1000... 
补码 的公式 第一位是-2^w次方 其他位都是正的 那么我想要最小值 第一位为一 其他为零就好了 然后再左移补零就可以

答案 : 我拿1 左移31位就可以 ps : 只要我的最低位为一 我就可以通过左移达成目的 同理 “3” 左移31位 应该也是可以的

3.isTmax

判断x是不是补码表示的最大值

审题 : 
补码表示 最高位 必须为零 然后其他位是一就可以 
32位 用16进制表示 0x00000000 八个零 每位是4个二进制位 每一位都是占用4bit  1 byte是8 bit
同样我们判断 只需要知道 我们有前提 0x7FFFFFFF 是最大值 此时最高位为零 其他都为一 
当我们对其+1 时 最高位为1 其他位是零 刚刚好 与原来的值相反 通过这一点来判断是不是最大值
其他值加一 都做不到和原值相反 因为只有最大值+1才会改变最高位 
另外 : 全为1的oxFFFFFFFF +1 会丢失一位 导致变成全为零 要排除这种情况 
int isTmax(int x) { 
  int tmin = x+1;
  int equal = tmin^(~x);
  return (!!tmin)&(!equal);
}

计算机内部用补码表示 然后 自己写一下源码就能明白 16进制和二进制转换真的很简单

4.allOddBits

如果x中的所有奇数位都为1,则返回1,不是则返回0 , 注意 奇数位是从左往右数为奇数的

  内部都是二进制来表示 并且是补码表示 
  有个位运算是"与" 表示 相同则为1 只要是和奇数位全为1的数进行逻辑与运算那就一定与其相同
  所以答案就是
  因为不能 直接赋值 8bit 就是2个16进制位 因为4个二进制位为一个16进制位
  然后给填充的零里面加1 用 ^ 只要不同则为1 可以将奇数位赋值
int allOddBits(int x) {
  int a_8 = 0xAA;
  int a_16 = (a_8 << 8)|(a_8);
  int a_32 = (a_16 << 16)|(a_16);
  int equal = (x & a_32) ^ a_32;
  return !equal;
}

5.negate

返回x的相反数

很简单 在底层  整数就是二进制补码  相反数就是 按位取反+1 
为什么呢 : 因为正数的补码是本身                         // 例如 -3补码转换成3的补码
            负数的转为原码是按位取反+1(符号位不变)
            而一个负数的补码要转换成相反数的补码         // 负数的源码跟他的正数源码只差了符号位
            其相反数的补码和他的原码是相同的             //本来符号位不要取反 现在全都取反再补一
                

6.isAsciiDigit

判断 0x30 <= x <= 0x39,是返回1,不是则0

我们移项可知 可通过判断正负来判断范围 
向右移31位我们可以得到符号位 
int isAsciiDigit(int x) {
return !((x + ~0x30)>>31) | ((0x39 + ~x)>>31));
}

7.conditional

实现 x ? y : z (x不为0返回y,为0返回z)

就是三目运算符
int conditional(int x, int y, int z) {
x = ~(!!x) + 1;  当x为非0时把他变成0xFFFFFFFF 这个值很特殊 每个位都是1 //和他进行&运算 会保留自己所有的位
·····
当x=0时 每个位变成全零 此时返回 z 否则返回y 就是 return(x&y|~x&z) 

8.isLessOrEqual

实现一个小于等于符号来判断两个数。当x<=y时返回1,否则返回0。转化一下,满足条件y-x>=0时就行。当x,y同号是我们直接向减判断,但是当x,y不同号时,我们需要考虑是否会溢出

减法 
 *   Legal ops: ! ~ & ^ | + << >>
 没有减法 用前面的 
 y-x怎么跟零比 也就是和前面一样 通过右移看符号位 
 这里不能用if语句所以我们通过位运算 和!来完成0 和 1 的输出
 当然防止 正+正=负的情况 我们可以 情况进行排除 只要都为正 直接return 1
          负+负=正的情况 我们可以  只要都为负 我们就return 0 
          先写 return 1 的   (y>>31)&(x>>31)| 同为1 时为真 此时说明大家都是负数 为零时待定
                             (y>>31)^(x>>31) 同号为0 异号为1 
                        若为同号 只要判断 一个东西的正负
                        return ()|()

9.logicalNeg

**实现!运算符 只要不是全零 我就返回 0 **

  0是全零
  通过相反数来解 最后只看符号位  通过前面的公式来找到相反数 
  int t=(~x+1)
  int c=(t^x)>>31 
  我们将他的符号位变成第一位 而且是逻辑右移 前面补得的最高位 移动后 0:00000000 非0: 1111111111 也就是-1
  return c+1 

10.howManyBits

**函数功能:判断x使用补码需要多少位来表示 看不懂了属于是 **


/* howManyBits - return the minimum number of bits required to represent x in
 *             two's complement
 *  Examples: howManyBits(12) = 5
 *            howManyBits(298) = 10
 *            howManyBits(-5) = 4
 *            howManyBits(0)  = 1
 *            howManyBits(-1) = 1
 *            howManyBits(0x80000000) = 32
 *  Legal ops: ! ~ & ^ | + << >>
 *  Max ops: 90
 *  Rating: 4
 */
int howManyBits(int x) {//使用补码时最少需要多少比特位
  int flag;             
  int cnt_16,cnt_8,cnt_4,cnt_2,cnt_1,cnt_0;
  int sign = x>>31;
  x = (sign&(~x))|(~sign&(x));
  flag = !!(x>>16);
  cnt_16 = flag<<4;
  x = x>>cnt_16;
//b16 = !!(x>>16)<<4;
//x = x>>b16;
 
  flag = !!(x>>8);
  cnt_8 = flag<<3;
  x = x>>cnt_8;
 
  flag = !!(x>>4);
  cnt_4 = flag<<2;
  x = x>>cnt_4;
 
  flag = !!(x>>2);
  cnt_2 = flag<<1;
  x = x>>cnt_2;
 
  flag = !!(x>>1);
  cnt_1 = flag;
  x = x>>cnt_1;
 
  cnt_0 = x;
  return cnt_16 + cnt_8 + cnt_4 + cnt_2 + cnt_1 + cnt_0 + 1;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值