473,385 Members | 2,003 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,385 software developers and data experts.

Reinterpret the bits of a float as unsigned long

For a hash function I want to reinterpret the bits of a float
expression as unsigned long. The normal cast

(unsigned long) float_expression

truncates the float to an (unsigned long) integer.

But this is not the effect I want for a hash function.
With unions my hash function can be implemented:

union {
long unsigned hashvalue;
float floatvalue;
} value;

value.floatvalue = float_expression;

Now

value.hashvalue

contains the reinterpreted bits as intended. But I think a shorter
solution (without assignment or memcpy to a variable) should
be possible.

When I cast first to (void *) and after that to (unsigned long)
the gcc gives me the error:

cannot convert to a pointer type

It seems casting a float to a pointer is prohibited by gcc.

Has anybody an idea to reinterpret the bits of a float as
unsigned long without assignment or memcpy (some sort
of tricky cast).

Greetings Thomas Mertes

Seed7 Homepage: http://seed7.sourceforge.net
Wikipedia: http://en.wikipedia.org/wiki/Seed7
Project page: http://sourceforge.net/projects/seed7

Feb 3 '06 #1
15 6919
<th***********@gmx.at> wrote in message
news:11**********************@g47g2000cwa.googlegr oups.com...
For a hash function I want to reinterpret the bits of a float
expression as unsigned long. The normal cast

(unsigned long) float_expression

truncates the float to an (unsigned long) integer.

But this is not the effect I want for a hash function.
With unions my hash function can be implemented:

union {
long unsigned hashvalue;
float floatvalue;
} value;

value.floatvalue = float_expression;

Now

value.hashvalue

contains the reinterpreted bits as intended. But I think a shorter
solution (without assignment or memcpy to a variable) should
be possible.

When I cast first to (void *) and after that to (unsigned long)
the gcc gives me the error:

cannot convert to a pointer type

It seems casting a float to a pointer is prohibited by gcc.

Has anybody an idea to reinterpret the bits of a float as
unsigned long without assignment or memcpy (some sort
of tricky cast).


If float_expression is a lvalue, you can write:

*(unsigned long *)&(float_expression)

but that is fraught with peril.

P.J. Plauger
Dinkumware, Ltd.
http://www.dinkumware.com
Feb 3 '06 #2
"P.J. Plauger" <p...@dinkumware.com> wrote:
If float_expression is a lvalue, you can write:

*(unsigned long *)&(float_expression)

but that is fraught with peril.


Thank you for your help. But the float_expression is not
granted to be an lvalue. Do you have an rvalue solution as well?

Greetings Thomas Mertes

Seed7 Homepage: http://seed7.sourceforge.net
Wikipedia: http://en.wikipedia.org/wiki/Seed7
Project page: http://sourceforge.net/projects/seed7

Feb 3 '06 #3
th***********@gmx.at wrote:
"P.J. Plauger" <p...@dinkumware.com> wrote:
If float_expression is a lvalue, you can write:

*(unsigned long *)&(float_expression)

but that is fraught with peril.


Thank you for your help. But the float_expression is not
granted to be an lvalue. Do you have an rvalue solution as well?

You can get at the underlying representation by casting to an
unsigned char* and work your way through that.
unsigned char *raw = (unsigned char *)&floatval;
Fiddle with raw[0] to raw[sizeof(float)-1] (e.g build an
unsigned long from the bits..)
Feb 3 '06 #4


th***********@gmx.at wrote On 02/03/06 13:20,:
"P.J. Plauger" <p...@dinkumware.com> wrote:

If float_expression is a lvalue, you can write:

*(unsigned long *)&(float_expression)

but that is fraught with peril.

Thank you for your help. But the float_expression is not
granted to be an lvalue. Do you have an rvalue solution as well?


You'll have to store the value in an lvalue first.
Consider: "Reinterpreting the bits" is an operation on
the representation of a value, not on the value itself.
A value doesn't "get represented" (in any C-accessible
sense) until it's stored; a value "in flight" in an
expression is just a naked value, without a representation
that C has any way to talk about.

Don't overlook PJP's closing remark, by the way.
When he says "fraught with peril" he doesn't mean there's
only one peril; he means there are multiple perils. Just
off-hand and without working hard, I can think of three.

--
Er*********@sun.com

Feb 3 '06 #5
<th***********@gmx.at> wrote in message
news:11*********************@g43g2000cwa.googlegro ups.com...
"P.J. Plauger" <p...@dinkumware.com> wrote:
If float_expression is a lvalue, you can write:

*(unsigned long *)&(float_expression)

but that is fraught with peril.


Thank you for your help. But the float_expression is not
granted to be an lvalue. Do you have an rvalue solution as well?


No.

P.J. Plauger
Dinkumware, Ltd.
http://www.dinkumware.com
Feb 3 '06 #6
Eric Sosman <Eric.Sos...@sun.com> wrote:
You'll have to store the value in an lvalue first.
Consider: "Reinterpreting the bits" is an operation on
the representation of a value, not on the value itself.


Reinterpreting a float expression as unsigned long
does absolutely nothing with the value. In the machine
code you would see nothing at this place.

The C compiler (gcc) must be convinced to accept a
"do nothing" cast. Normal casts from float to (long) integers
are defined as trunc operations. But in my case nothing
should be done with the value. From the logical point of view
a "do nothing" operation does not need an lvalue.

The x86 gcc has the same size for float and unsigned long:

sizeof(float) = 4
sizeof(unsigned long) = 4

therefore all float values map to unsigned long values.
Just the compiler must be convinced.

Any ideas?

Greetings Thomas Mertes

Seed7 Homepage: http://seed7.sourceforge.net
Wikipedia: http://en.wikipedia.org/wiki/Seed7
Project page: http://sourceforge.net/projects/seed7

Feb 3 '06 #7


th***********@gmx.at wrote On 02/03/06 14:55,:
Eric Sosman <Eric.Sos...@sun.com> wrote:

You'll have to store the value in an lvalue first.
Consider: "Reinterpreting the bits" is an operation on
the representation of a value, not on the value itself.

Reinterpreting a float expression as unsigned long
does absolutely nothing with the value. In the machine
code you would see nothing at this place.


I think we've said the same thing in different words:
Reinterpretation is about representations, not about
values.
The C compiler (gcc) must be convinced to accept a
"do nothing" cast. Normal casts from float to (long) integers
are defined as trunc operations.
That's why the compiler must *not* be convinced to
change its behavior. It is doing what the language
definition requires.
But in my case nothing
should be done with the value. From the logical point of view
a "do nothing" operation does not need an lvalue.
It needs a representation to be able to reinterpret.
C is unable to "see" representations that do not reside
in lvalues, and this "blindness" is the source of some of
C's power to optimize. For example, `x++' is defined as
having the same effect as `x += 1', yet on many systems
there will not even *be* a `1' anywhere in the compiled
code of `x++'. That `1' has no representation, yet it
is a value nonetheless.
The x86 gcc has the same size for float and unsigned long:

sizeof(float) = 4
sizeof(unsigned long) = 4

therefore all float values map to unsigned long values.
Just the compiler must be convinced.
That takes care of one of the three perils I thought
of. Another is alignment: the fact that two objects have
the same size does not imply that they have the same
alignment requirements -- and it's not hard to imagine a
machine whose integer and F-P units connect to memory in
different fashions (one word: "coprocessor").

The third peril is more subtle: Some F-P schemes can
use different bit combinations for the same value. In
IEEE F-P, for example, -0 and +0 are numerically equal but
have different representations. Since you want to use the
reinterpreted-as-long bits as a hash code, you could find
yourself with different hash codes for equal keys. Your
hash table would work fine *most* of the time ...

And, of course, once you've verified that all three
perils are either non-perilous or can be avoided on your
current machine, you or someone else will decide to use
the code on a different system -- where, all of a sudden,
`long' is eight bytes and requires eight-byte alignment.
The peril of avoiding peril rather than dealing with it
is that avoidance is local and avoidance is temporary ...
Any ideas?


One thought is that using a floating-point value as a
hash key is a dodgy business at best. The problem isn't
so much with the value itself, but with the computation
that produces it: if you insert an item using `0.0f' as a
key and then try to retrieve it with `(float)cos(3.14159)'
you are quite likely to be disappointed. Discrepancies
as small as one part in four million are enough to bollix
your hash code and send the search to the wrong spot in
the table.

Are you sure you want to do this? What larger problem
are you trying to solve by building this hash table?

--
Er*********@sun.com

Feb 3 '06 #8


Eric Sosman wrote On 02/03/06 16:04,:

[...] if you insert an item using `0.0f' as a
key and then try to retrieve it with `(float)cos(3.14159)'
you are quite likely to be disappointed. [...]


Never do trig on an empty stomach. That should
have been `(float)sin(3.14159)', of course.

--
Er*********@sun.com

Feb 3 '06 #9
Eric Sosman <Eric.Sos...@sun.com> wrote
Are you sure you want to do this? What larger problem
are you trying to solve by building this hash table?


The Seed7 programming language supports hashtables for
all index types that provide a 'hashCode' and a 'compare'
function. If you use the type

hash [string] float

the 'hashCode(string)' and 'compare(string, sting)' functions
are used to implement this hashtable. When the baseType of
the hashtable (float in this examle) has also an 'hashCode'
and an 'compare' function the type 'hash [string] float' can
be flipped (the values are turned to keys and the keys into values).
the result type of the flipped hashtable is

hash [float] array string

When your 'hash [string] float' table maps mountain names to
their height. It is possible to write a list of mountains sorted by
height with:

mountainsWithHeight := flip(HeightOfMountain);
for height range sort(keys(mountainsWithHeight)) do
for mountainName range sort(mountainsWithHeight[height]) do
writeln(mountainName rpad 20 <& " " <& height);
end for;
end for;

This example is similar to the wordcnt.sd7 example in the
Seed7 package.

The Seed7 interpreter uses unions to store all object values.
The 'float to unsigned long' cast is done with unions there.
The Seed7 compiler produces a C program where the hashCode
function could just be a "do nothing" cast from float to
unsigned long.

Greetings Thomas Mertes

Seed7 Homepage: http://seed7.sourceforge.net
Wikipedia: http://en.wikipedia.org/wiki/Seed7
Project page: http://sourceforge.net/projects/seed7

Feb 3 '06 #10
In article <ds**********@news1brm.Central.Sun.COM>,
Eric Sosman <Er*********@sun.com> wrote:
Eric Sosman wrote On 02/03/06 16:04,:

[...] if you insert an item using `0.0f' as a
key and then try to retrieve it with `(float)cos(3.14159)'
you are quite likely to be disappointed. [...]


Never do trig on an empty stomach. That should
have been `(float)sin(3.14159)', of course.


It is the floating point that got you into trouble, because

(int) sin(3.14159) == (int) cos (3.14159) :-)
Feb 3 '06 #11


th***********@gmx.at wrote On 02/03/06 17:40,:
Eric Sosman <Eric.Sos...@sun.com> wrote

Are you sure you want to do this? What larger problem
are you trying to solve by building this hash table?


[something about a language called Seed7, which supports
hash tables using all manner of weird keys]

When your 'hash [string] float' table maps mountain names to
their height. It is possible to write a list of mountains sorted by
height with:

mountainsWithHeight := flip(HeightOfMountain);
for height range sort(keys(mountainsWithHeight)) do
for mountainName range sort(mountainsWithHeight[height]) do
writeln(mountainName rpad 20 <& " " <& height);
end for;
end for;


Seems like either (1) Seed7 hash tables allow
duplicate keys, or (2) no two mountains can have
the same height ...

--
Er*********@sun.com

Feb 3 '06 #12
On 3 Feb 2006 14:40:14 -0800, th***********@gmx.at wrote:
Eric Sosman <Eric.Sos...@sun.com> wrote
Are you sure you want to do this? What larger problem
are you trying to solve by building this hash table?


The Seed7 programming language supports hashtables for


Thanks for the unsolicited advertisement. Not. Your post is not only
off-topic in c.l.c., but has no relevance to the OP's question.

--
Al Balmer
Sun City, AZ
Feb 4 '06 #13
Eric Sosman <Eric.Sos...@sun.com> wrote:
Seems like either (1) Seed7 hash tables allow
duplicate keys, or (2) no two mountains can have
the same height ...


(3) Flipping a hashtable creates a hashtable with
arrays of formerKeys as elements:

hash [formerValue] array formerKey

Therefore you need two for-loops to write the output
in the example.

Greetings Thomas Mertes

Seed7 Homepage: http://seed7.sourceforge.net
Wikipedia: http://en.wikipedia.org/wiki/Seed7
Project page: http://sourceforge.net/projects/seed7

Feb 4 '06 #14
Eric Sosman wrote:
A value doesn't "get represented" (in any C-accessible
sense) until it's stored; a value "in flight" in an
expression is just a naked value, without a representation
that C has any way to talk about.


I disagree.

/* BEGIN new.c */

#include <stdio.h>

int main(void)
{
switch (-1 & 3) {
case 1:
puts("signed magnitude");
break;
case 2:
puts("ones's complement");
break;
default:
puts("two's complement");
break;
}
return 0;
}

/* END new.c */
--
pete
Feb 4 '06 #15
pete wrote:
Eric Sosman wrote:

A value doesn't "get represented" (in any C-accessible
sense) until it's stored; a value "in flight" in an
expression is just a naked value, without a representation
that C has any way to talk about.

I disagree.
[counterexample with `&' snipped]


Good point. Not helpful to the O.P., though,
who wants access to the representation of a `float'.

--
Eric Sosman
es*****@acm-dot-org.invalid
Feb 4 '06 #16

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: sarmin kho | last post by:
Hi Pythoners, When it is an integer number, what is the range of the integer number and long integer number?? do we have typecasting of 8bits or 16bits signed and unsigned number in python? ...
14
by: Ben | last post by:
Hi, I need to write some data types into an array of unsigned chars. These are basically "signals" within a message, so each signal will have a start bit and a length. The signals will also...
2
by: Goran | last post by:
Hi! I need to convert from a unsigned char array to a float. I don't think i get the right results in the program below. unsigned char array1 = { 0xde, 0xc2, 0x44, 0x23}; //I'm not sure in...
40
by: aku | last post by:
I'm looking for the absolute fastest way to count the nr of bits that are set to "1" in a string. Presumably I then first need the fastest way to do this in a byte. I think this is it, but...
7
by: sathyashrayan | last post by:
Group, Following function will check weather a bit is set in the given variouble x. int bit_count(long x) { int n = 0; /* ** The loop will execute once for each bit of x set,
36
by: Digital Puer | last post by:
Hi, suppose I have an unsigned long long. I would like to extract the front 'n' bits of this value and convert them into an integer. For example, if I extract the first 3 bits, I would get an int...
6
by: karthi | last post by:
hi, I need user defined function that converts string to float in c. since the library function atof and strtod occupies large space in my processor memory I can't use it in my code. regards,...
22
by: Bill Reid | last post by:
I just noticed that my "improved" version of sscanf() doesn't assign floating point numbers properly if the variable assigned to is declared as a "float" rather than a "double". (This never...
4
by: rkmr.em | last post by:
hi i want to send unsigned 32 bit integer to socket, and looking for something equivalent to this method... http://livedocs.adobe.com/flex/2/langref/flash/net/Socket.html#writeUnsignedInt() ...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.