You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

388 lines
13 KiB

8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
8 months ago
  1. /*
  2. * CS:APP Data Lab
  3. *
  4. * <Please put your name and userid here>
  5. *
  6. * bits.c - Source file with your solutions to the Lab.
  7. * This is the file you will hand in to your instructor.
  8. *
  9. * WARNING: Do not include the <stdio.h> header; it confuses the dlc
  10. * compiler. You can still use printf for debugging without including
  11. * <stdio.h>, although you might get a compiler warning. In general,
  12. * it's not good practice to ignore compiler warnings, but in this
  13. * case it's OK.
  14. */
  15. #if 0
  16. /*
  17. * Instructions to Students:
  18. *
  19. * STEP 1: Read the following instructions carefully.
  20. */
  21. You will provide your solution to the Data Lab by
  22. editing the collection of functions in this source file.
  23. INTEGER CODING RULES:
  24. Replace the "return" statement in each function with one
  25. or more lines of C code that implements the function. Your code
  26. must conform to the following style:
  27. int Funct(arg1, arg2, ...) {
  28. /* brief description of how your implementation works */
  29. int var1 = Expr1;
  30. ...
  31. int varM = ExprM;
  32. varJ = ExprJ;
  33. ...
  34. varN = ExprN;
  35. return ExprR;
  36. }
  37. Each "Expr" is an expression using ONLY the following:
  38. 1. Integer constants 0 through 255 (0xFF), inclusive. You are
  39. not allowed to use big constants such as 0xffffffff.
  40. 2. Function arguments and local variables (no global variables).
  41. 3. Unary integer operations ! ~
  42. 4. Binary integer operations & ^ | + << >>
  43. Some of the problems restrict the set of allowed operators even further.
  44. Each "Expr" may consist of multiple operators. You are not restricted to
  45. one operator per line.
  46. You are expressly forbidden to:
  47. 1. Use any control constructs such as if, do, while, for, switch, etc.
  48. 2. Define or use any macros.
  49. 3. Define any additional functions in this file.
  50. 4. Call any functions.
  51. 5. Use any other operations, such as &&, ||, -, or ?:
  52. 6. Use any form of casting.
  53. 7. Use any data type other than int. This implies that you
  54. cannot use arrays, structs, or unions.
  55. You may assume that your machine:
  56. 1. Uses 2s complement, 32-bit representations of integers.
  57. 2. Performs right shifts arithmetically.
  58. 3. Has unpredictable behavior when shifting if the shift amount
  59. is less than 0 or greater than 31.
  60. EXAMPLES OF ACCEPTABLE CODING STYLE:
  61. /*
  62. * pow2plus1 - returns 2^x + 1, where 0 <= x <= 31
  63. */
  64. int pow2plus1(int x) {
  65. /* exploit ability of shifts to compute powers of 2 */
  66. return (1 << x) + 1;
  67. }
  68. /*
  69. * pow2plus4 - returns 2^x + 4, where 0 <= x <= 31
  70. */
  71. int pow2plus4(int x) {
  72. /* exploit ability of shifts to compute powers of 2 */
  73. int result = (1 << x);
  74. result += 4;
  75. return result;
  76. }
  77. FLOATING POINT CODING RULES
  78. For the problems that require you to implement floating-point operations,
  79. the coding rules are less strict. You are allowed to use looping and
  80. conditional control. You are allowed to use both ints and unsigneds.
  81. You can use arbitrary integer and unsigned constants. You can use any arithmetic,
  82. logical, or comparison operations on int or unsigned data.
  83. You are expressly forbidden to:
  84. 1. Define or use any macros.
  85. 2. Define any additional functions in this file.
  86. 3. Call any functions.
  87. 4. Use any form of casting.
  88. 5. Use any data type other than int or unsigned. This means that you
  89. cannot use arrays, structs, or unions.
  90. 6. Use any floating point data types, operations, or constants.
  91. NOTES:
  92. 1. Use the dlc (data lab checker) compiler (described in the handout) to
  93. check the legality of your solutions.
  94. 2. Each function has a maximum number of operations (integer, logical,
  95. or comparison) that you are allowed to use for your implementation
  96. of the function. The max operator count is checked by dlc.
  97. Note that assignment ('=') is not counted; you may use as many of
  98. these as you want without penalty.
  99. 3. Use the btest test harness to check your functions for correctness.
  100. 4. Use the BDD checker to formally verify your functions
  101. 5. The maximum number of ops for each function is given in the
  102. header comment for each function. If there are any inconsistencies
  103. between the maximum ops in the writeup and in this file, consider
  104. this file the authoritative source.
  105. /*
  106. * STEP 2: Modify the following functions according the coding rules.
  107. *
  108. * IMPORTANT. TO AVOID GRADING SURPRISES:
  109. * 1. Use the dlc compiler to check that your solutions conform
  110. * to the coding rules.
  111. * 2. Use the BDD checker to formally verify that your solutions produce
  112. * the correct answers.
  113. */
  114. #endif
  115. /* Copyright (C) 1991-2020 Free Software Foundation, Inc.
  116. This file is part of the GNU C Library.
  117. The GNU C Library is free software; you can redistribute it and/or
  118. modify it under the terms of the GNU Lesser General Public
  119. License as published by the Free Software Foundation; either
  120. version 2.1 of the License, or (at your option) any later version.
  121. The GNU C Library is distributed in the hope that it will be useful,
  122. but WITHOUT ANY WARRANTY; without even the implied warranty of
  123. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  124. Lesser General Public License for more details.
  125. You should have received a copy of the GNU Lesser General Public
  126. License along with the GNU C Library; if not, see
  127. <https://www.gnu.org/licenses/>. */
  128. /* This header is separate from features.h so that the compiler can
  129. include it implicitly at the start of every compilation. It must
  130. not itself include <features.h> or any other header that includes
  131. <features.h> because the implicit include comes before any feature
  132. test macros that may be defined in a source file before it first
  133. explicitly includes a system header. GCC knows the name of this
  134. header in order to preinclude it. */
  135. /* glibc's intent is to support the IEC 559 math functionality, real
  136. and complex. If the GCC (4.9 and later) predefined macros
  137. specifying compiler intent are available, use them to determine
  138. whether the overall intent is to support these features; otherwise,
  139. presume an older compiler has intent to support these features and
  140. define these macros by default. */
  141. /* wchar_t uses Unicode 10.0.0. Version 10.0 of the Unicode Standard is
  142. synchronized with ISO/IEC 10646:2017, fifth edition, plus
  143. the following additions from Amendment 1 to the fifth edition:
  144. - 56 emoji characters
  145. - 285 hentaigana
  146. - 3 additional Zanabazar Square characters */
  147. //1
  148. /*
  149. * bitXor - x^y using only ~ and &
  150. * Example: bitXor(4, 5) = 1
  151. * Legal ops: ~ &
  152. * Max ops: 14
  153. * Rating: 1
  154. */
  155. int bitXor(int x, int y) {
  156. return ~(~x&~y)&~(x&y);
  157. }
  158. /*
  159. * tmin - return minimum two's complement integer
  160. * Legal ops: ! ~ & ^ | + << >>
  161. * Max ops: 4
  162. * Rating: 1
  163. */
  164. int tmin(void) {
  165. return 0x1<<31;
  166. }
  167. //2
  168. /*
  169. * isTmax - returns 1 if x is the maximum, two's complement number,
  170. * and 0 otherwise
  171. * Legal ops: ! ~ & ^ | +
  172. * Max ops: 10
  173. * Rating: 1
  174. */
  175. int isTmax(int x) {
  176. int i =x+1;
  177. x = x+i;
  178. x = ~x;
  179. i = !i;
  180. x = x+i;
  181. return !x;
  182. }
  183. /*
  184. * allOddBits - return 1 if all odd-numbered bits in word set to 1
  185. * where bits are numbered from 0 (least significant) to 31 (most significant)
  186. * Examples allOddBits(0xFFFFFFFD) = 0, allOddBits(0xAAAAAAAA) = 1
  187. * Legal ops: ! ~ & ^ | + << >>
  188. * Max ops: 12
  189. * Rating: 2
  190. */
  191. int allOddBits(int x) {
  192. int a = 0xaaaaaaaa;
  193. return !((a&x)^a);
  194. }
  195. /*
  196. * negate - return -x
  197. * Example: negate(1) = -1.
  198. * Legal ops: ! ~ & ^ | + << >>
  199. * Max ops: 5
  200. * Rating: 2
  201. */
  202. int negate(int x) {
  203. return ~x+1;
  204. }
  205. //3
  206. /*
  207. * isAsciiDigit - return 1 if 0x30 <= x <= 0x39 (ASCII codes for characters '0' to '9')
  208. * Example: isAsciiDigit(0x35) = 1.
  209. * isAsciiDigit(0x3a) = 0.
  210. * isAsciiDigit(0x05) = 0.
  211. * Legal ops: ! ~ & ^ | + << >>
  212. * Max ops: 15
  213. * Rating: 3
  214. */
  215. int isAsciiDigit(int x) {
  216. //下边界为加够了就溢出,比这个大
  217. //上边界为加不够就不溢出
  218. int downstream = ~0x30+1;
  219. int upstream = ~0x39;
  220. int leftside = !((downstream+x)>>31); //超过0x30就符号变为0
  221. int rightside = !!((upstream+x)>>31); //小于0x39就符号仍然为1
  222. return leftside&rightside;
  223. }
  224. /*
  225. * conditional - same as x ? y : z
  226. * Example: conditional(2,4,5) = 4
  227. * Legal ops: ! ~ & ^ | + << >>
  228. * Max ops: 16
  229. * Rating: 3
  230. */
  231. int conditional(int x, int y, int z) {
  232. x = !!(x);
  233. x = ~x+1;
  234. return (x&y)|(~x&z);
  235. }
  236. /*
  237. * isLessOrEqual - if x <= y then return 1, else return 0
  238. * Example: isLessOrEqual(4,5) = 1.
  239. * Legal ops: ! ~ & ^ | + << >>
  240. * Max ops: 24
  241. * Rating: 3
  242. */
  243. int isLessOrEqual(int x, int y) {
  244. int tmp = ~y+1;
  245. tmp = tmp+x-1;
  246. tmp = tmp >> 31;//如果比y大,则为0,比y小等于,为1
  247. return !!tmp;
  248. }
  249. //4
  250. /*
  251. * logicalNeg - implement the ! operator, using all of
  252. * the legal operators except !
  253. * Examples: logicalNeg(3) = 0, logicalNeg(0) = 1
  254. * Legal ops: ~ & ^ | + << >>
  255. * Max ops: 12
  256. * Rating: 4
  257. */
  258. int logicalNeg(int x) {
  259. return ((x|(~x+1))>>31)+1;
  260. }
  261. /* howManyBits - return the minimum number of bits required to represent x in
  262. * two's complement
  263. * Examples: howManyBits(12) = 5
  264. * howManyBits(298) = 10
  265. * howManyBits(-5) = 4
  266. * howManyBits(0) = 1
  267. * howManyBits(-1) = 1
  268. * howManyBits(0x80000000) = 32
  269. * Legal ops: ! ~ & ^ | + << >>
  270. * Max ops: 90
  271. * Rating: 4
  272. */
  273. int howManyBits(int x) {
  274. x = ((~(x>>31))&x)|(x>>31&~x);//左边为如果为正数,则保留;右边为如果为负数,则取反
  275. //先从最大开始查找
  276. int tf = !!(x>>16); //如果小于等于16位,则为0,否则为1
  277. int b16 = tf << 4; //长度超过16位,记录值b16为16,否则为0,代表至少16位
  278. x = x>>b16; //右移动b16位,超过16位则探讨16位以上的,少于16位则探讨16位以下的
  279. tf = !!(x>>8); //开始探讨剩余部位是否超过8位,超过看超过多少,没超过看余下多少
  280. int b8 = tf << 3;//长度超过8位,记录值b8为8,否则为0,代表再多至少8位
  281. x = x>>b8;
  282. tf = !!(x>>4);
  283. int b4 = tf << 2 ; //8找4,长度超过4位,记录值b4为4,否则为0,代表再多至少4位
  284. x = x>>b4;
  285. tf = !!(x>>2);
  286. int b2 = tf << 1; //4找2,长度超过2位,记录值b2为2,否则为0,代表再多至少2位
  287. x = x>>b2;
  288. tf = !!(x>>1); //2找1,长度超过1位,记录值b1为1,否则为0,代表再多至少1位
  289. int b1 = tf << 0;
  290. x = x>>b1;
  291. int b0 = x;//截断到只剩单个数字,这个数字是1就再多一位,是0就不会增加
  292. return b0+b1+b2+b4+b8+b16+1; //正数多一位补码最高位,负数因为取反未+1,理应再加1,故两个输出表达式一致
  293. }
  294. //float
  295. /*
  296. * floatScale2 - Return bit-level equivalent of expression 2*f for
  297. * floating point argument f.
  298. * Both the argument and result are passed as unsigned int's, but
  299. * they are to be interpreted as the bit-level representation of
  300. * single-precision floating point values.
  301. * When argument is NaN, return argument
  302. * Legal ops: Any integer/unsigned operations incl. ||, &&. also if, while
  303. * Max ops: 30
  304. * Rating: 4
  305. */
  306. unsigned floatScale2(unsigned uf) {
  307. unsigned sign = (0x80000000)&uf;
  308. unsigned exp = (0x7f800000)&uf;
  309. unsigned frac = (0x007fffff)&uf;
  310. if(exp == 0x7f800000)
  311. return uf; //如果是exp全为255,frac全是0就是无穷,不是就是NaN,都直接return
  312. if(exp == 0x00000000){
  313. if(frac == 0x00000000)
  314. return uf; //exp全为0,frac全为0,则为0,0*2=0,原样不动
  315. return (frac<<1)|sign|exp;//exp全为0,frac不全为0,注意到非规格化极小和规格化之间是连续的,即frac第一位为1时,左移会把exp变为非全0,回到规格化
  316. }
  317. return (exp+0x00800000)|sign|frac;
  318. }
  319. /*
  320. * floatFloat2Int - Return bit-level equivalent of expression (int) f
  321. * for floating point argument f.
  322. * Argument is passed as unsigned int, but
  323. * it is to be interpreted as the bit-level representation of a
  324. * single-precision floating point value.
  325. * Anything out of range (including NaN and infinity) should return
  326. * 0x80000000u.
  327. * Legal ops: Any integer/unsigned operations incl. ||, &&. also if, while
  328. * Max ops: 30
  329. * Rating: 4
  330. */
  331. int floatFloat2Int(unsigned uf) {
  332. unsigned sign = ((0x80000000)&uf)>>31;
  333. unsigned exp = ((0x7f800000)&uf)>>23;
  334. unsigned frac = (0x007fffff)&uf;
  335. unsigned base = (frac+0x00800000);//加1后的基底(对于常规数)
  336. int bias = (exp-127)-23;//真实需要左移的
  337. if(sign==0)
  338. sign = 1;
  339. else
  340. sign = -1;
  341. if(exp == 255)
  342. return 0x80000000u;//足够大
  343. if(exp == 0)
  344. return 0;//足够小
  345. if(bias <=0){
  346. if(bias<=-24)
  347. bias = -24;
  348. return sign*(base>>(-bias));
  349. }
  350. else{
  351. if(bias>=9)
  352. return 0x80000000u;
  353. return sign*(base<<bias);
  354. }
  355. }
  356. // #include "floatPower2.c"