IEEE 754浮動小数点フォーマットの概要とC言語の基本データ型変換の実質
53646 ワード
本人菜鳥は、C言語のデータ変換現象を研究するのに少し時間を費やしました(まだ深い原因が出ていません).
Primeを見たことがなくて、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
}