#include /*************************************************** * Finding a bug * * The following program is intended to determine * whether the result of dividing an integer by 2 * is even or odd. * * Does the original expression * * n & 2 == 2 * * work as intended? * * If not, why not? * * What would you do to fix it? * * * OPERATOR PRECEDENCE * * The first problem is operator precedence. * * The equality operator == has higher precedence * than the bitwise AND operator &. * * Consequently, * * n & 2 == 2 * * is interpreted as * * n & (2 == 2). * * Since * * 2 == 2 * * is true, and true converts to 1 in this * expression, the test is effectively * * n & 1. * * This tests bit 0 rather than bit 1. * * Parentheses are therefore required: * * (n & 2) == 2. * * * WHY BIT 1? * * For a non-negative integer, dividing by 2 shifts * the significance of every bit one position to the * right. * * Thus, the original bit 1 determines whether n/2 * is even or odd: * * bit 1 == 0 n/2 is even * bit 1 == 1 n/2 is odd. * * For example, * * 8 = 1000 8/2 = 4, which is even * 10 = 1010 10/2 = 5, which is odd. * * * NEGATIVE INTEGERS * * Once you have fixed the precedence bug, try the * program with negative integers as well. * * Does the bitwise test still work? ***************************************************/ // Function declarations int main(); // Function definitions int main() { int n{}; std::cout << "Enter an integer: "; std::cin >> n; if ( n & 2 == 2 ) { std::cout << "The number divided by two is even" << std::endl; } else { std::cout << "The number divided by two is odd" << std::endl; } return 0; } // Hints: // // First, fix the operator-precedence bug. // // n & 2 == 2 // // is not evaluated in the order you might initially // expect. // // Your compiler may even warn you about this. // // Once you have fixed that problem, test values such // as // // 8, 10, 12, 14 // // and then try // // -8, -10, -12, -14. // // Does the corrected bitwise expression work for // both positive and negative integers? // Here is one solution: /* if ( (n & 2) == 0 ) { std::cout << "The number divided by two is even" << std::endl; } else { std::cout << "The number divided by two is odd" << std::endl; } */ /*************************************************** * Explanation * * The expression * * n & 2 == 2 * * is interpreted as * * n & (2 == 2) * * because == has higher precedence than bitwise &. * * The first correction is therefore to use * * (n & 2) == 2. * * However, because we are asking whether n/2 is * even, it is slightly more direct to ask whether * bit 1 is zero: * * (n & 2) == 0. * * If bit 1 is zero, n/2 is even. Otherwise, n/2 is * odd. * * * What about negative integers? * * Modern C++ specifies signed integer values using * the corresponding modulo-2^N bit representation. * Consequently, the same bit test works for negative * integers as well. * * For example, * * -8/2 == -4 even * -10/2 == -5 odd * -12/2 == -6 even * -14/2 == -7 odd. * * There is therefore no need to first calculate the * absolute value. * * * An alternative solution * * If the purpose were simply to solve the problem, * rather than to practise bitwise operations, the * intention could be expressed much more directly: * * if ( ((n/2) % 2) == 0 ) { * ... * } * * For this exercise, however, the bitwise solution * illustrates both operator precedence and the * significance of individual bits. ***************************************************/