整数和浮点数的大小

21

我有一个关于 int 和 float 变量范围的问题:

如果它们都是 4 字节大小,为什么它们有不同的范围呢?

6个回答

23

它们完全不同 - 通常情况下,int 只是一个简单的2的补码有符号整数,而 float 是一个单精度浮点表示,具有23位尾数、8位指数和1位符号(参见http://en.wikipedia.org/wiki/IEEE_754-2008)。


2
+1 当然,你比我更清楚那些只是常见的表示方法。 - cnicutar
确实 - 既然这显然是一个新手问题,我认为最好保持简单。 - Paul R
@cnicutar,您是在暗示float可以任意表示吗? - Andreas Brinck
1
@Andreas Brinck 我的意思是标准并没有规定那些必须是表示形式。 - cnicutar
1
@Andreas, cnicutar:为了澄清,C标准并不要求实现使用IEEE-754。 - Oliver Charlesworth
1
@Andreas Brinck - 除了IEEE 754之外,还有很多浮点格式;在晚白垩纪时期,我曾经在VAX上工作过,它使用的是VAX F格式。C语言标准不关心实现所使用的具体浮点格式,它只规定了最小范围和精度。 - John Bode

18

它们具有不同的值范围,因为它们的内容被解释的方式不同; 换句话说,它们具有不同的表示

浮点数和双精度浮点数通常被表示为类似于

+-+-------+------------------------+
| |       |                        |
+-+-------+------------------------+
 ^    ^                ^
 |    |                |
 |    |                +--- significand
 |    +-- exponent
 |
 +---- sign bit

在这种浮点数表示法中,你需要1个比特位来表示符号s(0代表正数,1代表负数),一些比特位来表示指数e,以及其余的比特位用于表示尾数或分数f。所表示的值为s * f * 2e

可以表示的值的范围由指数中的比特数决定;指数中比特越多,则可能表示的值的范围越广。

精度(非正式地说,即可表示的值之间的间隔大小)由尾数中比特的数量决定。并不是所有浮点数值都能用给定数量的比特精确表示。尾数中比特位越多,则任意两个可表示值之间的间隔越小。

尾数中的每个比特位表示2的-n次方,其中n是从左边开始计数的比特位数。

 110100...
 ^^ ^
 || |  
 || +------ 1/2^4 = 0.0625
 || 
 |+-------- 1/2^2 = 0.25
 |
 +--------- 1/2^1 = 0.5
                    ------
                    0.8125

这是一个每个人都应该收藏的链接:计算机科学家应该了解的浮点算术知识.


4

同样大小的两种类型可以有不同的范围。

例如,signed int 和 unsigned int 都是 4 字节,但其中一个将其 32 位之一保留给符号,这会默认降低最大值因子 2。此外,范围也不同,因为其中一个可以是负数。另一方面,浮点数则在使用一些位进行小数范围时损失了值范围。


“浮点数[...]失去值范围”听起来好像浮点数能表示的最大数字比同样大小的整数能表示的最大数字要小,这绝对不是真的。 - sepp2k

1

标准并未指定以字节为单位的大小,但它指定了各种整数类型必须能够容纳的最小范围。您可以从中推断出最小的字节大小。

标准保证的最小范围(来自“C和C++中的整数类型”):

signed char: -127 to 127
unsigned char: 0 to 255
"plain" char: -127 to 127 or 0 to 255 (depends on default char signedness)
signed short: -32767 to 32767
unsigned short: 0 to 65535
signed int: -32767 to 32767
unsigned int: 0 to 65535
signed long: -2147483647 to 2147483647
unsigned long: 0 to 4294967295
signed long long: -9223372036854775807 to 9223372036854775807
unsigned long long: 0 to 18446744073709551615

实际的平台特定范围值可以在 C 中找到,或者在 C++ 中找到(甚至更好的是,在头文件中使用模板化的 std::numeric_limits)。

标准只要求:

sizeof(short int) <= sizeof(int) <= sizeof(long int)

float 的“分辨率”与 int 不同,尽管它们的大小看起来相似。 int 是二进制补码,而 float 由23位尾数、8位指数和1位符号组成。


8
这似乎并没有回答实际问题? - Paul R
float 不是整数类型。 - pmg
1
浮点数的范围是3.4E+/-38(7个数字)在Visual C中,int的范围为-2,147,483,648到2,147,483,647,两者都是4字节,那么为什么会有如此大的范围差异?这实际上是我想知道的。 - atul
2
@Monkey:好的-你现在已经编辑了它,加入了有关浮点数的句子,但原始答案甚至没有提到浮点数。 - Paul R
2
显然,在编辑之前,许多人看到了原始答案,当时它没有关于浮点数的句子。不过没关系,因为你已经修复了它。但是你可能需要删除大部分与不同整数大小和范围无关的内容。 - Paul R
显示剩余3条评论

1

你正在混淆数字的表示方式,这取决于你(或其他人)定义的一些规则,以及你用来在计算机中保存数字的方式(字节)。

例如,你可以只使用一个比特来保存一个数字,并决定0代表-100,1代表+100。或者0代表0.5,1代表1.0。这两个东西,数据和数据的含义是独立的。


1

一个整数只是一个数字... 它的范围取决于位数(对于有符号或无符号整数而言,位数不同)。

浮点数则完全不同。 这只是一种关于用二进制表示浮点数的约定...

它由一个符号位、一个指数字段和一个尾数编码组成。

请阅读以下文章:

http://www.eosgarden.com/en/articles/float/

它将让你从二进制的角度理解浮点数值,然后你就会理解范围的概念...


严谨地说,C语言的整数类型也像浮点类型一样,只是“关于表示的约定”。另外,在你的第二段中有一个循环定义! - Oliver Charlesworth

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接