1

Is there a way to convert a float to just a bit-pattern so that I can do things like

int mantissa = 0u;
int exponent = 0u;    

mantissa = myFloat>>11;
exponent = myFloat>>23;

Attempting to do this generates a compile-time error:

main.c:24:11: error: invalid operands to binary >> (have 'float' and 'int')
mantissa = (myFloat>>11); 

main.c:25:12: error: invalid operands to binary >> (have 'float' and 'int')
exponent = (myFloat>>23);

Is there a way to do this? Converting to int will give the bit pattern of the signed int version, so I don't want to do that, I want the bits of the original float saved into an unsigned int. How can I best do this

Zaya
  • 316
  • 4
  • 14
  • 1
    Relevant: https://stackoverflow.com/questions/39336542/quickly-find-the-integer-part-of-the-base-2-logarithm – rici Feb 13 '18 at 16:41
  • 1
    What are you trying to do? What do you intend to achieve by shifting a floating point number right by 11 or 23 bits? – AAT Feb 13 '18 at 16:41
  • I need to isolate just the mantissa and just the exponent parts for a school thing. ( see [this](https://en.wikipedia.org/wiki/Single-precision_floating-point_format#IEEE_754_single-precision_binary_floating-point_format:_binary32) ) I thought this would be a clever way to do it, but at this point I could have just brute forced a crappy solution – Zaya Feb 13 '18 at 16:43
  • 1
    Isolating the significand (the preferred term; “mantissa” is a legacy term) and exponent is better done with the `frexp` function in `math.h`. – Eric Postpischil Feb 13 '18 at 16:49
  • @AAT for reference, there are legitimate purposes for manipulating floats at a low level. For instance, incrementing to the next representable float value. – spectras Feb 13 '18 at 17:10
  • Be careful with this… the floating point implementation doesn't have to conform to IEEE 754/IEC 60559, it could be anything. If it is 754 the compiler should define a `__STDC_IEC_559__` macro. – nemequ Feb 13 '18 at 18:01
  • @spectras: fortunately, there is a portable representation-independent standard library function for that: `nextafter`. – rici Feb 13 '18 at 18:30
  • @spectras Naturally there are, and I have done this myself when necessary. I never said there are no such legitimate purposes: but they are pretty niche. As the OP has now explained what outcome he is after then the quality of answers he gets will be better, rather than leaving us to explore the full problem space of bitwise manipulation of floating point representations... see Eric Postpischil's response. – AAT Feb 14 '18 at 16:20

1 Answers1

2

the typical solution is something like this:

typedef union {
  unsigned int i;
  float f;
} u;
u u1;
u1.f = 0.341; // your float here
unsigned int x = u1.i; // converted to uint

This legal in C99 and does not invoke UB (which is good), or violate strict aliasing rules.

C_Elegans
  • 1,113
  • 8
  • 15
  • Still will get UB if these manipulations result in trap representation. – Eugene Sh. Feb 13 '18 at 16:44
  • 1
    It does not invoke undefined behavior **if** `float` and `int` are the same size in the C implementation in which it is used, if the `float` value used is never a trap representation in `int`, et cetera. Generally, one ought to use unsigned types for working with bits. – Eric Postpischil Feb 13 '18 at 16:48
  • 1
    OP requested " want the bits of the original float saved into an unsigned int.". Recommend `unsigned` over `int` in this case. – chux - Reinstate Monica Feb 13 '18 at 17:07