Thread: Pointer arithmetic

  1. #1
    Registered User
    Join Date
    Mar 2007
    Posts
    2

    Pointer arithmetic

    If any of you have viewed the Sun microsystems fdlibm source this code might look familiar. I'm porting it around but the only trouble is I'm unsure exactly what this little snippit does:

    Code:
    double a = 24.364536457; // Some number, doesn't really matter
    int b = *(1 + (int *)&a);
    The literal translation of this code is obvious, it just takes the address of the double and shifts it by one byte then dereferences it. This supposedly gets the high order bits of the double. I'm wondering if anyone has a more friendly way of doing this. The confusion for me is that doubles are stored in memory in a way that is compiler specific yet this code is portable. Any takers?

  2. #2
    Deathray Engineer MacGyver's Avatar
    Join Date
    Mar 2007
    Posts
    3,210
    It actually takes the address that the double is at increased by 4 (on a 32-bit system), and then dereferences that address and stores the resulting intenger inside b.

    Pointer arithmetic means that when you add a value to a pointer it moves to the next location that it could point to... Case in point:

    Code:
    int *p;
    ...
    /* assume p points to the beginning of an array greater than or equal to in size to 2 */
    p = p + 1;
    The last line is translated as follows:

    Code:
    p = p + (sizeof(*p) + 1);

  3. #3
    Lean Mean Coding Machine KONI's Avatar
    Join Date
    Mar 2007
    Location
    Luxembourg, Europe
    Posts
    444
    Quote Originally Posted by depietro View Post
    The literal translation of this code is obvious, it just takes the address of the double and shifts it by one byte then dereferences it. This supposedly gets the high order bits of the double. I'm wondering if anyone has a more friendly way of doing this. The confusion for me is that doubles are stored in memory in a way that is compiler specific yet this code is portable. Any takers?
    It doesn't really "shift the address of the double by one". What it does is:

    - it takes the address of the double (double is 8 bytes)
    - it casts that pointer to a (int *) pointer (int is 4 bytes)
    - in increases the (int *) pointer by one, actually adding 4 bytes
    - it dereferences that and stores it as int

    That gets the 4 high order (depends on endianess ?) bytes of the double, just the same as:
    Code:
    int c = *((int *)&a);
    gets the 4 lower order bytes.

  4. #4
    Registered User
    Join Date
    Mar 2007
    Posts
    2
    Thanks for the quick reply, however, I think you misunderstand my question and perhaps my knowledge of pointer arithmetic. As stated in the question, I am very aware of the literal meaning of the code, what I am looking for is a semantic understanding of what it does. The code from sun's fdlibm.h is as follows:

    Code:
    #define __HI(x) *(1+(int*)&x)
    
    #ifdef __STDC__
    	double __ieee754_atan2(double y, double x)
    #else
    	double __ieee754_atan2(y,x)
    	double  y,x;
    #endif
    {  
    	double z;
    	int k,m,hx,hy,ix,iy;
    	unsigned lx,ly;
    
    	hx = __HI(x);
    
    ...
    looking to understand what is found in hx and if I can reproduce the same effect in a different way with bit shifting. This is so I can port it to java.

  5. #5
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    It assumes doubles are stored in 8 bytes, and that code gets the most significant 32 bits.

    It's the same as
    Code:
    union {
        double z;
        unsigned int w[2];
    } var;
    
    var.z = myDouble;
    hx = var.w[1];
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  6. #6
    Gawking at stupidity
    Join Date
    Jul 2004
    Location
    Oregon, USA
    Posts
    3,218
    Quote Originally Posted by depietro
    this code is portable.
    Quote Originally Posted by Salem
    It assumes doubles are stored in 8 bytes
    One of these statements is false.
    If you understand what you're doing, you're not learning anything.

  7. #7
    Lean Mean Coding Machine KONI's Avatar
    Join Date
    Mar 2007
    Location
    Luxembourg, Europe
    Posts
    444
    This code should work wherever double is twice the size of an integer, no ?

  8. #8
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by KONI View Post
    This code should work wherever double is twice the size of an integer, no ?
    How is that compatible with "portable?" Clearly it isn't portable to architectures where this statement is false.

  9. #9
    Lean Mean Coding Machine KONI's Avatar
    Join Date
    Mar 2007
    Location
    Luxembourg, Europe
    Posts
    444
    I never said it was portable, I only mentioned the sufficient condition for it to be.

  10. #10
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by KONI View Post
    I never said it was portable, I only mentioned the sufficient condition for it to be.
    So now you're redefining portable to mean only the platforms where your statement is valid? Isn't that a bit tautological?

  11. #11
    Gawking at stupidity
    Join Date
    Jul 2004
    Location
    Oregon, USA
    Posts
    3,218
    brewbuck, are you confusing KONI with depietro?
    If you understand what you're doing, you're not learning anything.

  12. #12
    Lean Mean Coding Machine KONI's Avatar
    Join Date
    Mar 2007
    Location
    Luxembourg, Europe
    Posts
    444
    I'm not redefining portable, since I never ever said that this code was portable. In fact, only depietro said that it was in his first post. Since "portable" means the same to me as it does for everyone, I implicitly said that it wasn't portable and even included the condition for it to run correctly.

  13. #13
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by KONI View Post
    I'm not redefining portable, since I never ever said that this code was portable. In fact, only depietro said that it was in his first post. Since "portable" means the same to me as it does for everyone, I implicitly said that it wasn't portable and even included the condition for it to run correctly.
    Sorry. The comment by "itsme86" quoted two different people, and I didn't notice.

  14. #14
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    > looking to understand what is found in hx and if I can reproduce the same effect in a different way with bit shifting.
    http://en.wikipedia.org/wiki/IEEE_fl...ecision_64_bit
    Depending on whether you machine is big-endian or little endian, it seems you get either the bottom half of all the mantissa bits, or something containing the sign, exponent and most significant matissa bits.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 5
    Last Post: 04-04-2009, 03:45 AM
  2. Problems passing a file pointer to functions
    By smitchell in forum C Programming
    Replies: 4
    Last Post: 09-30-2008, 02:29 PM
  3. Pointers, arithmetic, and order of operation.
    By Aerie in forum C Programming
    Replies: 4
    Last Post: 04-19-2005, 07:35 AM
  4. Replies: 41
    Last Post: 07-04-2004, 03:23 PM