为什么会有这么多的数字类型(位,整型,浮点型,双精度型,长整型)?


9

我已经学习了PHP,Java和C。现在我很好奇为什么会有这么多类型的数字数据类型,例如bit,int,float,double和long。为什么不只为一种数字做类型呢?

有什么好处吗?也许如果我们使用整数来保存这么小的数字,那么我们可以节省内存吗?


6
除了HorusKol的答案:“ float”和“ integer”类型本质上是不同的。浮点数可以容纳非常大的数字,但是随着数字大小的增加,精度会下降。这种不精确性是由于浮点数的存储方式。相比之下,可以存储在整数中的值的范围是非常有限的,但是该值始终是精确的,因此您可以更轻松地比较值。同样,有两种不同的除法行为-整数会自动“截断”到最接近的整数,而浮点数则不会。这些行为中的每一个对于不同情况都是有用的。
坎普

JavaScript表面上只有一种数字类型。
Esailija

@kampu:实际上,在许多语言中,只要(虚拟)内存足以表示整数,整数就可以存储任何数字。
约尔格W¯¯米塔格

1
@JörgWMittag:但是,这个问题显然是在谈论静态语言,而不是像Python这样的动态语言。CPython本身将“无限范围”整数实现为32位int数组,每个int中的最后一位用于指示是否还有更多位要经过。此外,整数可以存储任何只数。这意味着具有无限存储空间的浮点数可以将值存储为精度(无穷大数),而整数只能存储值到精度(无穷大数零)。
坎普

@kampu:由于所有数字都由一系列位表示,即使无限存储,浮点数与整数之间始终存在一对一的映射关系。所以我不认为有人会质疑。

Answers:


17

为什么要考虑不同的数字数据类型有两个原因。

1.节省内存

for(long k=0;k<=10;k++)
{
    //stuff
}

为什么使用long时,它很容易成为整数,甚至是字节?这样做确实可以节省几个字节的内存。

2.浮点数和整数在计算机中的存储方式不同

假设我们将数字22存储在整数中。计算机将该数字以二进制形式存储在内存中,如下所示:

0000 0000 0000 0000 0000 0000 0001 0110

如果您不熟悉二进制数字系统,则可以用科学记数法表示为:2 ^ 0 * 0 + 2 ^ 1 * 1 + 2 ^ 2 * 1 + 2 ^ 3 * 0 + 2 ^ 4 * 1 + 2 ^ 5 * 0 + ... + 2 ^ 30 * 0。最后一位可能会或可能不会用来指示数字是否为负(取决于数据类型是带符号还是无符号)。

本质上,它只是2 ^(位)*值的总和。

当您引用涉及小数点的值时,这会改变。假设您用小数表示数字3.75。这在二进制文件中称为11.11。我们可以将其表示为科学记数法,表示为2 ^ 1 * 1 + 2 ^ 0 * 1 + 2 ^ -1 * 1 + 2 ^ -2 * 1或归一化为1.111 * 2 ^ 2

但是,计算机无法存储它:它没有表达该二进制点(小​​数点的二进制数字系统版本)的显式方法。计算机只能存储1和0。这就是浮点数据类型的来源。

假设sizeof(float)为4字节,则总共有32位。给第一位分配“符号位”。没有无符号的浮点数或双精度数。接下来的8位用作“指数”,最后的23位用作“有效数”(有时也称为尾数)。使用我们的3.75示例,我们的指数将为2 ^ 1,有效数将为1.111。

如果第一位为1,则数字为负。如果不是,则为正。指数被称为“偏见”的东西所修饰,因此我们不能简单地将“ 0000 0010”存储为指数。单精度浮点数的偏差为127,双精度浮点数(这是double数据类型的名称)的偏差为1023。最后23位保留给有效位数。有效位数只是我们二进制点右边的值。

我们的指数将是偏差(127)+指数(1)或以二进制表示

1000 0000

我们的意义是:

111 0000 0000 0000 0000 0000

因此,3.75表示为:

0100 0000 0111 0000 0000 0000 0000 0000

现在,让我们看一下表示为浮点数和整数的数字8:

0100 0001 0000 0000 0000 0000 0000 0000
0000 0000 0000 0000 0000 0000 0000 1000

计算机将如何添加8.0和8?甚至乘以它们!该计算机(更具体地说是x86计算机)具有CPU的不同部分,这些部分添加了浮点数和整数。


3
3)尽管很少出现问题:对大于计算机字数的数字的运算速度较慢。
罗伦·佩希特尔

6

早在我们拥有千兆字节系统(或在像Arduino这样的现代嵌入式系统)上,内存非常宝贵,因此实施了速记方法来指定特定数字将占用多少内存-BIT很简单-最初只占1位的记忆。

其他数据大小和名称在系统之间有所不同。在32位系统上,INT(或MEDIUMINT)通常为2个字节,LONGINT为4个字节,SMALLINT为单个字节。64位系统可以将LONGINT设置为8字节。

即使是现在-特别是在数据库应用程序或在服务器上运行有多个实例的程序中(例如网站上的服务器端脚本),您仍应注意选择的内容。如果您的数据库表具有数百万条记录,那么挑选一个2、4或8字节宽的整数来存储0到100之间的值(可以容纳一个字节)是非常浪费的。

更多信息:https : //en.wikipedia.org/wiki/Integer_(computer_science)


不错的答案+1。
Vinay

7
当系统很小时,不仅“先回”,而且“现在”。在设备上,Arduino的大小必须经济。
9000

1
哪个系统仅使用1位存储一点?位通常不能直接寻址
jk。

1
在许多体系结构中都是如此-但是在真正的旧系统中甚至可以直接寻址位,甚至在一些较新的嵌入式系统中(我仅十年前编程的某些控制器都使用位-那些只有大约64个特定宽度的可寻址位置)。如今,我猜编译器会解决这个问题并将其放入字节数组中。
HorusKol

我认为最主要的因素是CPU能力和性能,而不是内存问题
James

4

除了cpmjr123关于内存稀缺性,精度和范围折衷的优缺点之外,这些还可能是CPU的折衷方案。

大多数现代机器都有用于执行浮点运算的特殊硬件,称为FPU。也有一些系统没有FPU(现在通常是小型嵌入式设备),因此,根据目标硬件的不同,您将要么根本不使用浮点类型,要么使用软件浮点库。即使您的机器装有FPU,其提供的功能在历史上也存在差异。任何未在硬件中完成的功能都必须在软件中完成(或避免使用)

通过执行硬件支持的许多更简单的操作,可以在软件中进行浮点计算。因此,您也会获得潜在的速度折衷。


4

也许最重要的是,实际上有三种不同的基本数字类型。

整数,固定的小数和浮点数。

它们的行为各不相同。

根据所使用的数据类型,像7/2这样的简单操作可以给出3、3.50和3.499的答案。

“固定十进制”是灰姑娘类型,仅本地支持几种语言,例如COBOL和VisualBasic。它对计算机科学家没什么兴趣,但是对于任何提交一组帐户或计算发票营业税的人来说至关重要。


我以不同的方式将它们分开:离散数,近似数和环绕的代数环。在C典型的例子是intfloat,和unsigned int,分别。定点类型是离散类型的子类别,但是代数环与数字本质上是不同的[C中对无符号类型的困惑必须源于它们大多像环而不是数字,但不太一致的事实] 。
超级猫

3

他们有什么好处吗?

当然。有好处。在计算机世界中,内存是最重要的考虑因素之一。当数据可以容纳小于1kb的内存时,具有2kb的内存有什么用?。优化应该在那里。如果您使用更多的内存,显然会降低您的计算机速度。你真的很喜欢吗?没有权利...?

int - 2 bytes (16 bits)

long - 4 bytes (32 bits)

long long - 8 bytes (64 bits)

float - 4 bytes

不仅记忆,而且还有数字类型的组织。用于实例浮点。精度很重要,显然我们应该选择一种可以给我们带来更高精度的类型。

如果我们考虑过去的日子,那么您可能知道的记忆力就很少。为了保存并明智地使用它,我们存在这些差异。还有更多,如果您只是继续尝试使用Google进行搜索。希望对您有所帮助。


3

从概念上讲,整数和实数(浮点,双精度)是不同的类型,具有不同的操作集和内在属性。

整数是可枚举的,但浮点数不是,等等。

实际上,浮点数/双数是结合两个整数字段的结构:尾数和指数。复杂数字(您已排除在外)更加复杂。

任何实用语言都应至少具有整数和浮点数作为不同的类型-它们之间的操作差异太大。


我不熟悉您提到的“复数”。您能进一步解释吗?
cpmjr123


我知道a + bi形式的复数。我要求提供有关计算机如何存储复数的更多信息。据我所知,没有原始数据类型支持此功能。
cpmjr123

复数通常存储为两个浮点值,即它们的a(实部)和b(虚部)。尽管CPU可能对诸如(a b + c d)和(a b-c d)之类的值对执行加速的乘法加法指令,但CPU通常不会为复数运算提供本机支持。
rwong 2013年

1
另外,许多语言具有某些类型,其行为在很大程度上被定义为环绕的代数环(例如,如果类型的变量uint16_t持有65535,则将其递增将使其持有0)。理想情况下,语言必须干净,独立的类型代表包裹代数环和数字(允许数字溢出被困住,同时允许代码就被这东西很容易进行操作预计到套)。
超级猫

-1

除了浮点类型的行为与整数类型完全不同之外,我还想举一个极端的例子,说明每个数字的大小确实很重要。

假设您要对(长)数组进行排序。例如在C中:

int numbers[100000000];

因此,这里有1亿个数字。

如果每个数字只有一个字节长(因此使用unsigned char代替int),则这需要1亿字节的空间。

如果使用double,则每个数字通常为8字节,因此有8亿字节的空间。

因此,每次使用许多对象(在此示例中为数字)时,每个对象的大小(在此示例中为每个数字的大小)确实很重要。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.