Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
372 views
in Technique[技术] by (71.8m points)

data structures - Why is there a contradiction in the output by two programs written below (Unions in C)?

Here goes the first code:

#include<stdio.h>

int main(){
 union var{
 int a;
 int b;
 };

 union var v;

 v.b=10;
 v.a=5;
 printf("%d", v.b);
 return 0;
} 

This gives 5 as the output.

However, consider this code:

#include<stdio.h>

int main(){
 union var{
 int a;
 float b;
 };

 union var v;

 v.b=10.0;
 v.a=5;

 printf("%f", v.b);

 return 0;

}

This gives 0.000000 as the output.

Any explanations?

question from:https://stackoverflow.com/questions/65839212/why-is-there-a-contradiction-in-the-output-by-two-programs-written-below-unions

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Bits in memory are used to represent different types in different ways. This answer discusses the representations used most commonly for int (32-bit two’s complement) and float (IEEE-754 binary32, also called single precision), assuming there are no complications with padding bits or different ordering of bits and bytes between int and float.

For int, there is a sign bit and 31 value bits. The 31 value bits are interpreted as a binary numeral. The sign bit represents the value ?231, and the value represented by the int is the sum of the value of the sign bit and the value of the binary numeral.

When you store 5 in the int member v.a, 5 is represented with the sign bit 0 and value bits 0000000000000000000000000000101. When you read it with int member v.b, the bits are interpreted in the same way they were used to represent 5, so the result is 5.

When you read it with float member v.b, the bits are reinterpreted using the scheme for float.

For float, there is a sign bit s, 8 exponent bits e, and 23 significand bits f, where e and f are the values of the bits when interpreted as binary numerals. These bits are interpreted as:

  • If e = 0, the value represented is (?1)s?21-127?(0+f/223).
  • If 0 < e < 255, the value represented is (?1)s?2e-127?(1+f/223).
  • If e = 255 and f = 0, the value represented is (?1)s?∞.
  • If e = 255 and f ≠ 0, the value represented is a special Not-a-Number (NaN) value. (If the first bit of f is set, 222f, it is a quiet NaN. Otherwise, it is a signaling NaN.)

When the bits 00000000000000000000000000000101 are interpreted as a float, then s is 0, e is 0, and f is 5. This fits the first condition, so the value represented is (?1)0?21-127?(0+5/223) = 2?126?5?2?23 = 5?2?149, which is approximately 7?10?45.

When you print this number with %f, it is so small that only “0.000000” is printed. If you print it with %g, the output will be “7.00649e-45”.

Note that, in C, reading the value of a member other than the last one written reinterprets the bytes of memory as the new type, per C 2018 6.5.2.3 3 and note 99. In C++, the behavior is not defined.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...