2015-01-30 2 views
2

Я работаю над функцией, которая возвращает 1, когда x может быть представлена ​​как n-бит, номер дополнения 2 и 0, если он не может. Прямо сейчас мой код работает для некоторых примеров вроде (5,3), (- 4,3). Но я не могу заставить его работать для случаев, когда n больше, чем x (2,6). Любые предложения относительно того, почему? Спасибо.проблема с использованием маски для управления битом

У меня есть ограничения, которые включают в себя литье, явные или неявные, операторы относительного сравнения (<,>, < =, и> =), деление, модуль и умножение, вычитание, условные выражения (if или? :) , циклы, операторы switch, вызовы функций и макросы. Пусть 1 < п < 32.

int problem2(int x, int n){ 

    int temp = x; 
    uint32_t mask; 
    int maskco; 

    mask = 0xFFFFFFFF << n; 
    maskco = (mask | temp); 

return (maskco) == x; 

} 
+1

как делает ваш код работает для положительных чисел? –

+0

Когда я печатаю hex для maskco и сравниваю его с шестнадцатеричным целым, результат такой же, поэтому я предполагаю, что он работает для некоторых. – Rbutler93

+0

нет, он всегда делает старшие биты числа равными 1 с, поэтому он будет работать только для отрицательных чисел –

ответ

1

В вашем Funciton, temp просто лишняя, и maskco всегда устанавливать верхние биты, так что он не будет работать, если x положительное число

простое решение маскирует наиболее значимые биты

int fit_in_n_bits(int x, int n) 
{ 
    int maskabs = x >> sizeof(int) * CHAR_BIT - 1; 
    int xabs = (x + maskabs)^maskabs; // xabs = |x| 
    int nm  = ~n + 1U;     // nm = -n 
    int mask = 0xFFFFFFFFU >> (32 + nm); 
    return (xabs & mask) == xabs; 
} 

Другой способ:

int fit_in_n_bits(int x, int n) 
{ 
    int nm  = ~n + 1U; 
    int shift = 32U + nm; 
    int masksign = x >> (shift + 1); 
    int maskzero = 0xFFFFFFFFU >> shift; 
    return ((x & maskzero) | masksign) == x; 
} 

Вы также можете проверить путь Oon в here

int check_bits_fit_in_2s_complement(signed int x, unsigned int n) { 
    int mask = x >> 31; 

    return !(((~x & mask) + (x & ~mask))>> (n + ~0)); 
} 

One more way

/* 
* fitsBits - return 1 if x can be represented as an 
* n-bit, two's complement integer. 
* 1 <= n <= 32 
* Examples: fitsBits(5,3) = 0, fitsBits(-4,3) = 1 
* Legal ops: ! ~ &^| + << >> 
* Max ops: 15 
* Rating: 2 
*/ 
int fitsBits(int x, int n) { 
    int r, c; 
    c = 33 + ~n; 
    r = !(((x << c)>>c)^x); 
    return r; 
} 

Похожие:

1
int problem2_mj(int x, int n){ 
    unsigned int r; 
    int const mask = (-x) >> sizeof(int) * CHAR_BIT - 1; 

    r = (-x + mask - (1 & mask))^mask; // Converts +n -> n, -n -> (n-1) 
    return !(((1 << (n-1)) - r) >> sizeof(int) * CHAR_BIT - 1); 
} 
  1. Найти абсолютное значение и вычитать 1, если число было отрицательным
  2. Проверьте число меньше или равно 2 п-1

Check a working demo here


Согласно обновленному запросу здесь код, как добавить два числа:

int AddNums(int x, int y) 
{ 
    int carry; 

    // Iteration 1 
    carry = x & y; 
    x = x^y; 
    y = carry << 1; 

    // Iteration 2 
    carry = x & y; 
    x = x^y; 
    y = carry << 1; 

    ... 

    // Iteration 31 (I am assuming the size of int is 32 bits) 
    carry = x & y; 
    x = x^y; 
    y = carry << 1; 

    return x; 
} 
+0

Спасибо, это имеет смысл, но я не могу использовать вычитание. Есть ли способ сделать это без вычитания. – Rbutler93

+0

Да, напишите вспомогательную функцию для выполнения вычитания с помощью '^' и '&' –

+0

. Я немного смущен тем, как это работает, вы могли бы мне это объяснить? – Rbutler93

Смежные вопросы