首页 > 其他分享 >CMU 15-213:DataLab(整数部分)

CMU 15-213:DataLab(整数部分)

时间:2023-08-26 22:55:17浏览次数:39  
标签:Rating DataLab return 213 ops int Max sign 15

本笔记仅仅只是用于记录,内容为提示性,题主做的不一定完全符合规范!!!!。

本实验中,只有整型只能使用“+”和位运算符。后面浮点数可以用控制循环。

1.异或运算

直接用公式,或者像我这样利用真值表凑的

/* 
 * bitXor - x^y using only ~ and & 
 *   Example: bitXor(4, 5) = 1
 *   Legal ops: ~ &
 *   Max ops: 14
 *   Rating: 1
 * bitXor - returns ~(x&y),where 0 <= x <= 31 and 0 <= y <= 31
 * 在此处我们可以知道,异或可以检测x,y为不同数时,返回为1.
 */
int bitXor(int x, int y) {
  return ~(x&y) & ~(~x&~y);
}

2.最小数

在有符号整数中,整数和负数的连接是一个类似循环队列,它利用模将数字限制在区间内。

也就是负数在(\(2^{w-1}-1 \thicksim 2^w\))

/* 
 * ! is negative logic result
 * ~ is negative bits
 * tmin - return minimum two's complement integer 
 *   Legal ops: ! ~ & ^ | + << >>
 *   Max ops: 4
 *   Rating: 1
 * timin - returns 1<<31 
 */
int tmin(void) {

  return 1<<31;

}

3.判断x为最大值

在有符号数中,|Tmin|=|Tmax|+1:也就是说Tmin按位取反等于Tmax.

比如-8~7.1000按位取反0111.而0111+1发生正溢出,因为要限制在区间2^4,所以0111+1=1000=-8.

{还不熟悉,建议翻翻整数编码2.2.x小节}

此处Tmax先加1,正溢出后,Tmax转为Tmin,在按位取反变回Tmax,通过异或验证x是否为Tmax.

而minusOne就单纯是为了处理出现-1时的情况,因为其他情况都已经由(~(x+1)^x)决定。

/*
 * isTmax - returns 1 if x is the maximum, two's complement number,
 *     and 0 otherwise 
 *   Legal ops: ! ~ & ^ | +
 *   Max ops: 10
 *   Rating: 1 
 */
int isTmax(int x) {

  int minusOne = !(~x);
  return !((~(x+1)^x)|minusOne);
 
}

4.所有奇数位是否都为1

提示:在异或中,我们已经说过,其可用于比较两数中是否存在不相同部分.

步骤:先利用掩码提取对应掩码数据,再利用异或判断,是否完全对应

若与mask完全对应,则~(xmask)mask为0,否则为1。

/* 
 * allOddBits - return 1 if all odd-numbered bits in word set to 1
 *   where bits are numbered from 0 (least significant) to 31 (most significant)
 *   Examples allOddBits(0xFFFFFFFD) = 0, allOddBits(0xAAAAAAAA) = 1
 *   Legal ops: ! ~ & ^ | + << >>
 *   Max ops: 12
 *   Rating: 2
 */
int allOddBits(int x) {
  int mask = 0xAA<<24;
  mask = mask+(0xAA<<16)+(0xAA<<8)+(0xAA);
  return !((x&mask)^mask);
}

5.相反数

提示:补码

/* 
 * negate - return -x 
 *   Example: negate(1) = -1.
 *   Legal ops: ! ~ & ^ | + << >>
 *   Max ops: 5
 *   Rating: 2
 */
int negate(int x) {
  return ~x + 1;
}

6.判断x是否为0~9ASCII码

输入数要求是正数,我们首先想到,当输入x时,其条件为48 <= x <= 57。

当x与这个条件的边界值相加后,利用符号进行判断位,查看是否是发生溢出,下届负溢出,上界正溢出

其中下届和上界都是补码表示形式

/* 
 * isAsciiDigit - return 1 if 0x30 <= x <= 0x39 (ASCII codes for characters '0' to '9')
 *   Example: isAsciiDigit(0x35) = 1.
 *            isAsciiDigit(0x3a) = 0.
 *            isAsciiDigit(0x05) = 0.
 *   Legal ops: ! ~ & ^ | + << >>
 *   Max ops: 15
 *   Rating: 3
 */
int isAsciiDigit(int x) {
  int  signflag = 1<<31; //signflag 符号位设置
  int great = ~(0x30)+1; //下界
  int less = ~(signflag+0x39);//上界
  less = signflag & (less+x)>>31;
  great = signflag & (great+x)>>31;
  return !(great|less);
}

7.实现三元运算符

/* 
 * conditional - same as x ? y : z 
 *   Example: conditional(2,4,5) = 4
 *   Legal ops: ! ~ & ^ | + << >>
 *   Max ops: 16
 *   Rating: 3
 */
int conditional(int x, int y, int z) {
  x = !!x; //转为是否为0或者1
  x = ~x + 1; //取反
  return (x&y)|(~x&z); //关键:当x为全1时,x&y=y,而~x&z=0;否则,反之
}

8.比较x<=y

提示:先判断x和y大于或小于0。笔者当时做的时候x和y是四种情况,然后再写结果情况。
最终建立真值表形式,就写出来了结果式。

/* 
 * isLessOrEqual - if x <= y  then return 1, else return 0 
 *   Example: isLessOrEqual(4,5) = 1.
 *   Legal ops: ! ~ & ^ | + << >>
 *   Max ops: 24
 *   Rating: 3
 */
int isLessOrEqual(int x, int y) {
  int result = y + ~x + 1;//y-x;
  int signbit = (result>>31) &1;//取y-x结果的符号位,当y>=x时结果为0,否则为1
  int sign_x = (x>>31) &1;//取x的符号位
  int sign_y = (y>>31) &1;//取y的符号位
  int sign_xXory = sign_x ^ sign_y;//判断x和y的符号位是否相同,即x和y是否同正负
  return (!(sign_xXory|signbit)) | (sign_xXory&sign_x); //需要注意的是,当x<0,y>0时的情况
}

9.判断是否为0

/* 
 * logicalNeg - implement the ! operator, using all of 
 *              the legal operators except !
 *   Examples: logicalNeg(3) = 0, logicalNeg(0) = 1
 *   Legal ops: ~ & ^ | + << >>
 *   Max ops: 12
 *   Rating: 4 
 * 
 */
int logicalNeg(int x) {
  return !(x&(~0x0));//关注0就行,只有0与它的补码的与结果为0x0;
}

10.以二进制补码表示 x 所需的最小位数

提示:就是找第一次出现1的位置。此题因为在补码条件下所以更好做一点。

利用折半查找的思想,先查找高16位是否含1,如果含有,则继续查找确定第一次出现1的位置,一直查找到遍历结束。

/* 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) {
  // 原理:从高位到低位,找第一次出现1的位置,再加上符号位,则最少需要n+1个位;
  int b16, b8, b4, b2, b1, b0; // 表示0~15、16~23、24~27、28~29、30、31的位置处是否含有1,也就是每个部分的最少位数.
  int sign = x >> 31; // 取符号位
  // 因为是在补码的情况下,需要区分x为正负数.如果x为正则不变,x为负则取反,按理来说这里应该是取补码,负数的补码取反+1,但是这题测试时如果加1反而还错了.
  x = (sign^x); 

  //以下类似折半查找
  //先从b16(高16位)开始找是否有1,若有则继续查找高位中第一次出现1的位置
  //否则从b8(低16位)开始
  b16 = !!(x >> 16) << 4;// 先看高16位是否含有1,若有则表示至少需要16位
  x =  x >> b16; // 若有1,则原数右移16位,因为上面已经确定第一次出现1的位置在高16位中。否则在低16位

  b8 = !!(x >> 8) << 3; // 看剩余位是否有1,以下同理
  x = x >> b8;

  b4 = !!(x >> 4) << 2;
  x = x >> b4;

  b2 = !!(x >> 2) << 1;
  x = x >> b2;

  b1 = !!(x >> 1);
  x = x >> b1;
  b0 = x; //最后剩余的一位

  return b16+b8+b4+b2+b1+b0+1; // 别忘记加上符号位
}

标签:Rating,DataLab,return,213,ops,int,Max,sign,15
From: https://www.cnblogs.com/duuuuu17/p/17659647.html

相关文章

  • AtCoder Beginner Contest 215
    [ABC215F]DistMax2 二分出min(|xi-xj|,|yi-yj|),双指针维护是否存在满足条件的点对(i,j),假如二分当前值是x,那么|xi-xj|>=x&&|yi-yj|>=x #include<bits/stdc++.h>usingnamespacestd;#defineendl"\n"typedeflonglongll;consti......
  • 【LGR-153-Div.2】梦熊联盟 8 月月赛 Ⅳ & Cfz Round 1 & 飞熊杯 #1
    【LGR-153-Div.2】梦熊联盟8月月赛Ⅳ&CfzRound1&飞熊杯#1\(T1\)「CfzRound1」DeadCells\(100pts\)正解:模拟(注意特判)llgcd(lla,llb){ returnb?gcd(b,a%b):a;}intmain(){ lla,b,k,d,i,ans=1; a=read();b=read();k=read(); d=a/gcd(a,b)*b; f......
  • P4159 [SCOI2009] 迷路
    传送门先思考\(C_{i,j}\)要么只有0和1两种值的情况,那么这种情况就是求矩阵\(C^k\)中的\(C_{1,n}\)的值。证明:令矩阵\(G=C^2=\sum\limits_{k=1}^nC(i,k)*C(k,j)\),即当\(C(i,k)\)和\(C(k,j)\)都为1时,才有\(C(i,k)*C(k,j)\)才为1,表示\(i->k->j\)的路径,而\(G(i,j)\)即计算了枚举了所......
  • P2151 [SDOI2009] HH去散步 题解
    传送门简要题意:有\(n\)个人,\(m\)条无向边,走\(e\)条边,满足条件若第\(i\)条边为\(u->v\)则第\(i+1\)条边不能是\(v->u\),问\(s->t\)的方案有多少个,取模45989。因为要满足题目关于边的条件,所以我们考虑点边互换。将\(u-v\)的无向边一分为二变成\(u->v,v->u\),第\(i\)条边记录两个变......
  • 剑指Offer 15. 二进制中1的个数
    题目链接:剑指Offer15.二进制中1的个数题目描述:编写一个函数,输入是一个无符号整数(以二进制串的形式),返回其二进制表达式中数字位数为'1'的个数(也被称为汉明重量).)。解法思路:思路一:num依次右移,判断每一次移动后最后一位是否是1,是的话,就ans++代码:func(numuint32)int{......
  • Cisco Secure Web Appliance Virtual 15.0.0 GD - 适用于网络安全的思科高级威胁防护
    CiscoSecureWebApplianceVirtual15.0.0GD-适用于网络安全的思科高级威胁防护AsyncOSforWSA15.0.0GeneralDeployment(GD)请访问原文链接:https://sysin.org/blog/cisco-wsa-15/,查看最新版。原创作品,转载请保留出处。作者主页:sysin.orgCiscoSecureWebAppliance......
  • Cisco Secure Email Virtual Gateway 15.0.0 GD - 电子邮件安全
    CiscoSecureEmailVirtualGateway15.0.0GD-电子邮件安全AsyncOSforESA15.0.0GeneralDeployment(GD)请访问原文链接:https://sysin.org/blog/cisco-esa-15/,查看最新版。原创作品,转载请保留出处。作者主页:sysin.orgCiscoSecureEmail提供高级保护措施,保护您的收......
  • Nexpose v6.6.213 for Linux & Windows - 漏洞扫描
    Nexposev6.6.213forLinux&Windows-漏洞扫描Rapid7VulnerabilityManagement,ReleaseAug23,2023请访问原文链接:https://sysin.org/blog/nexpose-6/,查看最新版。原创作品,转载请保留出处。作者主页:sysin.org您的本地漏洞扫描程序搜集通过实时覆盖整个网络,随......
  • xsschallenge通关(11-15)
    level11老规矩,先查看源码,做代码审计:<?phpini_set("display_errors",0);$str=$_GET["keyword"];$str00=$_GET["t_sort"];$str11=$_SERVER['HTTP_REFERER'];$str22=str_replace(">","",$str11);$str33=st......
  • 1152 Google Recruitment
    题目:InJuly2004,GooglepostedonagiantbillboardalongHighway101inSiliconValley(showninthepicturebelow)forrecruitment.Thecontentissuper-simple,aURLconsistingofthefirst10-digitprimefoundinconsecutivedigitsofthenaturalcon......