3

I am trying to figure out the algorithm to this but all I get with google is doing it with casting. I need to know the details.

So if we have a float x and want to return its binary representation what do we need to do?

I know we need to return the float if its NaN or a infinity but otherwise what are the steps?

EDIT

The function takes in an unsigned int, to be used as if it was a float, and then return the integer the number represents. I cannot use casting, just conditionals and bit-wise operators.

Jace
  • 33
  • 1
  • 4
  • 1
    What do you mean by "binary representation"? Like 2.25 written as 10.01, or the internal representation of the float? The internal representation is typically in IEEE format, i.e. the value is 1.[mantissa]^(exponent), and only the mantissa and exponent are stored. You can get the actual 1s and 0s by just copying the memory into an int (or use a union) and printing the int. – Adam Sep 13 '11 at 03:54
  • @Adam, this is probably just a small terminology mistake on your end, but casting a `float` to an `int` "just" truncates the real part of the number. You need some (rather concise) pointer magic to get the bit pattern of a float. I agree with everything else though. – zneak Sep 13 '11 at 03:55
  • See http://stackoverflow.com/questions/2376915/how-to-print-out-the-memory-contents-of-a-variable-in-c – Alok Singhal Sep 13 '11 at 04:06
  • About your edit... That's not always possible, since the float might not be an integer. Can you clarify? – Mysticial Sep 13 '11 at 04:09
  • If its not an integer, I assume its either NaN or infinity. In that case I return a special sequence. – Jace Sep 13 '11 at 04:11
  • @Jace: Study carefully how single-precision is represented. Look at where the exponent is, where the mantissa is. From that you can use a couple of masks and bit-shifts to get your answer. A little extra logic is needed to check if the number is an integer or not. – Mysticial Sep 13 '11 at 04:37
  • "If its not an integer, I assume its either NaN or infinity." So you'll never see `2.5`? – Keith Thompson Sep 13 '11 at 05:07
  • Possible duplicate of [Casting float to int (bitwise) in C](https://stackoverflow.com/questions/12342926/casting-float-to-int-bitwise-in-c) – Björn Lindqvist Jan 21 '18 at 15:25

3 Answers3

4

Alternatively, use a union:

typedef union 
{
    float f_;
    int   i_;
} FloatBits;

FloatBits fb;

fb.f_ = 1.5;

Then fb.i_ contains the float mapped onto an int to allow extraction of the bits. Again, usual assunptions about the size of types - you can verify these using sizeof.

Using this approach, you can play with setting the bits in fb.i_ directly and seeing them mapped back into the float.

Keith
  • 6,756
  • 19
  • 23
  • I cant use language constructs. I will probably need a while loop or something but cant figure it out... – Jace Sep 13 '11 at 04:19
  • 1
    Though most compilers make this behave as you describe, this access is technically [undefined behavior](http://stackoverflow.com/questions/252552/unions-in-c). – Mark Elliot Sep 13 '11 at 04:22
  • @Mark Elliot: In recent versions of the standard, this is NOT undefined behavior, but rather gives implementation defined values. This is the recommended way to get the bit pattern of a float. On the other hand, achieving the same trick through a pointer cast technically *is* still wrong. – Dietrich Epp Sep 13 '11 at 04:37
  • @Dietrich Epp. Thanks for the note. I suspected this, thanks for the confirmation. Implementation defined is all we are after. – Keith Sep 13 '11 at 04:40
1

The float number in c programming language follows the IEEE Standard for Floating-Point Arithmetic (IEEE 754).

You can convert float to int with the code

int i = *(int *)&f; // f is the float variable you want to convert

And then interpret the int yourself according to IEEE 754 standard.

Summer_More_More_Tea
  • 12,740
  • 12
  • 51
  • 83
  • 4
    C does not specify the floating point format, that's platform dependent, though almost all modern platforms do in fact use IEEE754. ([more details](http://stackoverflow.com/questions/2724359/are-there-any-modern-platforms-with-non-ieee-c-c-float-formats)) – Mark Elliot Sep 13 '11 at 04:14
  • cant use explicit casting and the input is as an unsigned int to be viewed as a float. – Jace Sep 13 '11 at 04:19
  • @Jace Then convert it yourself according to the standard. :-) You should convince yourself you can achieve it by only condition statements and bit operations. – Summer_More_More_Tea Sep 13 '11 at 04:28
  • 2
    This violates strict aliasing and is not recommended. Use unions instead. – Dietrich Epp Sep 13 '11 at 04:39
1

To test if a 32-bit value represents NaN if it were a float you can check if its unsigned value is greater than the representation for infinity.

int n = 
if((n & 0x7FFFFFFF) > 0x7f800000) // is NaN

Removing the sign is required as a NaN can have negative sign bit set to 1 (though NaN is not positive or negative)


If you want to know if a float is NAN, you can use

float f = NAN
if (f != f) // is NAN

To compare with Infinity

float f = INFINITY;
if (f == INFINITY)
Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
  • Note that compilers "could" optimize `f != f` away. – Matthias Apr 23 '18 at 13:54
  • @Matthias Only if for their target, `f != f` is false for all values that a float `f` can have. This is not the case for compilers that claim to provide IEEE 754 arithmetics (most of them), although this is the case for `gcc -ffast-math` (which does not claim to provide IEEE 754 arithmetics). – Pascal Cuoq Apr 30 '18 at 08:44
  • @PascalCuoq idd. for msvc++ /fp:fast. – Matthias Apr 30 '18 at 09:31