-1

I know how pointers work, but I'm having some trouble understanding this cast with pointers.

float f;
scanf("%f", &f);
unsigned int x = *(unsigned int*)&f;

Can someone explain me how this works?

E_net4
  • 27,810
  • 13
  • 101
  • 139
  • 2
    Strictly speaking it breaks strict aliasing and invokes *undefined behavior* - which means it doesn't work – UnholySheep Apr 19 '20 at 20:59
  • The code is invalid. See: https://stackoverflow.com/questions/44512402/casting-float-to-int-pointer-and-back-to-float – kaylum Apr 19 '20 at 21:00
  • 1
    @SaymoinSam that is incorrect, `unsigned int x = (unsigned int)f` does something completely different (namely it casts the floating point number and truncates). The pointer cast would reinterpret the bytes of the floating point number as an unsigned integer – UnholySheep Apr 19 '20 at 21:02
  • Sorry my bad... – Saadi Toumi Fouad Apr 19 '20 at 21:06

2 Answers2

7
unsigned int x = *(unsigned int*)&f;

basically means "take the address of f, pretend it's an address to an unsigned int instead of a float, and dereference the result.

It's basically attempting to copy the bits from f into x without any type conversion.

As mentioned in the comments, this breaks a rule known as the "strict aliasing rule", and the behavior on doing so is undefined. This may work as expected. It may not.

John Bode
  • 119,563
  • 19
  • 122
  • 198
0

Just an addition to @John Bode's answer, try (and maybe debug) the following code to make things clear.

It's like, looking at the same bit pattern;

  1. wearing a float set of eyeglasses,
  2. wearing an int set of eyeglasses.
#include <stdio.h>
#include <stdlib.h>

void printBits(int k) {
    char bitStr[33];

    // put a string terminator at end of string
    bitStr[32] = '\0';

    for (int i = 0; i < 32; i++) {
        if (k & 1) {
            bitStr[31 - i] = '1'; // if 32nd bit is 1
        }
        else {
            bitStr[31 - i] = '0'; // if 32nd bit is 0
        }

        k = k >> 1; // shift all bits 1 bit right, dropping the right most (32nd) bit
    }

    printf("%s", bitStr);
    return;
}

int main()
{
    float f = 1.0f;
    int i = *(int *)&f;

    printf("bit pattern ");
    printBits(*(int *)&f);
    printf(" equals to %f in float\n", f);

    printf("bit pattern ");
    printBits(i);
    printf(" equals to %d in integer\n", i);

    return 0;
}
ssd
  • 2,340
  • 5
  • 19
  • 37