2.7.c 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. #include <stdio.h>
  2. unsigned getbits(unsigned x, int p, int n);
  3. unsigned int setbits(unsigned int x,unsigned int p,unsigned int n,unsigned int y);
  4. #define MAGIC_NUMBER 33091
  5. void shotgunPrintUint(const char name[], unsigned int in);
  6. unsigned int invertBits(unsigned int x,unsigned int p,unsigned int n);
  7. unsigned getInvertBits(unsigned x, int p, int n);
  8. int main()
  9. {
  10. shotgunPrintUint("return ",invertBits(0xdeadbeef,0,32));
  11. // printf("i:%u \t temp:%x \n",-1,temp);
  12. /** shifting 32 bits out is an overflow condition .*/
  13. // unsigned int temp = ~0;
  14. // unsigned int temp2=temp<<32;
  15. // printf("\t temp:%x \n",temp2);
  16. return(0);
  17. }
  18. /**
  19. a function invert(x,p,n) that returns x with the n bits that begin at position p inverted (i.e., 1 changed into 0 and vice versa), leaving the others unchanged.
  20. */
  21. unsigned int invertBits(unsigned int x,unsigned int p,unsigned int n)
  22. {
  23. //printf(" x : %0#10x : p %d : n %d \n",x,p,n);
  24. unsigned int left = getbits(x,p+n,32-(n+p)); //if position is zero...we just want middle case to handle it.
  25. //shotgunPrintUint("left ",left);
  26. unsigned int left_out = ((n+p)<32) ? left << (n+p) :0 ;
  27. //left is in the right spot
  28. shotgunPrintUint("left_out",left_out);
  29. unsigned int middle = getInvertBits(x,p,n); //just like setbits only this part is inverted here.
  30. //shotgunPrintUint("middle ",middle);
  31. unsigned int middle_out = middle << p ;
  32. //shotgunPrintUint("middle_out",middle_out);
  33. shotgunPrintUint("middle_out",middle_out);
  34. unsigned int right_out = getbits(x,0,p); // | getbits(y,p,n);
  35. //shotgunPrintUint("right_out ",right_out);
  36. //printf(" right : %x \n ",right);
  37. // unsigned int right_out = right >> (n+p);
  38. shotgunPrintUint("right_out",right_out);
  39. return left_out | middle_out | right_out;
  40. }
  41. unsigned int setbits(unsigned int x,unsigned int p,unsigned int n,unsigned int y)
  42. {
  43. //printf(" x : %0#10x : p %d : n %d \n",x,p,n);
  44. unsigned int left = getbits(x,p+n,32-(n+p)); //if position is zero...we just want middle case to handle it.
  45. //shotgunPrintUint("left ",left);
  46. unsigned int left_out = ((n+p)<32) ? left << (n+p) :0 ;
  47. //left is in the right spot
  48. //shotgunPrintUint("left_out",left_out);
  49. unsigned int middle = getbits(y,p,n);
  50. //shotgunPrintUint("middle ",middle);
  51. unsigned int middle_out = middle << p ;
  52. //shotgunPrintUint("middle_out",middle_out);
  53. //shotgunPrintUint("middle_out",middle_out);
  54. unsigned int right_out = getbits(x,0,p); // | getbits(y,p,n);
  55. //shotgunPrintUint("right_out ",right_out);
  56. //printf(" right : %x \n ",right);
  57. // unsigned int right_out = right >> (n+p);
  58. //shotgunPrintUint("right_out",right_out);
  59. return left_out | middle_out | right_out;
  60. }
  61. /* the problem here is this function is in fact broken due to ~0 << n not
  62. being valid C anymore.
  63. KNR Bullshit: ~0 << n is not defined in ANSI C
  64. KNR getbits: get n bits from position p
  65. */
  66. /*
  67. even if it is in K&R C
  68. */
  69. /* getbits: get n bits from position p */
  70. unsigned getbits(unsigned x, int p, int n)
  71. {
  72. // shotgunPrintUint("test me",0x1);
  73. // shotgunPrintUint("test me",0x0);
  74. //printf ("getbits x: %0#10x ,p: %d ,n: %d \n",x,p,n);
  75. unsigned int leftmask,rightmask;
  76. leftmask = rightmask = ~0;
  77. //shotgunPrintUint("maxmask ",leftmask);
  78. leftmask = leftmask << p; //find position p
  79. // shotgunPrintUint("leftmask ",leftmask);
  80. int shiftme = 32-(p+n);
  81. rightmask = (shiftme < 32) ? rightmask >> shiftme : 0; //find position p
  82. //shotgunPrintUint("rightmask ",rightmask);
  83. //shotgunPrintUint("shiftme ",shiftme);
  84. unsigned int finalmask = leftmask & rightmask;
  85. unsigned int data = x & finalmask;
  86. shotgunPrintUint("mask ",finalmask);
  87. // shotgunPrintUint("data",data);
  88. unsigned int outdata = data >> p;
  89. //shotgunPrintUint("outdata",outdata);
  90. //unsigned int outdata = (x >> (p-n));
  91. // printf(" mask : %x \n ",mask);
  92. //shotgunPrintUint("outdata",outdata);
  93. return outdata; // (x >> (p-n)) & mask;
  94. }
  95. /**
  96. retrieve n bits starting position p from x, with the bits themselves inverted.
  97. */
  98. unsigned getInvertBits(unsigned x, int p, int n)
  99. {
  100. // shotgunPrintUint("test me",0x1);
  101. // shotgunPrintUint("test me",0x0);
  102. //printf ("getbits x: %0#10x ,p: %d ,n: %d \n",x,p,n);
  103. unsigned int leftmask,rightmask;
  104. leftmask = rightmask = ~0;
  105. //shotgunPrintUint("maxmask ",leftmask);
  106. leftmask = leftmask << p; //find position p
  107. // shotgunPrintUint("leftmask ",leftmask);
  108. int shiftme = 32-(p+n);
  109. rightmask = (shiftme < 32) ? rightmask >> shiftme : 0; //find position p
  110. //shotgunPrintUint("rightmask ",rightmask);
  111. //shotgunPrintUint("shiftme ",shiftme);
  112. unsigned int finalmask = leftmask & rightmask;
  113. unsigned int data = (~x) & finalmask;
  114. shotgunPrintUint("mask ",finalmask);
  115. // shotgunPrintUint("data",data);
  116. unsigned int outdata = data >> p;
  117. //shotgunPrintUint("outdata",outdata);
  118. //unsigned int outdata = (x >> (p-n));
  119. // printf(" mask : %x \n ",mask);
  120. //shotgunPrintUint("outdata",outdata);
  121. return outdata; // (x >> (p-n)) & mask;
  122. }
  123. /**
  124. caution if you printf, padded with 0's, a hex number of exactly 0 it will print
  125. as 0000000000 not 0x00000000
  126. */
  127. /**
  128. drop me in if you don't want to use a debugger like GDB to shotgun-debug
  129. print the value of a uint
  130. */
  131. void shotgunPrintUint(const char name[], unsigned int in)
  132. {
  133. printf(name,23423);
  134. printf("\t\t: %0#10x \n",in);
  135. return;
  136. }