How to shift 32 bit int by 32 (yet again)

Turin

Ok, so I know that typically left- and right- shifts are well defined only for values 0..31. I was thinking how to best extend this to include 32, which simplifies some algorithms. I came up with:

 int32 << n & (n-32) >> 5

Which seems to work. Question is, is it guaranteed to work on any architecture (C, C++, Java), and can it be done more effectively?

phuclv

In Java it's guaranteed to work if those variables are of type int, since >> in Java does an arithmetic right shift and shifting more than 31 also has defined behavior. But beware of operator precedence

int lshift(int x, int n)
{
    return (x << n) & ((n-32) >> 5);
}

This will work for shift count up to 32. But it can be modified to include any int values with shift counts larger than 31 return 0

return (x << n) & ((n-32) >> 31);

However in C and C++ the size of int type and the behavior of >> operator is implementation defined. Most (if not all) modern implementations implement it as arithmetic shift for signed types though. Besides, the behavior of shifting more than the variable width is undefined. Worse yet, signed overflow invokes UB so even a left shift by 31 is also UB (until C++14). Therefore to get a well defined output you need to

  • Use a unsigned fixed-width type like uint32_t (so x << 31 isn't UB)
  • Use a compiler that emits arithmetic right shift instruction for >> and use a signed type for n, or implement the arithmetic shift yourself
  • Mask the shift amount to limit it to 5 bits for int32_t

The result would be

uint32_t lshift(uint32_t x, int32_t n)
{
    return (x << (n & 0x1F)) & ((n-32) >> 31);
}

If the architecture supports conditional instructions like x86 or ARM then the following way may be faster

return n < 32 ? x << n : 0;

On a 64-bit platform you can made this even simpler by shifting in a 64-bit type and then mask. Some 32-bit platforms like ARM does support shifting by 32 so this method is also efficient

return ((uint64_t)x << (n & 0x3F)) & 0xFFFFFFFFU;

You can see the output assembly here. I don't see how it can be improved further

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

Javascript bit shift to 32 bits

From Dev

How to declare a list of 32 bit binary numbers and shift in Python?

From Dev

how to extract the 4 bytes of a 32bit int in lua

From Dev

How to get the first 11 bits of a 32 bit int with ctypes

From Dev

How to split an unsigned long int (32 bit) into 8 nibbles?

From Dev

2 bit right shift of a 32 bit unsigned integer

From Dev

Bit twiddling to get sign bit of 32 bit int

From Dev

8 bit int vs 32 bit int on a 32 bit architechture (GCC)

From Dev

Int overflow on 32-bit systems

From Dev

constructing 32 bit unsigned int in c

From Dev

Python - Generate a 32 bit random int with arguments

From Dev

sizeof(int*) in 32-bit compatibility mode

From Dev

GPGS Started Crashing on iOS 32bit devices Again

From Dev

Will an int be 32bit and a long 64bit regardless of whether the system is 32 or 64 bit?

From Dev

Will an int be 32bit and a long 64bit regardless of whether the system is 32 or 64 bit?

From Dev

Convert one 32bit float number into two 16bit uint number and then convert back to that 32bit float again

From Dev

Converting 16 bit unsigned int array to 32 bit float array

From Dev

Unsigned int from 32 bit to 64bit OS

From Dev

Convert 11 bit hex value to a signed 32 bit int

From Dev

Circular shift Int32 digits using C#

From Dev

How to combine 4 uint32_t ints into a whole 128 bit int and return

From Dev

C# How to Remove leading 0's from 32bit int

From Dev

Modulo 7 on 64 bit integer using shift and add (32 bit works but 64 doesn't)

From Dev

How to create Int32 through UnsafePointer<Int32>?

From Dev

How to know the source of Ubuntu 64 or 32 bit?

From Dev

C - How to check if 8 bits are in 32 bit?

From Dev

How to detect if client system is 32 or 64 bit?

From Dev

How to create 32 bit mask in Java

From Dev

How to look for a registry key? 32/64 bit

Related Related

  1. 1

    Javascript bit shift to 32 bits

  2. 2

    How to declare a list of 32 bit binary numbers and shift in Python?

  3. 3

    how to extract the 4 bytes of a 32bit int in lua

  4. 4

    How to get the first 11 bits of a 32 bit int with ctypes

  5. 5

    How to split an unsigned long int (32 bit) into 8 nibbles?

  6. 6

    2 bit right shift of a 32 bit unsigned integer

  7. 7

    Bit twiddling to get sign bit of 32 bit int

  8. 8

    8 bit int vs 32 bit int on a 32 bit architechture (GCC)

  9. 9

    Int overflow on 32-bit systems

  10. 10

    constructing 32 bit unsigned int in c

  11. 11

    Python - Generate a 32 bit random int with arguments

  12. 12

    sizeof(int*) in 32-bit compatibility mode

  13. 13

    GPGS Started Crashing on iOS 32bit devices Again

  14. 14

    Will an int be 32bit and a long 64bit regardless of whether the system is 32 or 64 bit?

  15. 15

    Will an int be 32bit and a long 64bit regardless of whether the system is 32 or 64 bit?

  16. 16

    Convert one 32bit float number into two 16bit uint number and then convert back to that 32bit float again

  17. 17

    Converting 16 bit unsigned int array to 32 bit float array

  18. 18

    Unsigned int from 32 bit to 64bit OS

  19. 19

    Convert 11 bit hex value to a signed 32 bit int

  20. 20

    Circular shift Int32 digits using C#

  21. 21

    How to combine 4 uint32_t ints into a whole 128 bit int and return

  22. 22

    C# How to Remove leading 0's from 32bit int

  23. 23

    Modulo 7 on 64 bit integer using shift and add (32 bit works but 64 doesn't)

  24. 24

    How to create Int32 through UnsafePointer<Int32>?

  25. 25

    How to know the source of Ubuntu 64 or 32 bit?

  26. 26

    C - How to check if 8 bits are in 32 bit?

  27. 27

    How to detect if client system is 32 or 64 bit?

  28. 28

    How to create 32 bit mask in Java

  29. 29

    How to look for a registry key? 32/64 bit

HotTag

Archive