In C bits, multiply by 3 and divide by 16

My friend had these puzzles, and this is the one that eludes me. This is the problem: you are given a number, and you want to return that number 3 times and divide by 16 rounding by 0. It should be easy. Trick? You can use only! ~ and ^ | + <β†’ operators and of them only a combination of 12.

int mult(int x){
    //some code here...
return y;
}

My attempt:

    int hold = x + x + x;
    int hold1 = 8;
    hold1 = hold1 & hold;
    hold1 = hold1 >> 3;
    hold = hold >> 4;
    hold = hold + hold1;
    return hold;

But this does not seem to work. I think I have a problem of losing bits, but I can’t think of a way to save them. Another perspective will be enjoyable. To add, you can also use variables of type int and no loop if operators or function calls can be used.

Now I have the number 0xfffffff. It should return 0x2ffffff, but it returns 0x3000000.

+1
5

(). , , 15 3. if ( ) .

, ,

x = x*3

blarg.

hold x + 15;

if , , x , 15, , ( 3, ).

16, , , . !

+3

, ( , ):

((num<<2)+~num+1)>>4

JavaScript, :

for (var num = -128; num <= 128; ++num) {
  var a = Math.floor(num * 3 / 16);
  var b = ((num<<2)+~num+1)>>4;
  console.log(
    "Input:", num,
    "Regular math:", a,
    "Bit math:", b,
    "Equal: ", a===b
  );
}
+2

, 4, 3 , 4.

3*x/16=(x/4+x/4+x/4)/4

main()
{
   int x=0xefffffff;
   int y;
   printf("%x",x);
   y=x&(0x80000000);
   y=y>>31;
   x=(y&(~x+1))+(~y&(x));
   x=x>>2;
   x=x&(0x3fffffff);
   x=x+x+x;
   x=x>>2;
   x=x&(0x3fffffff);
    x=(y&(~x+1))+(~y&(x));
   printf("\n%x %d",x,x);
}

0x3fffffff msb . . 2 . . arround -ve + ve, .

+1

n 16, k c < 16:

    (n/16) = k + (c/16).

( .) 3/16, 3

    (n/16) * 3 = 3k + (c/16) * 3.

k , 3k . , int , , , c < 16, ( sizeof(int) >= 7). ,

    (3n/16) = 3k + (3c/16).

  • k n/16 . , k , AND. 3k. : 3.
  • c AND ( ). 3 . . : 4.
  • , .

: 8.

. . , , n . .

  • n, AND.
  • , OR.
  • .
  • , OR .

, 11.

+1

, C99 6.5.7 , , . , int 32 , int. , , , , , .

, , . 16 ( ), . , 16. , , , . N 2 N -1 , , , .

#include <stdio.h>
#include <stdlib.h>

int ref (int a)
{
  long long int t = ((long long int)a * 3) / 16;
  return (int)t;
}

int main (void)
{
  int a, t, r, c, res;
  a = 0;
  do {
    t = a >> 4;         /* high order bits */
    r = a & 0xf;        /* low order bits */
    c = (a >> 31) & 15; /* shift correction. Portable alternative: (a < 0) ? 15 : 0 */
    res = t + t + t + ((r + r + r + c) >> 4);
    if (res != ref(a)) {
      printf ("!!!! error a=%08x  res=%08x  ref=%08x\n", a, res, ref(a));
      return EXIT_FAILURE;
    }
    a++;
  } while (a);
  return EXIT_SUCCESS;
}
+1

Source: https://habr.com/ru/post/1530061/


All Articles