2.63 Logic & Arithmetic Right Shift

★★★

Problem:

Fill in code for the following C functions. Function srl performs a logical right shift using an arithmetic shift (given by value xsra), followed by other operations not including right shifts or division. Function sra performs an arithmetic right shift using a logical right shift (given by value xsrl), followed by other operations not including right shifts or division. You may use the computation 8 * sizeof(int) to determine w, the number of bits in data type int. The shift amount k cna range from 0 to w-1.

unsigned srl(unsigned x, int k) {
    /* Perform shift arithmetically */
    unsigned xsra = (int)x >> k;
.
.
.
}

int sra(int x, int k) {
    /* Perform shift logically */
    int xsrl = (unsigned)x >> k;
.
.
.
}

code:

#include <stdio.h>
#include <assert.h>

unsigned srl(unsigned x, int k) {
    /* Perform shift arithmetically */
    unsigned xsra = (int)x >> k;
    int w = (sizeof(int)) << 3;
    int mask = ((int)-1) << (w - k);
    return xsra & ~mask;
}

unsigned sra(int x, int k) {
    /* Perform shift logically */
    int xsrl = (unsigned)x >> k;
    int w = (sizeof(int)) << 3;
    int mask = ((int)-1) << (w - k);
    /* Get the most significant bit unchanged, 0 for other bits */
    int m = 1 << (w - 1);
    /* Make mask unchanged if the most significant bit of x is 1, changed otherwise */
    mask &= !(x & m) - 1;
    return xsrl | mask;
}

int main() {
    unsigned uval = 0x12345678;    // the most significant bit is 0
    int val = 0x12345678;
    assert(srl(uval, 4) == uval >> 4);
    assert(sra(val, 4) == val >>4);

    uval = 0x87654321;    // the most significant bit is 1
    val = 0x87654321;
    assert(srl(uval, 4) == uval >> 4);
    assert(sra(val, 4) == val >>4);

    return 0;
}

Last updated