Function that checks for overflow in addition of unsigned ints - c

I have to make functions that check for overflow in integer addition, subtraction, and unsigned int addition(using only ! ~ | & ^ + >> <<). I have functions figured out for signed integer addition and subtraction, but I can't figure out how to do one for unsigned int addition.
How would I go about doing this?
Here is the code I have for the 2 functions I have completed:
int twosAddOk(int x, int y){
int z=x+y;
int a=x>>31;
int b=y>>31;
int c=z>>31;
return !!(a^b)|(!(a^c)&!(b^c));
}
int twosSubtractOK(int x, int y){
int z=x+~y+1;
return !(((x^y & x^z))>>31);
}

You can calculate the carry-out from the MSB the hard way:
int unsignedAddOk(unsigned int x, unsigned int y){
unsigned int x0=(~(1U<<31))&x; // MSB of x cleared
unsigned int y0=(~(1U<<31))&y; // MSB of y cleared
int c=(x0+y0)>>31; // Carry-in of MSB
int a=x>>31; // MSB of x
int b=y>>31; // MSB of y
return !((a&b)|(a&c)|(b&c));
}

Perhaps a solution without coding the magic number 31
// Return 1 on overflow
int unsigned_add_overflow_test(unsigned a, unsigned b) {
// Add all but the LSBits and then add 1 if both LSBits are 1
// When overflow would occur with a + b, sum's MSBit is set.
unsigned sum = (a >> 1) + (b >> 1) + (a&b&1);
// Test MSBit set
// vvv--------- All bits set
return !!(sum & ~(-1u >> 1));
// ^^^^^^^^^^ -- All bits set, except MSBit
// ^^^^^^^^^^^ -- MSBit set, rest are 0
}
Or as a one-liner
!!( ((a >> 1) + (b >> 1) + (a&b&1)) & ~(-1u >> 1)) )

Related

Rotate right using bit operation in c

I am trying to come up with a function int rotateRight (int x, int n) that rotates x to the right by n. For example,
rotateRight(0x87654321,4) = 0x76543218
This is what I have so far:
int rotateRight(int x, int n) {
int mask = (((1 << n)-1)<<(32-n));
int reserve = (int)((unsigned) (x&mask) >>(32-n));
return (x << n) | reserve;
}
However, I am forbidden to use any casting, and the allowed operations are ~ & ^ | + << and >>. Can anyone help me fix this?
Basically all you have to do is:
shift everything right by n bits using right shift: >>
shift the bits you want to rotate all the way to the left: <<
Combine the shifted right and shifted left bits with or: |
See this code for an example implementation using the function signature you require:
int rotateRight(int x, int n) {
//if n=4, x=0x12345678:
//shifted = 0x12345678 >> 4 = 0x01234567
int shifted = x >> n;
//rot_bits = (0x12345678 << 28) = 0x80000000
int rot_bits = x << (32-n);
//combined = 0x80000000 | 0x01234567 = 0x81234567
int combined = shifted | rot_bits;
return combined;
}
This implementation isn't safe though, at least not without a few guarantees - namely that x will always be positive, and n will be positive and always <= 32.
If you pass in a negative integer for shifting, it will work incorrectly since it will sign-extend the left-most bit. If you want this function to work for all integers, you should change all the types from int to unsigned int (that way no sign-extension or negative left-shifting will take place) and then modulo n by 32 (% 32). Here is a safe version of the function:
unsigned int rotateRight(unsigned int x, unsigned int n) {
//needed so you don't right shift more than int width
n %= 32;
//needed so you don't left shift more than int width
unsigned int leftshift_val = (32-n) % 32
unsigned int shifted = x >> n;
unsigned int rot_bits = x << leftshift_val;
unsigned int combined = shifted | rot_bits;
return combined;
}
And golfed down to a single line, for you minimalists:
unsigned rotr(unsigned x, unsigned n) {
return (x >> n % 32) | (x << (32-n) % 32);
}
A rotation is done with a combination of left and right shifts.
Shifting a signed integer's sign bit is a problem. Suggest converting to unsigned to perform the shift. #The Paramagnetic Croissant
An example of implementation-defined behavior is the propagation of the high-order bit when a signed integer is shifted right.
Shifting by the bit width or more is a problem. Limit actual shifting to n modulo Bit_width. OP's (...<<(32-n)); code is a problem when n == 0.
OP's example looks more like a left rotate. Will assume the function should rotate right. (0x87654321,4) --> 0x18765432. #Mark Shevchenko
An int may have a width other than 32.
#include <limits.h>
#define INT_BIT_WIDTH (sizeof (int) * CHAR_BIT)
int rotateRight(int x, int n) {
unsigned xu = x;
unsigned nu = n;
nu %= INT_BIT_WIDTH;
unsigned y = xu >> nu;
if (nu > 0) {
y |= xu << (INT_BIT_WIDTH - nu);
}
return y;
}
[Edit] as OP is limited to ~ & ^ | + << >>, use the alternate following code.
Note: This is an issue in rare cases where the width of an int is not a power of 2.
// nu %= INT_BIT_WIDTH;
nu &= INT_BIT_WIDTH - 1;
[Edit2] Thought I would form an unsigned minimalistic solution as inspired by #RPGillespie as OP cannot use %.
#include <limits.h>
#define UNS_WIDTH (sizeof (unsigned) * CHAR_BIT)
#define UNS_WIDTH_M1 (UNS_WIDTH - 1)
unsigned unsigned_rotate_right(unsigned x, unsigned n) {
return (x >> (n & UNS_WIDTH_M1)) | (x << ((UNS_WIDTH - n) & UNS_WIDTH_M1));
}
According to this explanation, rotation can be done with the following implementation.
#include<stdio.h>
#define INT_BITS 32
/*Function to left rotate n by d bits*/
int leftRotate(int n, unsigned int d)
{
/* In n<<d, last d bits are 0. To put first 3 bits of n at
last, do bitwise or of n<<d with n >>(INT_BITS - d) */
return (n << d)|(n >> (INT_BITS - d));
}

Check if a number can be represented using n bits in 2’s complement

I'm working on a function that returns 1 when x can be represented as an n-bit, 2’s complement number and 0 if it can't. Right now my code works for some examples like (5, 3), (-4, 3). But I can't get it to work for instances where n is bigger than x like (2, 6). Any suggestions as to why?
I do have restrictions though which include casting, either explicit or implicit, relative comparison operators (<, >, <=, and >=), division, modulus, and multiplication, subtraction, conditionals (if or ? :), loops, switch statements, function calls, and macro invocations. Assume 1 < n < 32.
int problem2(int x, int n){
int temp = x;
uint32_t mask;
int maskco;
mask = 0xFFFFFFFF << n;
maskco = (mask | temp);
return (maskco) == x;
}
In your function, temp is just redundant, and maskco always have the top bit(s) set, so it won't work if x is a positive number where the top bit isn't set
The simple solution is to mask out the most significant bits of the absolute value, leaving only the low n bits and check if it's still equal to the original value. The absolute value can be calculated using this method
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;
}
Another way:
int fit_in_n_bits2(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;
}
You can also check out oon's way 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;
}
Related:
How to tell if a 32 bit int can fit in a 16 bit short
counting the number of bit required to represent an integer in 2's complement
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);
}
Find the absolute value and subtract 1 if the number was negative
Check if number is less than or equal to 2n-1
Check a working demo here
As per your updated request here is the code how to add two numbers:
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;
}

how to guard against bit overflow in C using only bitwise operators

I have to re-write a method to find out if x is less than or equal to y using only bitwise operators and no conditional statements. I have this so far:
int isLessOrEqual(int x, int y)
{
int a = x + (~y) + 1;
return ((a&0x80000000) >> 31);
}
But I have no idea how to guard against overflow? Can anyone lend a helping hand?
[Edit] Bad solution as it uses conditionals. I'll leave it up for a while for as it may provide insight.
Assume we know int is 4-byte 2's compliment.
if (x == y) return 1;
int SignMask = 0x80000000;
// if x & y have different signs ...
if ((x & SignMask) != (y & SignMask)) {
return !!(x & SignMask);
}
// Continue with your original code knowing overflow will not happen.
Just for the sake of exercise, The following twisted code will do without any "+" or conditional statements (unless you consider cast to boolean conditional).
#define MSB 0x80000000
typedef bool (*RecurseFunc)(unsigned int, unsigned int);
bool EndRecursion(unsigned int ux, unsigned int uy)
{
// stop recursion - ux cannot be smaller than uy
return false;
}
bool CompareMSB(unsigned int ux, unsigned int uy)
{
// jump table, may make global...
RecurseFunc Handler[2] = {EndRecursion, CompareMSB};
// yMsbBigger == MSB only iff Y"MSB==1 and X:MSB==0
unsigned int yMsbBigger = ((~ux) & uy) & MSB;
// differentMsb will be MSB only iff the MSB of Y different MSB of x
unsigned int differentMsb = (uy ^ ux) & MSB;
// prepare to check on the next bit - shift it to MSB position
ux <<= 1;
uy <<= 1;
// we may want to check the remaining bits if ux,uy had same signs and
// the remaining bits of y are not all 0
bool mayRecurse = ((bool)uy) && (!(bool)differentMsb);
// C will not evaluate the second expression if the first is true
// the second expression will "EndRecursion" if we may not recurse -
// otherwise recurse
return (((bool)yMsbBigger) || Handler[mayRecurse](ux, uy));
}
bool isYGreater(int x, int y)
{
// we reverse the sign bits so positive value will have MSB=1, making it
// "greater" then negative value's MSB
unsigned int xbits = (unsigned int)x ^ MSB;
unsigned int ybits = (unsigned int)y ^ MSB;
return (CompareMSB(xbits, ybits));
}

C bytes - can't output char (only 8 bits)

Please take a look at my function:
int getByte(int x, int n) {
int oneOnes = 255 << ( n << 3);
int compute = oneOnes & x;
//FIND A WAY TO RETURN CHAR (NOT INT)
char result = (compute >> (n << 3));
return result;
}
Everthing works great until the comment. That is, I start with an integer x, and I want to take only a certain subsection (specified by n). So what I did was make everything except the 8 bits I want to keep into zeros. So for example, if the input was:
1001011 10011011 00101011 01001011
And I want to keep only the 3rd group of bits (counting from the right), then the result would be:
00000000 10011011 00000000 00000000
So I've managed to do that correctly. The issue is, I need to return only the bits that I want (with the zeros cropped, as a char). Despite creating a char result and returning that, what's being returned is still the 32 bit value.
Any help? Thanks!
To be clear: For 00000000 10011011 00000000 00000000, I want only 10011011 to be returned.
Thanks!
Yes, it is not a 8-bit value as your function is declared to return the int, not a char and you are returning not the result but compute. Also, if you would like it not to be sign-propagated somewhere use unsigned char as a result type:
unsigned char getByte(int x, int n) {
int oneOnes = 255 << ( n << 3);
int compute = oneOnes & x;
//FIND A WAY TO RETURN CHAR (NOT INT)
unsigned char result = (compute >> (n << 3));
return result;
}
But the more efficient implementation is this one:
unsigned getByte(int x, int n) {
return (x >> (n << 3)) & 0xFF;
}
The basic problem is that you're trying to use signed integers to do this, but shifts of signed integers are not well defined -- whenever the bit pattern happens to be a negative value, bad things happen.
Instead, as is usually the case when doing bit manipulations, you want to use unsigned integers:
unsigned int getByte(unsigned int x, unsigned int n) {
unsigned int oneOnes = 255U << ( n << 3);
unsigned int compute = oneOnes & x;
return (compute >> (n << 3));
}
Its even easier if you do the masking AFTER the shifting, as then you don't need to shift the mask:
unsigned int getByte(unsigned int x, unsigned int n) {
return (x >> (n << 3)) & 255U;
}

replace byte in 32 bit number

I have a function called replaceByte(x,n,c) that is to replace byte n in x with c with the following restrictions:
Bytes numbered from 0 (LSB) to 3 (MSB)
Examples: replaceByte(0x12345678,1,0xab) = 0x1234ab78
You can assume 0 <= n <= 3 and 0 <= c <= 255
Legal ops: ! ~ & ^ | + << >>
Max ops: 10
int replaceByte(int x, int n, int c) {
int shift = (c << (8 * n));
int mask = 0xff << shift;
return (mask & x) | shift;
}
but when I test it I get this error:
ERROR: Test replaceByte(-2147483648[0x80000000],0[0x0],0[0x0]) failed...
...Gives 0[0x0]. Should be -2147483648[0x80000000]
after realizing that * is not a legal operator I have finally figured it out...and if you are curious, this is what I did:
int replaceByte(int x, int n, int c) {
int mask = 0xff << (n << 3);
int shift = (c << (n << 3));
return (~mask & x) | shift;
}
Since this looks like homework I'm not going to post code, but list the steps you need to perform:
Cast c into a 32-bit number so you don't lose any bits while shifting
Next, shift c by the appropriate number of bits to the left (if n==0 no shifting, if n==1 shift by 8 etc.)
Create a 32-bit bitmask that will zero the lowest 8 bits of x, then shift this mask by the same amount as the last step
Perform bitwise AND of the shifted bitmask and x to zero out the appropriate bits of x
Perform bitwise OR (or addition) of the shifted c value and x to replace the masked bits of the latter
Ahh... You are almost there.
Just change
return (mask & x) | shift;
to
return (~mask & x) | shift;
The mask should contain all ones except for the region to be masked and not vice versa.
I am using this simple code and it works fine in gcc
#include<stdio.h>
int replaceByte(int x, int n, int c)
{
int shift = (c << (8 * n));
int mask = 0xff << shift;
return (~mask & x) | shift;
}
int main ()
{
printf("%X",replaceByte(0x80000000,0,0));
return 0;
}
Proper solution is for c = 0 as well:
int replaceByte(int x, int n, int c)
{
int shift = 8 * n;
int value = c << shift;
int mask = 0xff << shift;
return (~mask & x) | value;
}

Resources