当存储double数据类型无法容纳的大值时会发生什么?

问题描述 投票:0回答:1
#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;
}

上面的代码在编译时会生成警告,因为 (

92233720368547758071
) 太大而无法存储在
double
中,而我使用
char
指针来寻址
double
数据类型,因为我想检查所有 8 个字节。

输出:

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. 符号位:(1位)

  2. 指数:(11位)

  3. 尾数:(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

c encoding binary double ieee-754
1个回答
1
投票

数字

92233720368547758071
绝对可以放入
double
内,因为
double
(IEEE754 float64) 可以容纳高达
1.8e+308
左右的值。

92233720368547758071
变成
18446744073709551616
的原因是
92233720368547758071
整数字面,而
18446744073709551616
是最接近(也是最大)的64位整数。

要制作双文字,请使用

.
,例如
92233720368547758071.0


注意:

92233720368547758071.0
实际上会存储为
92233720368547760000.0

可表征值之间的差距随着其大小的增大而增大;当幅度穿过

2^52
时,可表示值之间的差距变得大于
1.0
。请注意,52 位以上的整数可以完全放入尾数内。

© www.soinside.com 2019 - 2024. All rights reserved.