#include <stdio.h>
int main() {
double a =92233720368547758071;
printf("value=%lf\n", a);
int i;
char *b = &a;
for (i = 0; i < 8; i++) {
printf("%d byte (%p)value: <%d>\n", i + 1, b,*b);
b++;
}
return 0;
}
(编译器详细信息): gcc(Ubuntu 13.2.0-23ubuntu4)13.2.0
上面的代码在编译时会生成警告,因为 (
92233720368547758071
) 太大而无法存储在 double
中,而我使用 char
指针来寻址 double
数据类型,因为我想检查所有 8 个字节。
(警告):
test.c: In function ‘main’:
test.c:6:12: warning: integer constant is too large for its type
6 | double a = 92233720368547758071;
| ^~~~~~~~~~~~~~~~~~~~
test.c:8:17: warning: initialization of ‘char *’ from incompatible pointer type ‘double *’ [-Wincompatible-pointer-types]
8 | int i;char *b = &a;
输出:
value=18446744073709551616.000000
1 byte (0x7ffda3f173f8)value: <0>
2 byte (0x7ffda3f173f9)value: <0>
3 byte (0x7ffda3f173fa)value: <0>
4 byte (0x7ffda3f173fb)value: <0>
5 byte (0x7ffda3f173fc)value: <0>
6 byte (0x7ffda3f173fd)value: <0>
7 byte (0x7ffda3f173fe)value: <-16>
8 byte (0x7ffda3f173ff)value: <67>
IEEE 754 标准用于表示内存中的浮点数。
double
数据类型使用双精度编码格式。
格式包含:
符号位:(1位)
指数:(11位)
尾数:(52 位)
表示64位的浮点数。
(
92233720368547758071
)转换:
Normalised number: [+]1.[0100000000000000000000000000000000000000000000000000]*2^[66]
double precision bias: 1023
Exponent: 1023+66=1089
1) sign-bit: (0)
2) Exponent: (10001000001)
3) Mantissa|Precision: (0100000000000000000000000000000000000000000000000000)
92233720368547758071
->
01000100 00010100 00000000 00000000 00000000 00000000 00000000 00000000
(
18446744073709551616
)转换:
Normalised number:[+]1.[0000000000000000000000000000000000000000000000000000]*2^[64]
double precision bias: 1023
Exponent: 1023+64=1087
1) sign-bit: (0)
2) Exponent: (10000111111)
3) Mantissa|Precision: (0000000000000000000000000000000000000000000000000000)
18446744073709551616
->
01000011 11110000 00000000 00000000 00000000 00000000 00000000 00000000
我的系统linux使用little endian在内存中存储数据。接下来,我们尝试解码每个字节中存储的数据,我们得到相同的结果。
(系统信息):
PRETTY_NAME="Ubuntu 24.04 LTS"
NAME="Ubuntu"
VERSION_ID="24.04"
VERSION="24.04 LTS (Noble Numbat)"
VERSION_CODENAME=noble
Hostname=HP-Laptop-15s-fq5xxx
1st byte value (0) which in binary -> (00000000)
2nd byte value (0) which in binary -> (00000000)
3rd byte value (0) which in binary -> (00000000)
4th byte value (0) which in binary -> (00000000)
5th byte value (0) which in binary -> (00000000)
6th byte value (0) which in binary -> (00000000)
7th byte value (-16) which in binary -> (11110000)
8th byte value (67) which in binary -> (01000011)
我的问题是数字
92233720368547758071
如何转换,如何存储为18446744073709551616
?
这里发生了什么?这个 (
18446744073709551616
) 如何存储在内存中而不是 92233720368547758071
?
数字
92233720368547758071
绝对可以放入 double
内,因为 double
(IEEE754 float64) 可以容纳高达 1.8e+308
左右的值。
92233720368547758071
变成18446744073709551616
的原因是92233720368547758071
是整数字面,而18446744073709551616
是最接近(也是最大)的64位整数。
要制作双文字,请使用
.
,例如92233720368547758071.0
。
注意:
92233720368547758071.0
实际上会存储为92233720368547758080.0
。
可表征值之间的差距随着其大小的增大而增大;当幅度穿过
2^52
时,可表示值之间的差距变得大于1.0
。请注意,52 位以上的整数可以完全放入尾数内。