• A Great friend to the HardForum with a great kid that he is trying to get a scholorship to continue his schooling. Please give hime a vote! Only 24 hours left! Thanks.
    If you have an VOTE FOR KEENAN!

Quick question on C types

Joined
Oct 26, 2005
Messages
2,340
Is there a simpler way than the following code to force C to assign the same bit pattern to a different type? Casts between ints, chars and pointers seem to work like this, until you bring floats into the mix.
Code:
float f = 7.7;
int n = *(int *)(void *)&f;

Could've sworn I saw a more straightforward way of going about it earlier today (at least, I'm pretty sure I understood the example I saw, and I only just got this void type puzzled out).
 
I'm curious why you would want to do this...

Perhaps you were thinking of unions?

Code:
typedef union
{
   float   f;
   int32_t i;
} FloatInt32OverlayType;

...
FloatInt32OverlayType variable;

variable.f = 7.7;
n = variable.i;
 
I can't personally think of an "easier" way.

One thing that I did once (when I was new at C :)) was enumerate all possible floats: you can use the above trick to convert an int into a float, and then print it via printf(). What can I say? I'm easily amused.
 
If you want to copy the bits exactly, I would use something like memcpy().

http://www.cplusplus.com/reference/clibrary/cstring/memcpy.html

So:

float f = 7.7;
int n;

memcpy(&n, &f, 2);

This is really bad code though. First, I think (not completely sure) that the size of float varies across systems. Some systems use 4 bytes for storing floats, others use 8 bytes, making them the same as a 8-byte double. Second, you cannot just copy bits like that. Float stores a magnitude as well as the exponent and also a sign bit. Integers only have sign and magnitude. So you cannot just do a straight copy of the bits, you need to translate.

n = f; should place the value "7" in n, truncating the decimal without rounding up.
 
I'm curious why you would want to do this...
Well, the code I saw was extracting the sign bit to avoid a (potentially more expensive) floating point comparison. I don't actually need it for anything myself, but I'm trying to learn C and I'm just looking into little details like this to try and get a clearer picture of the language.

Perhaps you were thinking of unions?
That was quite possibly it :) . Thanks.

One thing that I did once (when I was new at C :)) was enumerate all possible floats...
Whoa... All 4294967296 of them? :D

If you want to copy the bits exactly, I would use something like memcpy().
That might have been it too. In any case, it might be a better solution than pointer cast / union tricks, if only for readability's sake.

I think you're right about float length being (potentially) machine dependent. Pretty sure int is the same - to make sure you don't overshoot n's allocation, I guess you'd need something like
Code:
float f = 7.7;
int *n = malloc(sizeof(float));

memcpy(n, &f, sizeof(float));

Second, you cannot just copy bits like that. Float stores a magnitude as well as the exponent and also a sign bit.
Yeah, I know it's going to give me garbage if I actually try to use it as an integer. I was thinking about this more for the purposes of bit-level manipulation (extracting sign/exponent/mantissa fields from a float, for example).
 
The other issue that I forgot to mention is endianness (x86 is different than Sun SPARC for example). Some systems are big endian and some are small endian. So you not only need to worry about the size of the variables represented, but also how the bits are stored.

I have not had much experience with "bit thrashing" but you can get into a lot of trouble doing it. That is one of the reasons of why it cannot be done in more modern languages like Java and C#. Then again, performance is probably the only reason why you are writing in C.
 
IEEE defines the FP standard, Wiki link, they are fixed (other than endian).

The size of integers can vary across systems, but almost any desktop or server system today allows you to define a 32 bit int, be it as long, int or int32.
 
FreiDOg said:
The size of integers can vary across systems, but almost any desktop or server system today allows you to define a 32 bit int, be it as long, int or int32.

As a side note, the C99 standard defines fixed-size integer types via stdint.h. stdint.h typedefs int8_t, uint8_t, and the same for 16, 32, and 64 bits. So should someone need exact-size integers, stdint.h just gives them to the programmer, portable and all wrapped up with a bow on top. :)

SNYP40A1 said:
The other issue that I forgot to mention is endianness (x86 is different than Sun SPARC for example). Some systems are big endian and some are small endian. So you not only need to worry about the size of the variables represented, but also how the bits are stored.

That is true, especially if one were to overlay an array or record of some sort on top of anything. However, I would also like to point out that if someone's going after a specific bit or range of bits, and if it were done mathematically with bitwise operations, the same code could work on both endians. (HINT, HINT, OP. ;) )
 
Back
Top