I use= these values can be used as unique identifier in a table.
OK. This information is necessary because there is no possibility to convert a pointer into a floating-point number with any meaningful value; the floating-point number will have a meaningless value in any way.
There are two possibilities to convert a pointer to a (meaningless) floating-point value but in both cases you are not guaranteed that two floating-point numbers are unique for two different pointers!
Possibility 1:
Convert the pointer to an integer and the integer to floating-point:
phy_address = (double)(uintptr_t)p;
However as Weather Vane already mentioned in his comment double
values have a limited precision.
The integer values (addresses) 1234567890123456780 and 1234567890123456790 would both be rounded to 1234567890123456768.0.
Possibility 2:
Because both double
and pointers are 64 bits wide you could generate a floating-point number that has the same bits as the pointer:
union {
void *p;
double d;
} u;
...
u.p = p;
phy_address = u.d;
However there are numbers (for example the 0
) which have two different representations in the double
data type. This means that there are two different combinations of bits (and therefore two different addresses) that will generate the same number.
For this reason there cannot be any method to convert a 64-bit value into a double
value resulting in an unique double
value: The data type double
has less than 2^64 different values!
And it is even worse:
There are special values - so called "NaN" values. And there are a lot of them!
I just did the following test:
// Write a "NaN" value to a
...
b = a;
if(a == b) puts("equal");
if(a != b) puts("not equal");
// Check if a and b still contain the same value
...
... and I get the result "not equal" although the check at the end says that a
and b
still contain the same value!
Depending on your environment some NaN values (so-called "signalling NaN" values) might even cause your program to crash!
Conclusion
Personally I would never use floating-point data types as "unique identifier".
In your case I would directly use void *
as "unique identifier". If this is not possible I would use some 64-bit integer data type as "Stuart" already suggested in his answer.