简体   繁体   中英

float to int unexpected behaviour

can you please explain the o/p behavior of this program.

int main()
{
  float a = 12.5;
  printf("%d\n", a);
  printf("%d\n", *(int *)&a);
  return 0;
} 

can you please check code at http://codepad.org/AQRlAzkC
why is this output coming ..

You don't want to cast the float pointer to an integer pointer. Floats and integers are not stored the same way and if you do that then there is no conversion that will take place, and thus you will get garbage printed to the screen. If however you cast an int-value to a float-value then the compile will convert the float from it's internal type into an integer for you. So you should replace the (int *) with (int) .

Also, %d is for decimal(integer) values. What you want is %f , which is for float values, for the first printf .

What you want is this:

#include <stdio.h>

int main()
{
  float a = 12.5;
  printf("%f\n", a); //changed %d -> %f
  printf("%d\n", (int)a); //changed *(int *)& -> (int) for proper conversion
  return 0;
} 

verified here: http://codepad.org/QD4kzAC9

Floating point numbers are stored in IEEE 754 format . When you pass the %d format specifier to printf() you're telling it to look at the first sizeof(int) bytes starting at &a . Well in the IEEE 754 format this is a bunch of zeros.

I highly recommend you read What Every Computer Scientist Should Know About Floating-Point Arithmetic

The difference is that in one case the compiler is doing an implicit cast (I assume you get 12 from the first one) while in the second case it is taking the memory containing the floating point value and interpreting it as an int. It would help if you included what the actual output was.

Casting a pointer and casting a value are very different operations. When you cast a float to an int, you ask to transform the float value to an int value, which results in actual transformation of data; when you cast a float pointer to an int pointer, you just override type checks. A pointer is just an integer memory location: casting it to another kind of pointer doesn't involve any transformation.

So, what you see is what the bit pattern of your float looks like when treated as an integer.

The bit patterns most computers use to represent floats are described by the IEEE-754 standard. Integers, on the other hand, are just, well, integers represented in binary base. Therefore, taking the bits of a real number and interpreting them as an integer yields very different results.

Let's see.

  1. Floats are stored in a format defined in IEEE 754. See here: http://en.wikipedia.org/wiki/IEEE_754-2008
  2. Side note: You're passing a double into a float in your first instruction. This will be cast at compile-time, but some compilers might complain. If you mean to use a float, append an f: float a = 12.5f;
  3. You're passing a float into a %d argument. That is not good. Compilers may behave differently here, some might warn you about it. If you want to pass in a float, use %f.
  4. You're taking the IEEE-754-formatted integer and printing it out. See the link in item 1 to see what you're printing.

我认为它打印12 12是因为%d没有区别,并且*&a = a

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM