混淆了长和双的大小

时间:2013-09-08 17:41:50

标签: java memory-management

查看Java(但在其他语言中可能类似或相同),long和double都使用8个字节来存储值。

long使用8个字节来存储从-9,223,372,036,854,775,808到9,223,372,036,854,775,807的长整数

double使用8个字节来存储从-1.7E308到1.7E308的双精度浮点数,最多16位有效数字。

我的问题是,如果两者都使用相同数量的字节(8字节或2 ^ 64),那么如何双重存储更长的数字? 1.7E308比9,223,372,036,854,775,807大得多。

4 个答案:

答案 0 :(得分:5)

您可以以64位存储的绝对信息量当然是相同的。

您为这些位分配的含义有哪些变化。

integerlong变量中,使用的编码与您在正常生活中使用的十进制数相同,但使用了第二个补码的事实除外,但这不是不会改变那么多,因为它只是一个获得额外数字的技巧(只存储一个零而不是正面和负面)。

在float或double变量中,位分为两种:尾数和指数。这意味着每个双数字的形状类似于XXXXYYYYY,其数值类似于XXXX*2^YYYY。基本上你决定用不同的方式对它们进行编码,你得到的是你有相同数量的值但它们在整个实数集上以不同的方式分配。

浮点数的最大/最小值大于/小于整数的最大值/小值这一事实并不意味着有效存储的数据量。

答案 1 :(得分:2)

双倍可以通过在它可以存储的数字之间具有更大的间隔来存储更大的数字。并非双精度范围内的每个整数都可由该双精度表示。

更具体地说,double有一个用于存储符号的位(S),用于存储指数E的11位,以及52位精度,即所谓的尾数(M)。

对于大多数数字(有一些特殊情况),double存储数字(-1)^ S *(1 +(M * 2 ^ { - 52}))* 2 ^ {E - 1023},以及因此,当E很大时,将M改变1将使得到的数字的大小比一个大得多。这些巨大的差距使双打比长期更大。

答案 2 :(得分:0)

Long或int是带符号的实体,可以是正数或负数但不包含任何小数部分。

在计算机中使用浮点数或双精度类型来表示具有小数部分的数字。

long和double都是64位。 Long有1位用于签名(确定正或负),其余63位构成数字。所以范围可以是-2 ^ 63到2 ^ 63-1

双倍表示为由IEEE二进制浮点运算标准指定的不同方式,设计用于在计算机中存储非常大的数字。 64位双重表示为 - [1位] [11位指数] [52位尾数]

让我们看一下这个例子,将100.25转换成二进制形式存储为double

  1. 转换为二进制的十进制100.25是1100100.01
  2. 二进制1100100.01然后归一化为1.10010001 * 2 ^ 6
  3. 6是指数分量。我们选择基数或偏移为1023,以便正负表示正负。所以6 + 1023 = 1029是加偏差后的偏移指数分量。 100000011是指数的二进制表示。

  4. 要从1.10010001计算尾数,我们忽略在十进制右边存在的1,只使用小数点右边的所有数字(即10010001),右边填充任意剩余的52位零。 那么,现在尾数将是1001 0001 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000

  5. 因此,最后64位表示为 签名位exponenet尾数  0 100000011 1001 0001 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000

答案 3 :(得分:0)

阅读上面的Delimanolis语句,我测试了长到双转换中的精度损失-忽略了一个高达500的整数值(见下文)。

long L;
double D;

L = 922_3372_0368_5477_5807L;
L -= 500;
D = L;
L = (long)D;

System.out.println("D and L: " + D + " " + L);

输出

D and L: 9.223372036854776E18 9223372036854775807