8 Replies - 1757 Views - Last Post: 04 February 2011 - 10:04 PM Rate Topic: -----

#1 yfronto  Icon User is offline

  • New D.I.C Head

Reputation: 5
  • View blog
  • Posts: 30
  • Joined: 03-November 08

Using return value in printf

Posted 29 January 2011 - 11:40 AM

I'm hoping someone might explain this behaviour. I expect my upperBits(int n) function to be returning 4 bytes with 1s for only the first n bits. (1 should give 80000000, 2 should give F0000000, etc).

Here's the code:
#include <stdio.h>

int upperBits(int);

int main(int argv, char **args) {
    int i = 0;
    printf("%x %x\n", upperBits(i), (~0 << (32 + (~i + 1))));
    return 0;
}

int upperBits(int n) {
    return (~0 << (32 + (~n + 1)));
}



The output:
ffffffff 0



The code seems to work for every value except 0. But my bit manipulation seems to work within the printf function. Why should using a function instead of an inline evaluation make a difference here?

Cheers.

Is This A Good Question/Topic? 0
  • +

Replies To: Using return value in printf

#2 ishkabible  Icon User is offline

  • spelling expret
  • member icon





Reputation: 1618
  • View blog
  • Posts: 5,707
  • Joined: 03-August 09

Re: Using return value in printf

Posted 29 January 2011 - 11:59 AM

i think it has to do with the fact that "%x" expects and unsigned integer and your function returns a integer. i haven't tried it, its just what i thought about when i saw it. you also passing an int as well but i don't think that is an issue as 0 is the same for both signed and unsigned .

This post has been edited by ishkabible: 29 January 2011 - 12:00 PM

Was This Post Helpful? 1
  • +
  • -

#3 CTphpnwb  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 2836
  • View blog
  • Posts: 9,741
  • Joined: 08-August 08

Re: Using return value in printf

Posted 29 January 2011 - 12:01 PM

I get the same values for inline and function. Zero included.

i= 0 result:
ffffffff ffffffff

This post has been edited by CTphpnwb: 29 January 2011 - 12:03 PM

Was This Post Helpful? 0
  • +
  • -

#4 r.stiltskin  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 1833
  • View blog
  • Posts: 4,927
  • Joined: 27-December 05

Re: Using return value in printf

Posted 29 January 2011 - 01:31 PM

It works fine for me (gcc 4.4.3):
#include <stdio.h>

int upperBits(int);

int main(int argv, char **args) {
    int i;
    for( i = 0; i < 32; i++ ) {
      printf("%x %x\n", upperBits(i), (~0 << (32 + (~i + 1))));
    }
    return 0;
}

int upperBits(int n) {
    return (~0 << (32 + (~n + 1)));
}



gives
ffffffff ffffffff
80000000 80000000
c0000000 c0000000
e0000000 e0000000
f0000000 f0000000
f8000000 f8000000
fc000000 fc000000
fe000000 fe000000
ff000000 ff000000
ff800000 ff800000
ffc00000 ffc00000
ffe00000 ffe00000
fff00000 fff00000
fff80000 fff80000
fffc0000 fffc0000
fffe0000 fffe0000
ffff0000 ffff0000
ffff8000 ffff8000
ffffc000 ffffc000
ffffe000 ffffe000
fffff000 fffff000
fffff800 fffff800
fffffc00 fffffc00
fffffe00 fffffe00
ffffff00 ffffff00
ffffff80 ffffff80
ffffffc0 ffffffc0
ffffffe0 ffffffe0
fffffff0 fffffff0
fffffff8 fffffff8
fffffffc fffffffc
fffffffe fffffffe


Was This Post Helpful? 0
  • +
  • -

#5 yfronto  Icon User is offline

  • New D.I.C Head

Reputation: 5
  • View blog
  • Posts: 30
  • Joined: 03-November 08

Re: Using return value in printf

Posted 29 January 2011 - 01:45 PM

Thanks, guys. I'm also on gcc 4.4.3. Trying a few options produced different results.
The expected return value of a call to upperBits(0) should be 0 (asking the function to give me a number with 0 leading 1s). The compile options seems to have an impact:

$ gcc -o main -O2 test.c
$ ./main 
0 0
$ gcc -o main -O1 test.c
$ ./main 
ffffffff 0
$ gcc -o main test.c
$ ./main 
ffffffff ffffffff



It's strange that the degree of optimization changes the results, maybe I'll have to look at an assembly dump to see the differences in the bit shifts.

This post has been edited by yfronto: 29 January 2011 - 01:48 PM

Was This Post Helpful? 0
  • +
  • -

#6 Salem_c  Icon User is offline

  • void main'ers are DOOMED
  • member icon

Reputation: 1579
  • View blog
  • Posts: 3,007
  • Joined: 30-May 10

Re: Using return value in printf

Posted 29 January 2011 - 01:56 PM

With an input of 0, you're shifting by 32 bits.

Quote

6.5.7 Bitwise shift operators
1. Syntax

shift-expression:
additive-expression
shift-expression << additive-expression
shift-expression >> additive-expression

2. Constraints
Each of the operands shall have integer type.

3. Semantics
The integer promotions are performed on each of the operands. The type of the result is
that of the promoted left operand. If the value of the right operand is negative or is
greater than or equal to the width of the promoted left operand, the behavior is undefined.

As soon as your program performed an undefined operation, all bets were off.
One common observation of UB is seeing different optimisation levels produce different results.
Was This Post Helpful? 1
  • +
  • -

#7 yfronto  Icon User is offline

  • New D.I.C Head

Reputation: 5
  • View blog
  • Posts: 30
  • Joined: 03-November 08

Re: Using return value in printf

Posted 29 January 2011 - 02:07 PM

Ah, I see. I didn't realize shifting by more than the size of the left operand would cause strange behaviour, I figured I could just keep shifting all the bits out. I'll have to rethink my approach. Thanks all!

Cheers.
Was This Post Helpful? 0
  • +
  • -

#8 ishkabible  Icon User is offline

  • spelling expret
  • member icon





Reputation: 1618
  • View blog
  • Posts: 5,707
  • Joined: 03-August 09

Re: Using return value in printf

Posted 29 January 2011 - 02:48 PM

strange i thought it padded it with zero's if it went over..
this gives me '00'
cout<<(~0u<<284)<<(~0u>>284);

Was This Post Helpful? 0
  • +
  • -

#9 yfronto  Icon User is offline

  • New D.I.C Head

Reputation: 5
  • View blog
  • Posts: 30
  • Joined: 03-November 08

Re: Using return value in printf

Posted 04 February 2011 - 10:04 PM

Forgot to repost my solution. The original goal was to have a function that would provide n leading 1s using only ! ~ & + << >>. Here's what I came up with:

 #include <stdio.h>

int upperBits(int);

int main(int argv, char **args) {
int i;
for(i = 0; i <= 32; i++)
  printf("%x for %i\n", upperBits(i), i);
  return 0;
} 

int upperBits(int n) {
  return ((!!n & 1) << 31) >> (n + (~1 + 1));
}



Thanks for the help.

Cheers.

This post has been edited by yfronto: 04 February 2011 - 10:04 PM

Was This Post Helpful? 0
  • +
  • -

Page 1 of 1