Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Shift or divide (C programming)?

Status
Not open for further replies.

misterT

Well-Known Member
Most Helpful Member
I did some tests with gcc compiler. Can you replace divide by 2 operation with right-shift operation?

When you shift negative number to the right, the upper bit is filled with ones. This means that gcc is using arithmetic shift and 2's complement implementation. Looks like you can replace division with shift operation. (signed 16-bit integer)
Code:
decimal: -32768
binary: 1000000000000000

Shift >>1
decimal: -16384
binary: 1100000000000000

Divide by 2
decimal: -16384
binary: 1100000000000000

But, dividing and shifting -1 gives different results. True division is rounded to zero. Bit-shift is truncated down to -1.
Code:
decimal: -1
binary: 1111111111111111

Shift >>1
decimal: -1
binary: 1111111111111111

Divide by 2
decimal: 0
binary: 0000000000000000

Positive numbers behave as expected. No traps here.
Code:
decimal: 32767
binary: 0111111111111111
Shift >>1
decimal: 16383
binary: 0011111111111111

decimal: 32767
binary: 0111111111111111
Divide by 2
decimal: 16383
binary: 0011111111111111

decimal: 1
binary: 0000000000000001
Shift >>1
decimal: 0
binary: 0000000000000000

decimal: 1
binary: 0000000000000001
Divide by 2
decimal: 0
binary: 0000000000000000

Of course there is performance difference between shift and true division:
C:
        int16 >>= 1;
000001B2  LDD R24,Y+34        Load indirect with displacement
000001B3  LDD R25,Y+35        Load indirect with displacement
000001B4  ASR R25        Arithmetic shift right
000001B5  ROR R24        Rotate right through carry
000001B6  STD Y+35,R25        Store indirect with displacement
000001B7  STD Y+34,R24        Store indirect with displacement

        int16 /= 2;
00000259  LDD R24,Y+34        Load indirect with displacement
0000025A  LDD R25,Y+35        Load indirect with displacement
0000025B  IN R0,0x3F        In from I/O location
0000025C  CLI         Global Interrupt Disable
0000025D  OUT 0x3E,R29        Out to I/O location
0000025E  OUT 0x3F,R0        Out to I/O location
0000025F  OUT 0x3D,R28        Out to I/O location
00000260  TST R25        Test for Zero or Minus
00000261  BRGE PC+0x02        Branch if greater or equal, signed
00000262  ADIW R24,0x01        Add immediate to word
00000263  ASR R25        Arithmetic shift right
00000264  ROR R24        Rotate right through carry
00000265  STD Y+35,R25        Store indirect with displacement
00000266  STD Y+34,R24        Store indirect with displacement
 
Last edited:
Status
Not open for further replies.

Latest threads

Back
Top