diff --git a/404.html b/404.html index b1a9219ed..10d3c53c7 100644 --- a/404.html +++ b/404.html @@ -531,17 +531,21 @@ + + + + - 3. 数据结构简介 + 3. 数据结构与数据 - 3. 数据结构简介 + 3. 数据结构与数据 @@ -551,8 +555,8 @@ - - 3.1. 基本数据类型 + + 3.1. 数据结构分类 @@ -565,8 +569,36 @@ - - 3.2. 数据结构分类 + + 3.2. 基本数据类型 + + + + + + + + + + + + + + 3.3. 数字编码 * + + + + + + + + + + + + + + 3.4. 字符编码 * @@ -580,7 +612,7 @@ - 3.3. 小结 + 3.5. 小结 diff --git a/chapter_appendix/contribution/index.html b/chapter_appendix/contribution/index.html index 9db646f2c..7bc4c5f63 100644 --- a/chapter_appendix/contribution/index.html +++ b/chapter_appendix/contribution/index.html @@ -542,17 +542,21 @@ + + + + - 3. 数据结构简介 + 3. 数据结构与数据 - 3. 数据结构简介 + 3. 数据结构与数据 @@ -562,8 +566,8 @@ - - 3.1. 基本数据类型 + + 3.1. 数据结构分类 @@ -576,8 +580,36 @@ - - 3.2. 数据结构分类 + + 3.2. 基本数据类型 + + + + + + + + + + + + + + 3.3. 数字编码 * + + + + + + + + + + + + + + 3.4. 字符编码 * @@ -591,7 +623,7 @@ - 3.3. 小结 + 3.5. 小结 diff --git a/chapter_appendix/installation/index.html b/chapter_appendix/installation/index.html index 658412bd3..c279c74a2 100644 --- a/chapter_appendix/installation/index.html +++ b/chapter_appendix/installation/index.html @@ -542,17 +542,21 @@ + + + + - 3. 数据结构简介 + 3. 数据结构与数据 - 3. 数据结构简介 + 3. 数据结构与数据 @@ -562,8 +566,8 @@ - - 3.1. 基本数据类型 + + 3.1. 数据结构分类 @@ -576,8 +580,36 @@ - - 3.2. 数据结构分类 + + 3.2. 基本数据类型 + + + + + + + + + + + + + + 3.3. 数字编码 * + + + + + + + + + + + + + + 3.4. 字符编码 * @@ -591,7 +623,7 @@ - 3.3. 小结 + 3.5. 小结 diff --git a/chapter_array_and_linkedlist/array/index.html b/chapter_array_and_linkedlist/array/index.html index 7849c3018..4b0a30193 100644 --- a/chapter_array_and_linkedlist/array/index.html +++ b/chapter_array_and_linkedlist/array/index.html @@ -542,17 +542,21 @@ + + + + - 3. 数据结构简介 + 3. 数据结构与数据 - 3. 数据结构简介 + 3. 数据结构与数据 @@ -562,8 +566,8 @@ - - 3.1. 基本数据类型 + + 3.1. 数据结构分类 @@ -576,8 +580,36 @@ - - 3.2. 数据结构分类 + + 3.2. 基本数据类型 + + + + + + + + + + + + + + 3.3. 数字编码 * + + + + + + + + + + + + + + 3.4. 字符编码 * @@ -591,7 +623,7 @@ - 3.3. 小结 + 3.5. 小结 @@ -2827,7 +2859,7 @@ - + @@ -2836,7 +2868,7 @@ 上一页 - 3.3. 小结 + 3.5. 小结 diff --git a/chapter_array_and_linkedlist/linked_list/index.html b/chapter_array_and_linkedlist/linked_list/index.html index 4c3ef336b..acb0501c6 100644 --- a/chapter_array_and_linkedlist/linked_list/index.html +++ b/chapter_array_and_linkedlist/linked_list/index.html @@ -542,17 +542,21 @@ + + + + - 3. 数据结构简介 + 3. 数据结构与数据 - 3. 数据结构简介 + 3. 数据结构与数据 @@ -562,8 +566,8 @@ - - 3.1. 基本数据类型 + + 3.1. 数据结构分类 @@ -576,8 +580,36 @@ - - 3.2. 数据结构分类 + + 3.2. 基本数据类型 + + + + + + + + + + + + + + 3.3. 数字编码 * + + + + + + + + + + + + + + 3.4. 字符编码 * @@ -591,7 +623,7 @@ - 3.3. 小结 + 3.5. 小结 diff --git a/chapter_array_and_linkedlist/list/index.html b/chapter_array_and_linkedlist/list/index.html index b11dc1179..e0612c306 100644 --- a/chapter_array_and_linkedlist/list/index.html +++ b/chapter_array_and_linkedlist/list/index.html @@ -542,17 +542,21 @@ + + + + - 3. 数据结构简介 + 3. 数据结构与数据 - 3. 数据结构简介 + 3. 数据结构与数据 @@ -562,8 +566,8 @@ - - 3.1. 基本数据类型 + + 3.1. 数据结构分类 @@ -576,8 +580,36 @@ - - 3.2. 数据结构分类 + + 3.2. 基本数据类型 + + + + + + + + + + + + + + 3.3. 数字编码 * + + + + + + + + + + + + + + 3.4. 字符编码 * @@ -591,7 +623,7 @@ - 3.3. 小结 + 3.5. 小结 diff --git a/chapter_array_and_linkedlist/summary/index.html b/chapter_array_and_linkedlist/summary/index.html index ec5cf17b5..bc260ee6d 100644 --- a/chapter_array_and_linkedlist/summary/index.html +++ b/chapter_array_and_linkedlist/summary/index.html @@ -542,17 +542,21 @@ + + + + - 3. 数据结构简介 + 3. 数据结构与数据 - 3. 数据结构简介 + 3. 数据结构与数据 @@ -562,8 +566,8 @@ - - 3.1. 基本数据类型 + + 3.1. 数据结构分类 @@ -576,8 +580,36 @@ - - 3.2. 数据结构分类 + + 3.2. 基本数据类型 + + + + + + + + + + + + + + 3.3. 数字编码 * + + + + + + + + + + + + + + 3.4. 字符编码 * @@ -591,7 +623,7 @@ - 3.3. 小结 + 3.5. 小结 diff --git a/chapter_backtracking/backtracking_algorithm/index.html b/chapter_backtracking/backtracking_algorithm/index.html index 731cec1de..fd88c7fec 100644 --- a/chapter_backtracking/backtracking_algorithm/index.html +++ b/chapter_backtracking/backtracking_algorithm/index.html @@ -542,17 +542,21 @@ + + + + - 3. 数据结构简介 + 3. 数据结构与数据 - 3. 数据结构简介 + 3. 数据结构与数据 @@ -562,8 +566,8 @@ - - 3.1. 基本数据类型 + + 3.1. 数据结构分类 @@ -576,8 +580,36 @@ - - 3.2. 数据结构分类 + + 3.2. 基本数据类型 + + + + + + + + + + + + + + 3.3. 数字编码 * + + + + + + + + + + + + + + 3.4. 字符编码 * @@ -591,7 +623,7 @@ - 3.3. 小结 + 3.5. 小结 diff --git a/chapter_backtracking/n_queens_problem/index.html b/chapter_backtracking/n_queens_problem/index.html index 33f90f263..bca0b2dbb 100644 --- a/chapter_backtracking/n_queens_problem/index.html +++ b/chapter_backtracking/n_queens_problem/index.html @@ -542,17 +542,21 @@ + + + + - 3. 数据结构简介 + 3. 数据结构与数据 - 3. 数据结构简介 + 3. 数据结构与数据 @@ -562,8 +566,8 @@ - - 3.1. 基本数据类型 + + 3.1. 数据结构分类 @@ -576,8 +580,36 @@ - - 3.2. 数据结构分类 + + 3.2. 基本数据类型 + + + + + + + + + + + + + + 3.3. 数字编码 * + + + + + + + + + + + + + + 3.4. 字符编码 * @@ -591,7 +623,7 @@ - 3.3. 小结 + 3.5. 小结 diff --git a/chapter_backtracking/permutations_problem/index.html b/chapter_backtracking/permutations_problem/index.html index 410e545b1..7e6a67acd 100644 --- a/chapter_backtracking/permutations_problem/index.html +++ b/chapter_backtracking/permutations_problem/index.html @@ -542,17 +542,21 @@ + + + + - 3. 数据结构简介 + 3. 数据结构与数据 - 3. 数据结构简介 + 3. 数据结构与数据 @@ -562,8 +566,8 @@ - - 3.1. 基本数据类型 + + 3.1. 数据结构分类 @@ -576,8 +580,36 @@ - - 3.2. 数据结构分类 + + 3.2. 基本数据类型 + + + + + + + + + + + + + + 3.3. 数字编码 * + + + + + + + + + + + + + + 3.4. 字符编码 * @@ -591,7 +623,7 @@ - 3.3. 小结 + 3.5. 小结 diff --git a/chapter_binary_search/binary_search/index.html b/chapter_binary_search/binary_search/index.html index ddcef190d..00b2ed120 100644 --- a/chapter_binary_search/binary_search/index.html +++ b/chapter_binary_search/binary_search/index.html @@ -542,17 +542,21 @@ + + + + - 3. 数据结构简介 + 3. 数据结构与数据 - 3. 数据结构简介 + 3. 数据结构与数据 @@ -562,8 +566,8 @@ - - 3.1. 基本数据类型 + + 3.1. 数据结构分类 @@ -576,8 +580,36 @@ - - 3.2. 数据结构分类 + + 3.2. 基本数据类型 + + + + + + + + + + + + + + 3.3. 数字编码 * + + + + + + + + + + + + + + 3.4. 字符编码 * @@ -591,7 +623,7 @@ - 3.3. 小结 + 3.5. 小结 diff --git a/chapter_computational_complexity/performance_evaluation/index.html b/chapter_computational_complexity/performance_evaluation/index.html index 84aec1e22..edc38e69f 100644 --- a/chapter_computational_complexity/performance_evaluation/index.html +++ b/chapter_computational_complexity/performance_evaluation/index.html @@ -619,17 +619,21 @@ + + + + - 3. 数据结构简介 + 3. 数据结构与数据 - 3. 数据结构简介 + 3. 数据结构与数据 @@ -639,8 +643,8 @@ - - 3.1. 基本数据类型 + + 3.1. 数据结构分类 @@ -653,8 +657,36 @@ - - 3.2. 数据结构分类 + + 3.2. 基本数据类型 + + + + + + + + + + + + + + 3.3. 数字编码 * + + + + + + + + + + + + + + 3.4. 字符编码 * @@ -668,7 +700,7 @@ - 3.3. 小结 + 3.5. 小结 diff --git a/chapter_computational_complexity/space_complexity/index.html b/chapter_computational_complexity/space_complexity/index.html index fa9c3e29a..ae8278f1b 100644 --- a/chapter_computational_complexity/space_complexity/index.html +++ b/chapter_computational_complexity/space_complexity/index.html @@ -647,17 +647,21 @@ + + + + - 3. 数据结构简介 + 3. 数据结构与数据 - 3. 数据结构简介 + 3. 数据结构与数据 @@ -667,8 +671,8 @@ - - 3.1. 基本数据类型 + + 3.1. 数据结构分类 @@ -681,8 +685,36 @@ - - 3.2. 数据结构分类 + + 3.2. 基本数据类型 + + + + + + + + + + + + + + 3.3. 数字编码 * + + + + + + + + + + + + + + 3.4. 字符编码 * @@ -696,7 +728,7 @@ - 3.3. 小结 + 3.5. 小结 diff --git a/chapter_computational_complexity/summary/index.html b/chapter_computational_complexity/summary/index.html index f520dd402..5a5a68f85 100644 --- a/chapter_computational_complexity/summary/index.html +++ b/chapter_computational_complexity/summary/index.html @@ -18,7 +18,7 @@ - + @@ -554,17 +554,21 @@ + + + + - 3. 数据结构简介 + 3. 数据结构与数据 - 3. 数据结构简介 + 3. 数据结构与数据 @@ -574,8 +578,8 @@ - - 3.1. 基本数据类型 + + 3.1. 数据结构分类 @@ -588,8 +592,36 @@ - - 3.2. 数据结构分类 + + 3.2. 基本数据类型 + + + + + + + + + + + + + + 3.3. 数字编码 * + + + + + + + + + + + + + + 3.4. 字符编码 * @@ -603,7 +635,7 @@ - 3.3. 小结 + 3.5. 小结 @@ -1921,13 +1953,13 @@ - + @@ -1911,7 +1829,7 @@ - + @@ -1919,174 +1837,103 @@ -3.1. 数据与内存¶ -3.1.1. 基本数据类型¶ +3.2. 基本数据类型¶ 谈及计算机中的数据,我们会想到文本、图片、视频、语音、3D 模型等各种形式。尽管这些数据的组织形式各异,但它们都由各种基本数据类型构成。 -「基本数据类型」是 CPU 可以直接进行运算的类型,在算法中直接被使用。 +基本数据类型是 CPU 可以直接进行运算的类型,在算法中直接被使用。它包括: -「整数」按照不同的长度分为 byte, short, int, long 。在满足取值范围的前提下,我们应该尽量选取较短的整数类型,以减小内存空间占用; -「浮点数」表示小数,按长度分为 float, double ,选用规则与整数相同。 -「字符」在计算机中以字符集形式保存,char 的值实际上是数字,代表字符集中的编号,计算机通过字符集查表完成编号到字符的转换。 -「布尔」代表逻辑中的“是”与“否”,其占用空间需根据编程语言确定。 +整数类型 byte , short , int , long ; +浮点数类型 float , double ,用于表示小数; +字符类型 char ,用于表示各种语言的字母、标点符号、甚至表情符号等; +布尔类型 bool ,用于表示“是”与“否”判断; +所有基本数据类型都以二进制的形式存储在计算机中。在计算机中,我们将 \(1\) 个二进制位称为 \(1\) 比特,并规定 \(1\) 字节(byte)由 \(8\) 比特(bits)组成。基本数据类型的取值范围取决于其占用的空间大小,例如: + +整数类型 byte 占用 \(1\) byte = \(8\) bits ,可以表示 \(2^{8}\) 个不同的数字; +整数类型 int 占用 \(4\) bytes = \(32\) bits ,可以表示 \(2^{32}\) 个数字; + +下表列举了各种基本数据类型的占用空间、取值范围和默认值。此表格无需硬背,大致理解即可,需要时可以通过查表来回忆。 -类别 +类型 符号 占用空间 -取值范围 +最小值 +最大值 默认值 整数 -byte +byte 1 byte -\(-2^7\) ~ \(2^7 - 1\) ( \(-128\) ~ \(127\) ) +\(-2^7\) (\(-128\)) +\(2^7 - 1\) (\(127\)) \(0\) -short +short 2 bytes -\(-2^{15}\) ~ \(2^{15} - 1\) +\(-2^{15}\) +\(2^{15} - 1\) \(0\) -int +int 4 bytes -\(-2^{31}\) ~ \(2^{31} - 1\) +\(-2^{31}\) +\(2^{31} - 1\) \(0\) -long +long 8 bytes -\(-2^{63}\) ~ \(2^{63} - 1\) +\(-2^{63}\) +\(2^{63} - 1\) \(0\) 浮点数 -float +float 4 bytes -\(-3.4 \times 10^{38}\) ~ \(3.4 \times 10^{38}\) -\(0.0\) f +\(1.175 \times 10^{-38}\) +\(3.403 \times 10^{38}\) +\(0.0 f\) -double +double 8 bytes -\(-1.7 \times 10^{308}\) ~ \(1.7 \times 10^{308}\) +\(2.225 \times 10^{-308}\) +\(1.798 \times 10^{308}\) \(0.0\) 字符 -char +char 2 bytes / 1 byte -\(0\) ~ \(2^{16} - 1\) +\(0\) +\(2^{16} - 1\) \(0\) 布尔 -bool +bool 1 byte / 1 bit -\(\text{true}\) 或 \(\text{false}\) +\(\text{false}\) +\(\text{true}\) \(\text{false}\) -以上表格中,加粗项在算法题中最为常用。此表格无需硬背,大致理解即可,需要时可以通过查表来回忆。 -整数表示方式¶ -整数的取值范围取决于变量使用的内存长度,即字节(或比特)数。在计算机中,1 字节 (byte) = 8 比特 (bit),1 比特即 1 个二进制位。以 int 类型为例: - -整数类型 int 占用 4 bytes = 32 bits ,可以表示 \(2^{32}\) 个不同的数字; -将最高位视为符号位,\(0\) 代表正数,\(1\) 代表负数,一共可表示 \(2^{31}\) 个正数和 \(2^{31}\) 个负数; -当所有 bits 为 0 时代表数字 \(0\) ,从零开始增大,可得最大正数为 \(2^{31} - 1\) ; -剩余 \(2^{31}\) 个数字全部用来表示负数,因此最小负数为 \(-2^{31}\) ;具体细节涉及“源码、反码、补码”的相关知识,有兴趣的同学可以查阅学习; - -其他整数类型 byte, short, long 的取值范围的计算方法与 int 类似,在此不再赘述。 -浮点数表示方式 *¶ - -Note -本书中,标题后的 * 符号代表选读章节。如果你觉得理解困难,建议先跳过,等学完必读章节后再单独攻克。 - -细心的你可能会发现:int 和 float 长度相同,都是 4 bytes,但为什么 float 的取值范围远大于 int ?按理说 float 需要表示小数,取值范围应该变小才对。 -实际上,这是因为浮点数 float 采用了不同的表示方式。根据 IEEE 754 标准,32-bit 长度的 float 由以下部分构成: - -符号位 \(\mathrm{S}\) :占 1 bit ; -指数位 \(\mathrm{E}\) :占 8 bits ; -分数位 \(\mathrm{N}\) :占 24 bits ,其中 23 位显式存储; - -设 32-bit 二进制数的第 \(i\) 位为 \(b_i\) ,则 float 值的计算方法定义为: -\[ -\text { val } = (-1)^{b_{31}} \times 2^{\left(b_{30} b_{29} \ldots b_{23}\right)_2-127} \times\left(1 . b_{22} b_{21} \ldots b_0\right)_2 -\] -转化到十进制下的计算公式为 -\[ -\text { val }=(-1)^{\mathrm{S}} \times 2^{\mathrm{E} -127} \times (1 + \mathrm{N}) -\] -其中各项的取值范围为 -\[ -\begin{aligned} -\mathrm{S} \in & \{ 0, 1\} , \quad \mathrm{E} \in \{ 1, 2, \dots, 254 \} \newline -(1 + \mathrm{N}) = & (1 + \sum_{i=1}^{23} b_{23-i} 2^{-i}) \subset [1, 2 - 2^{-23}] -\end{aligned} -\] - - Fig. IEEE 754 标准下的 float 表示方式 - -以上图为例,\(\mathrm{S} = 0\) , \(\mathrm{E} = 124\) ,\(\mathrm{N} = 2^{-2} + 2^{-3} = 0.375\) ,易得 -\[ -\text { val } = (-1)^0 \times 2^{124 - 127} \times (1 + 0.375) = 0.171875 -\] -现在我们可以回答最初的问题:float 的表示方式包含指数位,导致其取值范围远大于 int 。根据以上计算,float 可表示的最大正数为 \(2^{254 - 127} \times (2 - 2^{-23}) \approx 3.4 \times 10^{38}\) ,切换符号位便可得到最小负数。 -尽管浮点数 float 扩展了取值范围,但其副作用是牺牲了精度。整数类型 int 将全部 32 位用于表示数字,数字是均匀分布的;而由于指数位的存在,浮点数 float 的数值越大,相邻两个数字之间的差值就会趋向越大。 -进一步地,指数位 \(E = 0\) 和 \(E = 255\) 具有特殊含义,用于表示零、无穷大、\(\mathrm{NaN}\) 等。 - - - - -指数位 E -分数位 \(\mathrm{N} = 0\) -分数位 \(\mathrm{N} \ne 0\) -计算公式 - - - - -\(0\) -\(\pm 0\) -次正规数 -\((-1)^{\mathrm{S}} \times 2^{-126} \times (0.\mathrm{N})\) - - -\(1, 2, \dots, 254\) -正规数 -正规数 -\((-1)^{\mathrm{S}} \times 2^{(\mathrm{E} -127)} \times (1.\mathrm{N})\) - - -\(255\) -\(\pm \infty\) -\(\mathrm{NaN}\) - - - - - -特别地,次正规数显著提升了浮点数的精度,这是因为: - -最小正正规数为 \(2^{-126} \approx 1.18 \times 10^{-38}\) ; -最小正次正规数为 \(2^{-126} \times 2^{-23} \approx 1.4 \times 10^{-45}\) ; - -双精度 double 也采用类似 float 的表示方法,此处不再详述。 -基本数据类型与数据结构的关系¶ -我们知道,数据结构是在计算机中组织与存储数据的方式,它的核心是“结构”,而非“数据”。如果想要表示“一排数字”,我们自然会想到使用「数组」数据结构。数组的存储方式可以表示数字的相邻关系、顺序关系,但至于具体存储的是整数 int 、小数 float 、还是字符 char ,则与“数据结构”无关。换句话说,基本数据类型提供了数据的“内容类型”,而数据结构提供了数据的“组织方式”。 +那么,基本数据类型与数据结构之间有什么联系与区别呢?我们知道,数据结构是在计算机中组织与存储数据的方式。它的主语是“结构”,而非“数据”。如果想要表示“一排数字”,我们自然会想到使用数组。这是因为数组的线性结构可以表示数字的相邻关系和顺序关系,但至于存储的内容是整数 int 、小数 float 、还是字符 char ,则与“数据结构”无关。 +换句话说,基本数据类型提供了数据的“内容类型”,而数据结构提供了数据的“组织方式”。如以下代码所示,我们可以使用不同基本数据类型来初始化数组。 JavaC++PythonGoJavaScriptTypeScriptCC#SwiftZig @@ -2160,14 +2007,6 @@ -3.1.2. 计算机内存¶ -在计算机中,内存和硬盘是两种主要的存储硬件设备。「硬盘」主要用于长期存储数据,容量较大(通常可达到 TB 级别)、速度较慢。「内存」用于运行程序时暂存数据,速度较快,但容量较小(通常为 GB 级别)。 -在算法运行过程中,相关数据都存储在内存中。下图展示了一个计算机内存条,其中每个黑色方块都包含一块内存空间。我们可以将内存想象成一个巨大的 Excel 表格,其中每个单元格都可以存储 1 byte 的数据,在算法运行时,所有数据都被存储在这些单元格中。 -系统通过「内存地址 Memory Location」来访问目标内存位置的数据。计算机根据特定规则为表格中的每个单元格分配编号,确保每个内存空间都有唯一的内存地址。有了这些地址,程序便可以访问内存中的数据。 - - Fig. 内存条、内存空间、内存地址 - -在数据结构与算法的设计中,内存资源是一个重要的考虑因素。内存是所有程序的共享资源,当内存被某个程序占用时,其他程序无法同时使用。我们需要根据剩余内存资源的实际情况来设计算法。例如,算法所占用的内存峰值不应超过系统剩余空闲内存;如果运行的程序很多并且缺少大量连续的内存空间,那么所选用的数据结构必须能够存储在离散的内存空间内。 @@ -2245,7 +2084,7 @@ - + @@ -2254,20 +2093,20 @@ 上一页 - 2.4. 小结 + 3.1. 数据结构分类 - +
谈及计算机中的数据,我们会想到文本、图片、视频、语音、3D 模型等各种形式。尽管这些数据的组织形式各异,但它们都由各种基本数据类型构成。
「基本数据类型」是 CPU 可以直接进行运算的类型,在算法中直接被使用。
基本数据类型是 CPU 可以直接进行运算的类型,在算法中直接被使用。它包括:
byte
short
int
long
float
double
char
bool
所有基本数据类型都以二进制的形式存储在计算机中。在计算机中,我们将 \(1\) 个二进制位称为 \(1\) 比特,并规定 \(1\) 字节(byte)由 \(8\) 比特(bits)组成。基本数据类型的取值范围取决于其占用的空间大小,例如:
下表列举了各种基本数据类型的占用空间、取值范围和默认值。此表格无需硬背,大致理解即可,需要时可以通过查表来回忆。
以上表格中,加粗项在算法题中最为常用。此表格无需硬背,大致理解即可,需要时可以通过查表来回忆。
整数的取值范围取决于变量使用的内存长度,即字节(或比特)数。在计算机中,1 字节 (byte) = 8 比特 (bit),1 比特即 1 个二进制位。以 int 类型为例:
其他整数类型 byte, short, long 的取值范围的计算方法与 int 类似,在此不再赘述。
Note
本书中,标题后的 * 符号代表选读章节。如果你觉得理解困难,建议先跳过,等学完必读章节后再单独攻克。
细心的你可能会发现:int 和 float 长度相同,都是 4 bytes,但为什么 float 的取值范围远大于 int ?按理说 float 需要表示小数,取值范围应该变小才对。
实际上,这是因为浮点数 float 采用了不同的表示方式。根据 IEEE 754 标准,32-bit 长度的 float 由以下部分构成:
设 32-bit 二进制数的第 \(i\) 位为 \(b_i\) ,则 float 值的计算方法定义为:
转化到十进制下的计算公式为
其中各项的取值范围为
Fig. IEEE 754 标准下的 float 表示方式
以上图为例,\(\mathrm{S} = 0\) , \(\mathrm{E} = 124\) ,\(\mathrm{N} = 2^{-2} + 2^{-3} = 0.375\) ,易得
现在我们可以回答最初的问题:float 的表示方式包含指数位,导致其取值范围远大于 int 。根据以上计算,float 可表示的最大正数为 \(2^{254 - 127} \times (2 - 2^{-23}) \approx 3.4 \times 10^{38}\) ,切换符号位便可得到最小负数。
尽管浮点数 float 扩展了取值范围,但其副作用是牺牲了精度。整数类型 int 将全部 32 位用于表示数字,数字是均匀分布的;而由于指数位的存在,浮点数 float 的数值越大,相邻两个数字之间的差值就会趋向越大。
进一步地,指数位 \(E = 0\) 和 \(E = 255\) 具有特殊含义,用于表示零、无穷大、\(\mathrm{NaN}\) 等。
特别地,次正规数显著提升了浮点数的精度,这是因为:
双精度 double 也采用类似 float 的表示方法,此处不再详述。
我们知道,数据结构是在计算机中组织与存储数据的方式,它的核心是“结构”,而非“数据”。如果想要表示“一排数字”,我们自然会想到使用「数组」数据结构。数组的存储方式可以表示数字的相邻关系、顺序关系,但至于具体存储的是整数 int 、小数 float 、还是字符 char ,则与“数据结构”无关。换句话说,基本数据类型提供了数据的“内容类型”,而数据结构提供了数据的“组织方式”。
那么,基本数据类型与数据结构之间有什么联系与区别呢?我们知道,数据结构是在计算机中组织与存储数据的方式。它的主语是“结构”,而非“数据”。如果想要表示“一排数字”,我们自然会想到使用数组。这是因为数组的线性结构可以表示数字的相邻关系和顺序关系,但至于存储的内容是整数 int 、小数 float 、还是字符 char ,则与“数据结构”无关。
换句话说,基本数据类型提供了数据的“内容类型”,而数据结构提供了数据的“组织方式”。如以下代码所示,我们可以使用不同基本数据类型来初始化数组。
在计算机中,内存和硬盘是两种主要的存储硬件设备。「硬盘」主要用于长期存储数据,容量较大(通常可达到 TB 级别)、速度较慢。「内存」用于运行程序时暂存数据,速度较快,但容量较小(通常为 GB 级别)。
在算法运行过程中,相关数据都存储在内存中。下图展示了一个计算机内存条,其中每个黑色方块都包含一块内存空间。我们可以将内存想象成一个巨大的 Excel 表格,其中每个单元格都可以存储 1 byte 的数据,在算法运行时,所有数据都被存储在这些单元格中。
系统通过「内存地址 Memory Location」来访问目标内存位置的数据。计算机根据特定规则为表格中的每个单元格分配编号,确保每个内存空间都有唯一的内存地址。有了这些地址,程序便可以访问内存中的数据。
Fig. 内存条、内存空间、内存地址
在数据结构与算法的设计中,内存资源是一个重要的考虑因素。内存是所有程序的共享资源,当内存被某个程序占用时,其他程序无法同时使用。我们需要根据剩余内存资源的实际情况来设计算法。例如,算法所占用的内存峰值不应超过系统剩余空闲内存;如果运行的程序很多并且缺少大量连续的内存空间,那么所选用的数据结构必须能够存储在离散的内存空间内。