2

I am asked to convert a float number into a 32 bit unsigned integer. I then have to check if all the bits are zero but I am having trouble with this. Sorry I am new to C

This is what I am doing

float number = 12.5;
// copying number into a 32-bit unsigned int
unsigned int val_number = *((unsigned int*) &number);

At this point I'm very confused on how to check if all bits are zero.

I think I need to loop through all the bits but I don't know how to do that.

Marcus Müller
  • 34,677
  • 4
  • 53
  • 94
Vigilante
  • 57
  • 6
  • 3
    *I am asked to convert a float number into a 32 bit unsigned integer* - this needs an exact definition of "convert". – Eugene Sh. Apr 08 '22 at 18:07
  • 3
    every number in your computer is already "in binary". That's how your computer works. – Marcus Müller Apr 08 '22 at 18:09
  • Have a look into bit masking, and bitwise operations. This will help you start or determining the state of the bits. – S3DEV Apr 08 '22 at 18:11
  • 1
    and as Eugene says, what you're doing is *probably* not what you should be doing if your assignment is to **convert**. What you do is more of a *misinterpret the `float` as `unsigned int`* than a conversion. – Marcus Müller Apr 08 '22 at 18:11
  • @MarcusMüller Did you mean *mis*interpret or *re*interpret? :) Not saying it is wrong though – Eugene Sh. Apr 08 '22 at 18:15
  • assignment said "copy", wrong word choice from me – Vigilante Apr 08 '22 at 18:18
  • `unsigned int val_number = *((unsigned int*) &number);` is a strict-aliasing violation and therefore undefined behavior. And it assumes a `float` is the same size as an `unsigned int`, which does not have to be true. – Andrew Henle Apr 08 '22 at 18:19
  • "copy" might be a hint to use `memcpy` from `float` to `unsigned` - this will remove the violation of strict aliasing. – Eugene Sh. Apr 08 '22 at 18:22
  • 1
    my professor just wants us to copy what he did in lecture: "Copy the bits of a and b into 32-bit unsigned integer variables val_a and val_b. You cannot just do an assignment, but rather you’ll need cast the addresses of a and b to type (unsigned int *) and then dereference the addresses" – Vigilante Apr 08 '22 at 18:24
  • 1
    @Vigilante congrats, that will work most of the times, but it *is* an invocation of undefined behaviour. There's no guarantee it works, not even that anything tells you if it doesn't work. – Marcus Müller Apr 08 '22 at 18:26
  • 4
    @Vigilante His suggestion is a direction to violate a certain C rule (that is - strict aliasing rule). You can point it out to him. The safer way would be to use `memcpy`. – Eugene Sh. Apr 08 '22 at 18:27
  • 2
    @Vigilante Your professor's code [violates 6.5p7 of the C 11 standard](https://port70.net/~nsz/c/c11/n1570.html#6.5p7). It is a [strict aliasing violation](https://stackoverflow.com/questions/98650/what-is-the-strict-aliasing-rule) and undefined behavior. If you want to copy bytes like that, you can use `memcpy()`. – Andrew Henle Apr 08 '22 at 18:28
  • Also, by the way, checking whether an IEEE754 is all zero bits doesn't require conversion to anything; a simple `number==0.0f` and a check of the sign (`signbit(number) != 0`) would be all you need. – Marcus Müller Apr 08 '22 at 18:29
  • And if you do approach your professor with this, as @EugeneSh. suggests, and if he replies with something like "But it works", he really doesn't understand C. The best he can say about code like that is, "I haven't observed it to fail **yet**". – Andrew Henle Apr 08 '22 at 18:31
  • @Vigilante In mentioning the _strict aliasing violation_ coding concern, to a _good_ professor, even if they disagree, will look favorable on the potential issue as something a college level person should look into. Programing is really a young science and there is continuing evolvement of best-practices. If the prof dismisses the issue, understand there are many in the real world too stuck in a rut. – chux - Reinstate Monica Apr 08 '22 at 19:11

2 Answers2

3

To copy the bytes of a 32-bit float to an integer, best to copy to an integer type that is certainly 32-bit. unsigned may be less, same or more than 32-bits.

#include <inttypes.h>

float number = 12.5;
uint32_t val_number32;  // 32-bit type
memcpy(&val_number32, &number, sizeof val_number32);

Avoid the cast and assign. It leads to aliasing problems with modern compilers @Andrew.

"... need cast the addresses of a and b to type (unsigned int *) and then dereference the addresses" reflects a risky programing technique.


To test if the bits of the unsigned integer are all zero, simply test with the constant 0.

int bit_all_zero = (val_number32 == 0);

An alternative is to use a union to access the bytes from 2 different encodings.

union {
  float val_f;
  uint32_t val_u;
} x = { .val_f = 12.5f };
int bit_all_zero = (x.val_u == 0);
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
0

Checking if all the bits are zero is equivalent to checking if the number is zero.

So it would be int is_zero = (val_number == 0);

user1113569
  • 3,441
  • 2
  • 14
  • 10
  • 2
    IEEE 754 has a signed zero representation. – Eugene Sh. Apr 08 '22 at 18:14
  • OK, you are talking about the resulting unsigned integer, after the "conversion". – Eugene Sh. Apr 08 '22 at 18:20
  • Why is there a vote down on this? Evaluating `val_number == 0`, after `val_number` has been “converted” from `float` performs the test OP requested, “I then have to check if all the bits are zero.” OP does not ask to test if the `float` has a zero value. – Eric Postpischil Apr 08 '22 at 18:36