16

C++ 提供了三种浮点类型:float、double 和 long double。我很少在我的代码中使用浮点数,但是当我这样做时,我总是被无害的行上的警告所吸引,比如

float PiForSquares = 4.0;

问题是文字 4.0 是双精度数,而不是浮点数——这很烦人。

对于整数类型,我们有 short int、int 和 long int,这非常简单。为什么 C 没有短浮点数、浮点数和长浮点数?“双”到底是从哪里来的?

编辑:浮动类型之间的关系似乎类似于整数。double 必须至少与 float 一样大,long double 至少与 double 一样大。没有其他精度/范围保证。

4

12 回答 12

34

术语“单精度”和“双精度”起源于 FORTRAN,并且在 C 发明时已经广泛使用。在 1970 年代早期的机器上,单精度显着提高了效率,并且与今天一样,使用的内存是双精度的一半。因此,它是浮点数的合理默认值。

long double当 IEEE 标准允许 Intel 80287 浮点芯片使用 80 位浮点数而不是经典的 64 位双精度时,才添加了它。

提问者对保证的看法不正确;今天几乎所有语言都保证以单精度(32 位)和双精度(64 位)实现 IEEE 754 二进制浮点数。有些还提供扩展精度(80 位),在 C 中显示为long double. 由 William Kahan 带头的 IEEE 浮点标准是良好工程对权宜之计的胜利:在当时的机器上,它看起来非常昂贵,但在今天的机器上,它非常便宜,而且 IEEE 浮点的可移植性和可预测性点数每年必须节省数以亿计的美元。

于 2008-12-30T02:45:02.383 回答
25

您可能知道这一点,但您可以制作文字浮点数/长双精度数

 float f = 4.0f;
 long double f = 4.0l;

Double 是默认设置,因为这是大多数人使用的。长双精度数可能是矫枉过正,或者浮点数的精度非常差。Double 适用于几乎所有应用程序。

为什么取名?有一天,我们只有 32 位浮点数(实际上我们只有定点数,但我离题了)。无论如何,当浮点成为现代架构中流行的特性时,C 可能是当时的主要语言,并给出了“浮点”这个名称。似乎有道理。

当时可能已经想到了double,但是在当时的cpu's/fp cpus中并没有真正实现,都是16位或者32位。一旦 double 被用于更多架构中,C 可能就会开始添加它。C 需要一个两倍于浮点数的东西的名称,因此我们得到了一个双精度数。然后有人需要更精确,我们认为他疯了。无论如何,我们添加了它。四元组(?)这个名字有点矫枉过正。长双已经足够好,没有人发出很大的噪音。

部分困惑是good-ole“int”似乎随着时间而改变。过去,“int”表示 16 位整数。但是,浮点数作为 32 位 IEEE 浮点数绑定到IEEE 标准。出于这个原因,C 将 float 定义为 32 位,并使用 double 和 long double 来引用更长的标准。

于 2008-12-29T23:49:36.840 回答
5

字面量

问题是文字 4.0 是双精度数,而不是浮点数——这很烦人。

对于常量,整数和浮点数之间存在一个重要区别。虽然决定使用哪种整数类型相对容易(您选择足够小的值来保存值,但有符号/无符号会增加一些复杂性),但使用浮点数并不是那么容易。许多值(包括像 0.1 这样的简单值)不能用浮点数精确表示,因此类型的选择不仅会影响性能,还会影响结果值。在这种情况下,C 语言设计者似乎更喜欢稳健性而不是性能,因此他们决定默认表示应该是更准确的表示。

历史

为什么 C 没有短浮点数、浮点数和长浮点数?“双”到底是从哪里来的?

术语“单精度”和“双精度”起源于 FORTRAN,并且在 C 发明时已经广泛使用。

于 2008-12-30T13:39:43.733 回答
2

首先,这些名称并非特定于 C++,但对于任何实现 IEEE 754 的浮点数据类型来说都是非常常见的做法。

“double”这个名称是指“双精度”,而 float 通常被称为“单精度”。

于 2008-12-29T23:50:17.510 回答
1

两种最常见的浮点格式使用 32 位和 64 位,较长的一种是第一种的“双倍”大小,因此被称为“双倍”。

于 2008-12-29T23:51:31.393 回答
1

它们被称为单精度和双精度,因为它们与处理器的自然大小(不确定术语)有关。因此,32 位处理器的单精度将是 32 位长,而它的双精度将是 64 位长的两倍。他们只是决定在 C 中将单精度类型称为“float”。

于 2009-02-01T21:49:21.437 回答
1

double 之所以这样命名,是因为它是 float 的“精度”的两倍。真的,这意味着它使用了两倍的浮点值空间——如果你的浮点数是 32 位的,那么你的双精度数将是 64 位的。

双精度这个名称有点用词不当,因为双精度浮点数的尾数精度为 52 位,而单精度浮点数的尾数精度为 23 位(双精度为 56)。更多关于浮点的信息:Floating Point - Wikipedia,包括底部的单精度和双精度浮点数文章链接。

long double 的名称可能与整数类型的长整数与短整数的传统相同,但在这种情况下,他们将其颠倒过来,因为 'int' 等同于 'long int'。

于 2008-12-30T00:04:37.467 回答
1

在定点表示中,小数点后面有固定数量的数字(十进制表示中小数点的概括)。与浮点表示形成对比,其中小数点可以在所表示的数字的数字内移动或浮动。因此得名“浮点表示”。这被缩写为“浮动”。

在 K&R C 中,float指的是具有 32 位二进制表示double的浮点表示,并指的是具有 64 位二进制表示的浮点表示,或者是名称的两倍大小和来源。但是,最初的 K&R 规范要求所有浮点计算都以双精度完成。

在最初的 IEEE 754 标准 (IEEE 754-1985)(浮点表示和算术的黄金标准)中,为单精度和双精度浮点数的二进制表示提供了定义。双精度数的名称恰如其分,因为它们的位数是单精度数的两倍。

有关浮点表示的详细信息,请阅读 David Goldberg 的文章What Every Computer Scientist Should Know About Floating-Point Arithmetic

于 2008-12-30T02:17:04.890 回答
0

hence the %f for a float type, and a %lf for a long float which is the same as double.

于 2009-02-01T23:03:48.727 回答
0

double 是“双精度”的缩写。我猜,long double 来自于不想在处理器上开始出现精度更高的浮点类型时添加另一个关键字。

于 2008-12-29T23:52:23.230 回答
0

好的,从历史上看,它曾经是这样的:

用于 C 的原始机器将 16 位字分成 2 个字节,而一个 char 是一个字节。地址是 16 位,sizeof(foo*)2sizeof(char)也是,1。int 是 16 位,sizeof(int)2 也是。然后出现了 VAX(扩展寻址)机器,地址是 32 位。一个 char 仍然是 1 个字节,但sizeof(foo*)现在是 4 个。

有一些混乱,在伯克利编译器中解决了,所以一个 short 现在是 2 个字节,一个 int 是 4 个字节,因为它们非常适合高效的代码。long 变成了 8 个字节,因为 8 字节块有一种有效的寻址方法——称为双字。4 字节块是,当然,2 字节块是半字

浮点数的实现使得它们适合单字或双字。为了保持一致,双字浮点数被称为“双”。

于 2008-12-30T00:04:23.893 回答
0

应该注意的是,double不必能够保持比float;更大的值。它只需要更精确

于 2008-12-30T01:40:34.293 回答