Arithmetic Shift doesnt work on negative num input? Any idea what I am doing wrong here?

StackOverflow https://stackoverflow.com/questions/21357181

  •  02-10-2022
  •  | 
  •  

Question

// 1.5 Exercise 6.cpp : main project file.

#include "stdafx.h"
#include <stdio.h>

int sra(int x, int n);

int main()
{
    int intInputNum;

    int finalValue1;
    int finalValue2;

    printf("Please enter a integer and program will shift the integer 2 places to right,\n it will give value for both arithmetic as well as Logical shift\n");
    scanf("%d",&intInputNum);

    finalValue1 = intInputNum >> 2;

    finalValue2 = sra(intInputNum, 2);

    printf("Logical %d \n Arithmetic %d\n", finalValue1, finalValue2);

    return 0;
}


int sra(int x, int k)
{
    int xsrl = (unsigned)x >> k;
    unsigned mask = k ? ((1 << (8 * sizeof(int)-k)) - 1) : 0;
    return (x < 0) ? mask | xsrl : xsrl;
}

Sample run:

Please enter a integer and program will shift the integer 2 places to right,
 it will give value for both arithmetic as well as Logical shift
-500

Logical -125
Arithmetic 1073741823

Why is this not showing the correct value?

Was it helpful?

Solution 2

unsigned mask = k ? ((1 << (8 * sizeof(int)-k)) - 1) : 0;

I think this cannot be what you wanted. Example (k==1): mask = 0x7FFFFFFF

Then you use "mask | xsrl" which gives "0x7FFFFFFF" (it's an OR operation...)

Just thinking aloud: I think you might want

unsigned mask = k ? (0xFFFFFFFF<<(32-k)) : 0; 

To be really precise:

unsigned int mask = 0;
if ( k > 0 && k <= (8*sizeof(int)))
    mask = UINT_MAX<<((8*sizeof(int))-k);

and you need to include "limits.h" to get "UINT_MAX".

OTHER TIPS

The standard doesn't guarantee anything (i.e. it's either Undefined Behaviour in the << case or Implementation Defined in (your) >> case) for shift operations on negative left-hand-side (LHS) arguments.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top