1. 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. 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. Originally Posted by depietro
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. 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. 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];```

6. Originally Posted by depietro
this code is portable.
Originally Posted by Salem
It assumes doubles are stored in 8 bytes
One of these statements is false.

7. This code should work wherever double is twice the size of an integer, no ?

8. Originally Posted by KONI
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. I never said it was portable, I only mentioned the sufficient condition for it to be.

10. Originally Posted by KONI
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. brewbuck, are you confusing KONI with depietro?

12. 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. Originally Posted by KONI
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. > 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.