IEEE 754浮動小数点フォーマットの概要とC言語の基本データ型変換の実質


本人菜鳥は、C言語のデータ変換現象を研究するのに少し時間を費やしました(まだ深い原因が出ていません).
Primeを見たことがなくて、Cコンパイラの原理も知らないで、コンパイルの原理、アセンブリ、構成の原理は少し皮の毛だけを学びます.
以下は成果で、指摘と疑いを解くことを歓迎します.

  
    
// :INTEL T3400 , XP 32 , DEBUG ,VS2008(VC9)

// IEEE 754
// (s) (E) (M)
// 1 8 23 32 0x7FH +127
// 1 11 52 64 0x3FFH +1023
// 1 15 64 80 0x3FFFH +16383
//
// : 0 11111110 1111111 11111111 11111111
//
// , ,
// 1111111 11111111 11111111 1.1111111 11111111 11111111, ,
//
// + 2^(254 - 127) * (1 + 1 - 2^(-23)) = 3.4028234663852885981170418348452e+38

#include
" stdio.h "
#include
< float .h >
void main()
{
unsigned
int o0 = 2147483649 ; // 10000000 00000000 00000000 00000001
int p0 = o0; // 10000000 00000000 00000000 00000001, 11111111 11111111 11111111 11111111
int o00 = 2147483649 ; // 10000000 00000000 00000000 00000001
unsigned int p00 = o00; // 10000000 00000000 00000000 00000001
printf( " %u, %d
" ,o0,p0); // 2147483648, -2147483648
printf( " %d, %u
" ,o00,p00); // -2147483648, 2147483648
//

int o = 0xFFFF4000 ; // 11111111 11111111 01000000 00000000
short p = o; // 01000000 00000000
short q = * (( short * )( & o)); /// / 01000000 00000000
printf( " %d, %hd, %hd
" ,o,p,q); // -49152, 16384, 16384
// 16 , ( little endian )

int o1 = 0xFFFF8000 ; // 11111111 11111111 10000000 00000000
short p1 = o1; // 10000000 00000000
short q1 = * (( short * )( & o1)); // 10000000 00000000
printf( " %d, %hd, %hd
" ,o1,p1,q1); // -32768, -32768, -32768
//

short a1 = 32767 ; // 01111111 11111111
int b1 = (unsigned short )a1; // 00000000 00000000 01111111 11111111
int c1 = a1; // 00000000 00000000 01111111 11111111
int d1 = * (( int * ) & a1);
// 11001100 11001100 01111111 11111111 16 ?
// a1 , , ,
printf( " %hd, %d, %d, %d
" ,a1,b1,c1,d1); // 32767, 32767, 32767, -859013121

short a = 32768 ; // 10000000 00000000
int b = (unsigned short )a; // 00000000 00000000 10000000 00000000
int c = a; // 11111111 11111111 10000000 00000000
int d = * (( int * ) & a); // 11001100 11001100 10000000 00000000 , 。
printf( " %hd, %d, %d, %d
" ,a,b,c,d); // -32768, 32768, -32768, -859013120
// , ( ), 0, 1,
// 0, 1, ,

long x = 2147483648 ; // 10000000 00000000 00000000 00000000
float y = (unsigned long )x; // 0 10011110 0000000 00000000 00000000 IEEE 754
float y1 = * (( float * )( & x)); // 1 00000000 0000000 00000000 00000000 IEEE 754 -0
float z = x; // 1 10011110 0000000 00000000 00000000 00000000 IEEE 754
printf( " %ld, %f, %f, %f
" ,x,y,y1,z); // -2147483648, 2147483648.000000, -0.000000, -2147483648.000000
// , , , , x ,
// , , 。
// , , , 。
// , , , , IEEE 754 ,
//

float l = FLT_MAX;
// 3.402823466e+38F ---> 0 11111110 1111111 11111111 11111110 -- ( , )-->
// 340282346638528860000000000000000000000.000000--> 0 11111110 1111111 11111111 11111111
// ( 11111111 11111110, IEEE 754 )
unsigned long m = (unsigned long )l; // 00000000 00000000 00000000 00000000 //
unsigned long m1 = * ((unsigned long * )( & l)); // 01111111 01111111 11111111 11111111
long n = l; // 10000000 0000000 00000000 00000000 //
printf( " %f, %lu, %lu, %ld
" ,l,m,m1,n); // 340282346638528860000000000000000000000.000000, 0, 2139095039, -2147483648

unsigned
char * pl = (unsigned char * ) & l; // 11111111 11111111 01111111 01111111
printf( " %hu, %hu, %hu, %hu
" ,pl[ 0 ],pl[ 1 ],pl[ 2 ],pl[ 3 ]); // 255, 255, 127, 127

unsigned
char str[ 4 ] = { 255 , 255 , 127 , 127 }; // 11111111 11111111 01111111 01111111
printf( " %f
" , * (( float * )str)); // 340282346638528860000000000000000000000.000000

float ff = 1.0f ; // 0 01111111 0000000 00000000 00000000
printf( " %lu
" , * ((unsigned long * ) & ff));
// 1065353216 ------ 0 01111111 0000000 00000000 00000000 (IEEE 754 1.0) -> 00111111 10000000 00000000 00000000 ( 1065353216)

float i = 32769.5 ; // 0 10001110 0000000 00000001 10000000
short j = i; // 10000000 00000001
unsigned short k = i; // 10000000 00000001
printf( " %f, %hd, %hu
" ,i,j,k); // 32769.500000, -32767, 32769
// , , , ,
// short long float

float u = FLT_MAX;
// 3.402823466e+38F ---> 0 11111110 1111111 11111111 11111110 -- >340282346638528860000000000000000000000.000000-->
// 0 11111110 1111111 11111111 11111111
double v = u;
// 0 10001111110 11111111 11111111 11111110 00000000 00000000 00000000 0000
// , , 1023
double w = * (( double * ) & u);
// 11001100 11001100 11001100 11001100 01111111 01111111 11111111 11111111
// 11001100 ,01111111 01111111 11111111 11111111 ( , u ),
// 16 , , u
=
printf(
" *********************
%f
%lf
%lf
" ,u,v,w);
//
// *********************
// 340282346638528860000000000000000000000.000000
// 340282346638528860000000000000000000000.000000
// -92559616541579665000000000000000000000000000000000000000000000.000000 ,Release 0.000000
unsigned char * pv = (unsigned char * ) & v; // 00000000, 00000000, 00000000, 11100000, 11111111, 11111111, 11101111, 01000111
printf( " %hu, %hu, %hu, %hu, %hu, %hu, %hu, %hu
" ,pv[ 0 ],pv[ 1 ],pv[ 2 ],pv[ 3 ],pv[ 4 ],pv[ 5 ],pv[ 6 ],pv[ 7 ]); // 0, 0, 0, 224, 255, 255, 239, 71
// v 01000111 11101111 11111111 11111111 11100000 00000000 00000000 00000000
//
unsigned char * pw = (unsigned char * ) & w; // 11111111 11111111 01111111 01111111
printf( " %hu, %hu, %hu, %hu
" ,pw[ 0 ],pw[ 1 ],pw[ 2 ],pw[ 3 ]); // 255, 255, 127, 127

double u1 = FLT_MAX; // 0 10001111110 11111111 11111111 11111110 00000000 00000000 00000000 0000
float v1 = u1; // 0 11111110 1111111 11111111 11111111 , , 127
float w1 = * (( float * ) & u1); // 1 11000000 0000000 00000000 00000000, 11100000 00000000 00000000 00000000, ( )32
printf( " *********************
%lf
%f
%f
" ,u1,v1,w1);
// *********************
// 340282346638528860000000000000000000000.000000
// 340282346638528860000000000000000000000.000000
// -36893488147419103000.000000

double u2 = DBL_MAX; // 0 11111111110 1111 11111111 11111111 11111111 11111111 11111111 11111111
float v2 = u2; //
float w2 = * (( float * ) & u2); //
printf( " *********************
%lf
%f
%f
" ,u2,v2,w2);
// *********************
// 17976931348623157000000000000000000000000000000000000000000000000000000000000000
// 00000000000000000000000000000000000000000000000000000000000000000000000000000000
// 00000000000000000000000000000000000000000000000000000000000000000000000000000000
// 000000000000000000000000000000000000000000000000000000000000000000000.000000
// 1.#INF00
// -1.#QNAN0
unsigned char * pv2 = (unsigned char * ) & v2; // 00000000 00000000 10000000 01111111
printf( " %hu, %hu, %hu, %hu
" ,pv2[ 0 ],pv2[ 1 ],pv2[ 2 ],pv2[ 3 ]); // 0, 0, 128, 127
unsigned char * pw2 = (unsigned char * ) & w2; // 11111111 11111111 11111111 11111111, u2 32 , ,
printf( " %hu, %hu, %hu, %hu
" ,pw2[ 0 ],pw2[ 1 ],pw2[ 2 ],pw2[ 3 ]); // 255, 255, 255, 255
// , v2 w2 ,
// 00000000 00000000 10000000 01111111 01111111 10000000 00000000 00000000, IEEE 754 0 11111111 0000000 00000000 00000000
// 11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111, IEEE 754 1 11111111 1111111 11111111 11111111

// ,DEBUG
// 2147483649, -2147483647
// -2147483647, 2147483649
// -49152, 16384, 16384
// -32768, -32768, -32768
// 32767, 32767, 32767, -859013121
// -32768, 32768, -32768, -859013120
// -2147483648, 2147483648.000000, -0.000000, -2147483648.000000
// 340282346638528860000000000000000000000.000000, 0, 2139095039, -2147483648
// 255, 255, 127, 127
// 340282346638528860000000000000000000000.000000
// 1065353216
// 32769.500000, -32767, 32769
// *********************
// 340282346638528860000000000000000000000.000000
// 340282346638528860000000000000000000000.000000
// -92559616541579665000000000000000000000000000000000000000000000.000000
// 0, 0, 0, 224, 255, 255, 239, 71
// *********************
// 340282346638528860000000000000000000000.000000
// 340282346638528860000000000000000000000.000000
// -36893488147419103000.000000
// *********************
// 17976931348623157000000000000000000000000000000000000000000000000000000000000000
// 00000000000000000000000000000000000000000000000000000000000000000000000000000000
// 00000000000000000000000000000000000000000000000000000000000000000000000000000000
// 000000000000000000000000000000000000000000000000000000000000000000000.000000
// 1.#INF00
// -1.#QNAN0
// 0, 0, 128, 127
// 255, 255, 255, 255

// FLT_MAX(3.402823466e+38F):
// 2139095039 = 01111111 01111111 11111111 11111111
// 255, 255, 127, 127 01111111 01111111 11111111 11111111
// 01111111 01111111 11111111 11111111
// 0 11111110 1111111 11111111 11111111 IEEE 754 , 0
// 0 01111111 1111111 11111111 11111111 127 , 127 127
// 0 01111111 1 1111111 11111111 11111111 , 1
// + 1.1111111 11111111 11111111 * 2 ^ 01111111 = (1 + 1 - 2^(-23)) * 2^127 = 3.4028234663852885981170418348452e+38
}