This commit is contained in:
krahets
2025-12-31 19:38:45 +08:00
parent fdc032e300
commit f31cbc3f9f
474 changed files with 130810 additions and 103691 deletions

View File

@@ -37,7 +37,7 @@
<title>3.3 Number encoding * - Hello Algo</title>
<title>3.3 Number Encoding * - Hello Algo</title>
@@ -58,8 +58,8 @@
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,300i,400,400i,700,700i%7CRoboto+Mono:400,400i,700,700i&display=fallback">
<style>:root{--md-text-font:"Roboto";--md-code-font:"Roboto Mono"}</style>
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Lato:300,300i,400,400i,700,700i%7CJetBrains+Mono:400,400i,700,700i&display=fallback">
<style>:root{--md-text-font:"Lato";--md-code-font:"JetBrains Mono"}</style>
@@ -154,7 +154,7 @@
<div class="md-header__topic" data-md-component="header-topic">
<span class="md-ellipsis">
3.3 Number encoding *
3.3 Number Encoding *
</span>
</div>
@@ -371,7 +371,7 @@
<span class="md-ellipsis">
Before starting
Before Starting
@@ -388,7 +388,7 @@
<span class="md-nav__icon md-icon"></span>
Before starting
Before Starting
</label>
@@ -487,7 +487,7 @@
<span class="md-ellipsis">
0.1 About this book
0.1 About This Book
@@ -515,7 +515,7 @@
<span class="md-ellipsis">
0.2 How to read
0.2 How to Use This Book
@@ -604,7 +604,7 @@
<span class="md-ellipsis">
Chapter 1. Encounter with algorithms
Chapter 1. Encounter With Algorithms
@@ -626,7 +626,7 @@
<span class="md-nav__icon md-icon"></span>
Chapter 1. Encounter with algorithms
Chapter 1. Encounter With Algorithms
</label>
@@ -648,7 +648,7 @@
<span class="md-ellipsis">
1.1 Algorithms are everywhere
1.1 Algorithms Are Everywhere
@@ -676,7 +676,7 @@
<span class="md-ellipsis">
1.2 What is an algorithm
1.2 What Is an Algorithm
@@ -769,7 +769,7 @@
<span class="md-ellipsis">
Chapter 2. Complexity analysis
Chapter 2. Complexity Analysis
@@ -791,7 +791,7 @@
<span class="md-nav__icon md-icon"></span>
Chapter 2. Complexity analysis
Chapter 2. Complexity Analysis
</label>
@@ -813,7 +813,7 @@
<span class="md-ellipsis">
2.1 Algorithm efficiency assessment
2.1 Algorithm Efficiency Evaluation
@@ -841,7 +841,7 @@
<span class="md-ellipsis">
2.2 Iteration and recursion
2.2 Iteration and Recursion
@@ -869,7 +869,7 @@
<span class="md-ellipsis">
2.3 Time complexity
2.3 Time Complexity
@@ -897,7 +897,7 @@
<span class="md-ellipsis">
2.4 Space complexity
2.4 Space Complexity
@@ -992,7 +992,7 @@
<span class="md-ellipsis">
Chapter 3. Data structures
Chapter 3. Data Structures
@@ -1014,7 +1014,7 @@
<span class="md-nav__icon md-icon"></span>
Chapter 3. Data structures
Chapter 3. Data Structures
</label>
@@ -1036,7 +1036,7 @@
<span class="md-ellipsis">
3.1 Classification of data structures
3.1 Classification of Data Structures
@@ -1064,7 +1064,7 @@
<span class="md-ellipsis">
3.2 Basic data types
3.2 Basic Data Types
@@ -1101,7 +1101,7 @@
<span class="md-ellipsis">
3.3 Number encoding *
3.3 Number Encoding *
@@ -1119,7 +1119,7 @@
<span class="md-ellipsis">
3.3 Number encoding *
3.3 Number Encoding *
@@ -1145,10 +1145,10 @@
<ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
<li class="md-nav__item">
<a href="#331-integer-encoding" class="md-nav__link">
<a href="#331-sign-magnitude-1s-complement-and-2s-complement" class="md-nav__link">
<span class="md-ellipsis">
3.3.1 &nbsp; Integer encoding
3.3.1 &nbsp; Sign-Magnitude, 1's Complement, and 2's Complement
</span>
</a>
@@ -1159,7 +1159,7 @@
<a href="#332-floating-point-number-encoding" class="md-nav__link">
<span class="md-ellipsis">
3.3.2 &nbsp; Floating-point number encoding
3.3.2 &nbsp; Floating-Point Number Encoding
</span>
</a>
@@ -1189,7 +1189,7 @@
<span class="md-ellipsis">
3.4 Character encoding *
3.4 Character Encoding *
@@ -1282,7 +1282,7 @@
<span class="md-ellipsis">
Chapter 4. Array and linked list
Chapter 4. Array and Linked List
@@ -1304,7 +1304,7 @@
<span class="md-nav__icon md-icon"></span>
Chapter 4. Array and linked list
Chapter 4. Array and Linked List
</label>
@@ -1354,7 +1354,7 @@
<span class="md-ellipsis">
4.2 Linked list
4.2 Linked List
@@ -1410,7 +1410,7 @@
<span class="md-ellipsis">
4.4 Memory and cache *
4.4 Memory and Cache *
@@ -1501,7 +1501,7 @@
<span class="md-ellipsis">
Chapter 5. Stack and queue
Chapter 5. Stack and Queue
@@ -1523,7 +1523,7 @@
<span class="md-nav__icon md-icon"></span>
Chapter 5. Stack and queue
Chapter 5. Stack and Queue
</label>
@@ -1601,7 +1601,7 @@
<span class="md-ellipsis">
5.3 Double-ended queue
5.3 Double-Ended Queue
@@ -1692,7 +1692,7 @@
<span class="md-ellipsis">
Chapter 6. Hash table
Chapter 6. Hashing
@@ -1714,7 +1714,7 @@
<span class="md-nav__icon md-icon"></span>
Chapter 6. Hash table
Chapter 6. Hashing
</label>
@@ -1736,7 +1736,7 @@
<span class="md-ellipsis">
6.1 Hash table
6.1 Hash Table
@@ -1764,7 +1764,7 @@
<span class="md-ellipsis">
6.2 Hash collision
6.2 Hash Collision
@@ -1792,7 +1792,7 @@
<span class="md-ellipsis">
6.3 Hash algorithm
6.3 Hash Algorithm
@@ -1931,7 +1931,7 @@
<span class="md-ellipsis">
7.1 Binary tree
7.1 Binary Tree
@@ -1959,7 +1959,7 @@
<span class="md-ellipsis">
7.2 Binary tree traversal
7.2 Binary Tree Traversal
@@ -1987,7 +1987,7 @@
<span class="md-ellipsis">
7.3 Array Representation of tree
7.3 Array Representation of Tree
@@ -2015,7 +2015,7 @@
<span class="md-ellipsis">
7.4 Binary Search tree
7.4 Binary Search Tree
@@ -2043,7 +2043,7 @@
<span class="md-ellipsis">
7.5 AVL tree *
7.5 AVL Tree *
@@ -2206,7 +2206,7 @@
<span class="md-ellipsis">
8.2 Building a heap
8.2 Building a Heap
@@ -2234,7 +2234,7 @@
<span class="md-ellipsis">
8.3 Top-k problem
8.3 Top-K Problem
@@ -2397,7 +2397,7 @@
<span class="md-ellipsis">
9.2 Basic graph operations
9.2 Basic Operations on Graphs
@@ -2425,7 +2425,7 @@
<span class="md-ellipsis">
9.3 Graph traversal
9.3 Graph Traversal
@@ -2564,7 +2564,7 @@
<span class="md-ellipsis">
10.1 Binary search
10.1 Binary Search
@@ -2592,7 +2592,7 @@
<span class="md-ellipsis">
10.2 Binary search insertion
10.2 Binary Search Insertion
@@ -2620,7 +2620,7 @@
<span class="md-ellipsis">
10.3 Binary search boundaries
10.3 Binary Search Edge Cases
@@ -2648,7 +2648,7 @@
<span class="md-ellipsis">
10.4 Hashing optimization strategies
10.4 Hash Optimization Strategy
@@ -2676,7 +2676,7 @@
<span class="md-ellipsis">
10.5 Search algorithms revisited
10.5 Search Algorithms Revisited
@@ -2825,7 +2825,7 @@
<span class="md-ellipsis">
11.1 Sorting algorithms
11.1 Sorting Algorithms
@@ -2853,7 +2853,7 @@
<span class="md-ellipsis">
11.2 Selection sort
11.2 Selection Sort
@@ -2881,7 +2881,7 @@
<span class="md-ellipsis">
11.3 Bubble sort
11.3 Bubble Sort
@@ -2909,7 +2909,7 @@
<span class="md-ellipsis">
11.4 Insertion sort
11.4 Insertion Sort
@@ -2937,7 +2937,7 @@
<span class="md-ellipsis">
11.5 Quick sort
11.5 Quick Sort
@@ -2965,7 +2965,7 @@
<span class="md-ellipsis">
11.6 Merge sort
11.6 Merge Sort
@@ -2993,7 +2993,7 @@
<span class="md-ellipsis">
11.7 Heap sort
11.7 Heap Sort
@@ -3021,7 +3021,7 @@
<span class="md-ellipsis">
11.8 Bucket sort
11.8 Bucket Sort
@@ -3049,7 +3049,7 @@
<span class="md-ellipsis">
11.9 Counting sort
11.9 Counting Sort
@@ -3077,7 +3077,7 @@
<span class="md-ellipsis">
11.10 Radix sort
11.10 Radix Sort
@@ -3170,7 +3170,7 @@
<span class="md-ellipsis">
Chapter 12. Divide and conquer
Chapter 12. Divide and Conquer
@@ -3192,7 +3192,7 @@
<span class="md-nav__icon md-icon"></span>
Chapter 12. Divide and conquer
Chapter 12. Divide and Conquer
</label>
@@ -3214,7 +3214,7 @@
<span class="md-ellipsis">
12.1 Divide and conquer algorithms
12.1 Divide and Conquer Algorithms
@@ -3242,7 +3242,7 @@
<span class="md-ellipsis">
12.2 Divide and conquer search strategy
12.2 Divide and Conquer Search Strategy
@@ -3270,7 +3270,7 @@
<span class="md-ellipsis">
12.3 Building binary tree problem
12.3 Building a Binary Tree Problem
@@ -3298,7 +3298,7 @@
<span class="md-ellipsis">
12.4 Tower of Hanoi Problem
12.4 Hanoi Tower Problem
@@ -3435,7 +3435,7 @@
<span class="md-ellipsis">
13.1 Backtracking algorithms
13.1 Backtracking Algorithm
@@ -3463,7 +3463,7 @@
<span class="md-ellipsis">
13.2 Permutation problem
13.2 Permutations Problem
@@ -3491,7 +3491,7 @@
<span class="md-ellipsis">
13.3 Subset sum problem
13.3 Subset-Sum Problem
@@ -3519,7 +3519,7 @@
<span class="md-ellipsis">
13.4 n queens problem
13.4 N-Queens Problem
@@ -3616,7 +3616,7 @@
<span class="md-ellipsis">
Chapter 14. Dynamic programming
Chapter 14. Dynamic Programming
@@ -3638,7 +3638,7 @@
<span class="md-nav__icon md-icon"></span>
Chapter 14. Dynamic programming
Chapter 14. Dynamic Programming
</label>
@@ -3660,7 +3660,7 @@
<span class="md-ellipsis">
14.1 Introduction to dynamic programming
14.1 Introduction to Dynamic Programming
@@ -3688,7 +3688,7 @@
<span class="md-ellipsis">
14.2 Characteristics of DP problems
14.2 Characteristics of Dynamic Programming Problems
@@ -3716,7 +3716,7 @@
<span class="md-ellipsis">
14.3 DP problem-solving approach
14.3 Dynamic Programming Problem-Solving Approach
@@ -3744,7 +3744,7 @@
<span class="md-ellipsis">
14.4 0-1 Knapsack problem
14.4 0-1 Knapsack Problem
@@ -3772,7 +3772,7 @@
<span class="md-ellipsis">
14.5 Unbounded knapsack problem
14.5 Unbounded Knapsack Problem
@@ -3800,7 +3800,7 @@
<span class="md-ellipsis">
14.6 Edit distance problem
14.6 Edit Distance Problem
@@ -3937,7 +3937,7 @@
<span class="md-ellipsis">
15.1 Greedy algorithms
15.1 Greedy Algorithm
@@ -3965,7 +3965,7 @@
<span class="md-ellipsis">
15.2 Fractional knapsack problem
15.2 Fractional Knapsack Problem
@@ -3993,7 +3993,7 @@
<span class="md-ellipsis">
15.3 Maximum capacity problem
15.3 Maximum Capacity Problem
@@ -4021,7 +4021,7 @@
<span class="md-ellipsis">
15.4 Maximum product cutting problem
15.4 Maximum Product Cutting Problem
@@ -4154,7 +4154,7 @@
<span class="md-ellipsis">
16.1 Installation
16.1 Programming Environment Installation
@@ -4182,7 +4182,7 @@
<span class="md-ellipsis">
16.2 Contributing
16.2 Contributing Together
@@ -4210,7 +4210,7 @@
<span class="md-ellipsis">
16.3 Terminology
16.3 Terminology Table
@@ -4324,10 +4324,10 @@
<ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
<li class="md-nav__item">
<a href="#331-integer-encoding" class="md-nav__link">
<a href="#331-sign-magnitude-1s-complement-and-2s-complement" class="md-nav__link">
<span class="md-ellipsis">
3.3.1 &nbsp; Integer encoding
3.3.1 &nbsp; Sign-Magnitude, 1's Complement, and 2's Complement
</span>
</a>
@@ -4338,7 +4338,7 @@
<a href="#332-floating-point-number-encoding" class="md-nav__link">
<span class="md-ellipsis">
3.3.2 &nbsp; Floating-point number encoding
3.3.2 &nbsp; Floating-Point Number Encoding
</span>
</a>
@@ -4382,24 +4382,24 @@
<!-- Page content -->
<h1 id="33-number-encoding">3.3 &nbsp; Number encoding *<a class="headerlink" href="#33-number-encoding" title="Permanent link">&para;</a></h1>
<h1 id="33-number-encoding">3.3 &nbsp; Number Encoding *<a class="headerlink" href="#33-number-encoding" title="Permanent link">&para;</a></h1>
<div class="admonition tip">
<p class="admonition-title">Tip</p>
<p>In this book, chapters marked with an asterisk '*' are optional readings. If you are short on time or find them challenging, you may skip these initially and return to them after completing the essential chapters.</p>
<p>In this book, chapters marked with an asterisk * are optional readings. If you are short on time or find them challenging, you may skip these initially and return to them after completing the essential chapters.</p>
</div>
<h2 id="331-integer-encoding">3.3.1 &nbsp; Integer encoding<a class="headerlink" href="#331-integer-encoding" title="Permanent link">&para;</a></h2>
<p>In the table from the previous section, we observed that all integer types can represent one more negative number than positive numbers, such as the <code>byte</code> range of <span class="arithmatex">\([-128, 127]\)</span>. This phenomenon seems counterintuitive, and its underlying reason involves knowledge of sign-magnitude, one's complement, and two's complement encoding.</p>
<p>Firstly, it's important to note that <strong>numbers are stored in computers using the two's complement form</strong>. Before analyzing why this is the case, let's define these three encoding methods:</p>
<h2 id="331-sign-magnitude-1s-complement-and-2s-complement">3.3.1 &nbsp; Sign-Magnitude, 1's Complement, and 2's Complement<a class="headerlink" href="#331-sign-magnitude-1s-complement-and-2s-complement" title="Permanent link">&para;</a></h2>
<p>In the table from the previous section, we found that all integer types can represent one more negative number than positive numbers. For example, the <code>byte</code> range is <span class="arithmatex">\([-128, 127]\)</span>. This phenomenon is counterintuitive, and its underlying reason involves knowledge of sign-magnitude, 1's complement, and 2's complement.</p>
<p>First, it should be noted that <strong>numbers are stored in computers in the form of "2's complement"</strong>. Before analyzing the reasons for this, let's first define these three concepts.</p>
<ul>
<li><strong>Sign-magnitude</strong>: The highest bit of a binary representation of a number is considered the sign bit, where <span class="arithmatex">\(0\)</span> represents a positive number and <span class="arithmatex">\(1\)</span> represents a negative number. The remaining bits represent the value of the number.</li>
<li><strong>One's complement</strong>: The one's complement of a positive number is the same as its sign-magnitude. For negative numbers, it's obtained by inverting all bits except the sign bit.</li>
<li><strong>Two's complement</strong>: The two's complement of a positive number is the same as its sign-magnitude. For negative numbers, it's obtained by adding <span class="arithmatex">\(1\)</span> to their one's complement.</li>
<li><strong>Sign-magnitude</strong>: We treat the highest bit of the binary representation of a number as the sign bit, where <span class="arithmatex">\(0\)</span> represents a positive number and <span class="arithmatex">\(1\)</span> represents a negative number, and the remaining bits represent the value of the number.</li>
<li><strong>1's complement</strong>: The 1's complement of a positive number is the same as its sign-magnitude. For a negative number, the 1's complement is obtained by inverting all bits except the sign bit of its sign-magnitude.</li>
<li><strong>2's complement</strong>: The 2's complement of a positive number is the same as its sign-magnitude. For a negative number, the 2's complement is obtained by adding <span class="arithmatex">\(1\)</span> to its 1's complement.</li>
</ul>
<p>Figure 3-4 illustrates the conversions among sign-magnitude, one's complement, and two's complement:</p>
<p><a class="glightbox" href="../number_encoding.assets/1s_2s_complement.png" data-type="image" data-width="100%" data-height="auto" data-desc-position="bottom"><img alt="Conversions between sign-magnitude, one's complement, and two's complement" class="animation-figure" src="../number_encoding.assets/1s_2s_complement.png" /></a></p>
<p align="center"> Figure 3-4 &nbsp; Conversions between sign-magnitude, one's complement, and two's complement </p>
<p>Figure 3-4 shows the conversion methods among sign-magnitude, 1's complement, and 2's complement.</p>
<p><a class="glightbox" href="../number_encoding.assets/1s_2s_complement.png" data-type="image" data-width="100%" data-height="auto" data-desc-position="bottom"><img alt="Conversions among sign-magnitude, 1's complement, and 2's complement" class="animation-figure" src="../number_encoding.assets/1s_2s_complement.png" /></a></p>
<p align="center"> Figure 3-4 &nbsp; Conversions among sign-magnitude, 1's complement, and 2's complement </p>
<p>Although <u>sign-magnitude</u> is the most intuitive, it has limitations. For one, <strong>negative numbers in sign-magnitude cannot be directly used in calculations</strong>. For example, in sign-magnitude, calculating <span class="arithmatex">\(1 + (-2)\)</span> results in <span class="arithmatex">\(-3\)</span>, which is incorrect.</p>
<p><u>Sign-magnitude</u>, although the most intuitive, has some limitations. On one hand, <strong>the sign-magnitude of negative numbers cannot be directly used in operations</strong>. For example, calculating <span class="arithmatex">\(1 + (-2)\)</span> in sign-magnitude yields <span class="arithmatex">\(-3\)</span>, which is clearly incorrect.</p>
<div class="arithmatex">\[
\begin{aligned}
&amp; 1 + (-2) \newline
@@ -4408,85 +4408,85 @@
&amp; \rightarrow -3
\end{aligned}
\]</div>
<p>To address this, computers introduced the <u>one's complement</u>. If we convert to one's complement and calculate <span class="arithmatex">\(1 + (-2)\)</span>, then convert the result back to sign-magnitude, we get the correct result of <span class="arithmatex">\(-1\)</span>.</p>
<p>To solve this problem, computers introduced <u>1's complement</u>. If we first convert sign-magnitude to 1's complement and calculate <span class="arithmatex">\(1 + (-2)\)</span> in 1's complement, then convert the result back to sign-magnitude, we can obtain the correct result of <span class="arithmatex">\(-1\)</span>.</p>
<div class="arithmatex">\[
\begin{aligned}
&amp; 1 + (-2) \newline
&amp; \rightarrow 0000 \; 0001 \; \text{(Sign-magnitude)} + 1000 \; 0010 \; \text{(Sign-magnitude)} \newline
&amp; = 0000 \; 0001 \; \text{(One's complement)} + 1111 \; 1101 \; \text{(One's complement)} \newline
&amp; = 1111 \; 1110 \; \text{(One's complement)} \newline
&amp; = 0000 \; 0001 \; \text{(1's complement)} + 1111 \; 1101 \; \text{(1's complement)} \newline
&amp; = 1111 \; 1110 \; \text{(1's complement)} \newline
&amp; = 1000 \; 0001 \; \text{(Sign-magnitude)} \newline
&amp; \rightarrow -1
\end{aligned}
\]</div>
<p>Additionally, <strong>there are two representations of zero in sign-magnitude</strong>: <span class="arithmatex">\(+0\)</span> and <span class="arithmatex">\(-0\)</span>. This means two different binary encodings for zero, which could lead to ambiguity. For example, in conditional checks, not differentiating between positive and negative zero might result in incorrect outcomes. Addressing this ambiguity would require additional checks, potentially reducing computational efficiency.</p>
<p>On the other hand, <strong>the sign-magnitude of the number zero has two representations, <span class="arithmatex">\(+0\)</span> and <span class="arithmatex">\(-0\)</span></strong>. This means that the number zero corresponds to two different binary encodings, which may cause ambiguity. For example, in conditional judgments, if we don't distinguish between positive zero and negative zero, it may lead to incorrect judgment results. If we want to handle the ambiguity of positive and negative zero, we need to introduce additional judgment operations, which may reduce the computational efficiency of the computer.</p>
<div class="arithmatex">\[
\begin{aligned}
+0 &amp; \rightarrow 0000 \; 0000 \newline
-0 &amp; \rightarrow 1000 \; 0000
\end{aligned}
\]</div>
<p>Like sign-magnitude, one's complement also suffers from the positive and negative zero ambiguity. Therefore, computers further introduced the <u>two's complement</u>. Let's observe the conversion process for negative zero in sign-magnitude, one's complement, and two's complement:</p>
<p>Like sign-magnitude, 1's complement also has the problem of positive and negative zero ambiguity. Therefore, computers further introduced <u>2's complement</u>. Let's first observe the conversion process of negative zero from sign-magnitude to 1's complement to 2's complement:</p>
<div class="arithmatex">\[
\begin{aligned}
-0 \rightarrow \; &amp; 1000 \; 0000 \; \text{(Sign-magnitude)} \newline
= \; &amp; 1111 \; 1111 \; \text{(One's complement)} \newline
= 1 \; &amp; 0000 \; 0000 \; \text{(Two's complement)} \newline
= \; &amp; 1111 \; 1111 \; \text{(1's complement)} \newline
= 1 \; &amp; 0000 \; 0000 \; \text{(2's complement)} \newline
\end{aligned}
\]</div>
<p>Adding <span class="arithmatex">\(1\)</span> to the one's complement of negative zero produces a carry, but with <code>byte</code> length being only 8 bits, the carried-over <span class="arithmatex">\(1\)</span> to the 9<sup>th</sup> bit is discarded. Therefore, <strong>the two's complement of negative zero is <span class="arithmatex">\(0000 \; 0000\)</span></strong>, the same as positive zero, thus resolving the ambiguity.</p>
<p>One last puzzle is the <span class="arithmatex">\([-128, 127]\)</span> range for <code>byte</code>, with an additional negative number, <span class="arithmatex">\(-128\)</span>. We observe that for the interval <span class="arithmatex">\([-127, +127]\)</span>, all integers have corresponding sign-magnitude, one's complement, and two's complement, allowing for mutual conversion between them.</p>
<p>However, <strong>the two's complement <span class="arithmatex">\(1000 \; 0000\)</span> is an exception without a corresponding sign-magnitude</strong>. According to the conversion method, its sign-magnitude would be <span class="arithmatex">\(0000 \; 0000\)</span>, indicating zero. This presents a contradiction because its two's complement should represent itself. Computers designate this special two's complement <span class="arithmatex">\(1000 \; 0000\)</span> as representing <span class="arithmatex">\(-128\)</span>. In fact, the calculation of <span class="arithmatex">\((-1) + (-127)\)</span> in two's complement results in <span class="arithmatex">\(-128\)</span>.</p>
<p>Adding <span class="arithmatex">\(1\)</span> to the 1's complement of negative zero produces a carry, but since the <code>byte</code> type has a length of only 8 bits, the <span class="arithmatex">\(1\)</span> that overflows to the 9<sup>th</sup> bit is discarded. That is to say, <strong>the 2's complement of negative zero is <span class="arithmatex">\(0000 \; 0000\)</span>, which is the same as the 2's complement of positive zero</strong>. This means that in 2's complement representation, there is only one zero, and the positive and negative zero ambiguity is thus resolved.</p>
<p>One last question remains: the range of the <code>byte</code> type is <span class="arithmatex">\([-128, 127]\)</span>, and how is the extra negative number <span class="arithmatex">\(-128\)</span> obtained? We notice that all integers in the interval <span class="arithmatex">\([-127, +127]\)</span> have corresponding sign-magnitude, 1's complement, and 2's complement, and sign-magnitude and 2's complement can be converted to each other.</p>
<p>However, <strong>the 2's complement <span class="arithmatex">\(1000 \; 0000\)</span> is an exception, and it does not have a corresponding sign-magnitude</strong>. According to the conversion method, we get that the sign-magnitude of this 2's complement is <span class="arithmatex">\(0000 \; 0000\)</span>. This is clearly contradictory because this sign-magnitude represents the number <span class="arithmatex">\(0\)</span>, and its 2's complement should be itself. The computer specifies that this special 2's complement <span class="arithmatex">\(1000 \; 0000\)</span> represents <span class="arithmatex">\(-128\)</span>. In fact, the result of calculating <span class="arithmatex">\((-1) + (-127)\)</span> in 2's complement is <span class="arithmatex">\(-128\)</span>.</p>
<div class="arithmatex">\[
\begin{aligned}
&amp; (-127) + (-1) \newline
&amp; \rightarrow 1111 \; 1111 \; \text{(Sign-magnitude)} + 1000 \; 0001 \; \text{(Sign-magnitude)} \newline
&amp; = 1000 \; 0000 \; \text{(One's complement)} + 1111 \; 1110 \; \text{(One's complement)} \newline
&amp; = 1000 \; 0001 \; \text{(Two's complement)} + 1111 \; 1111 \; \text{(Two's complement)} \newline
&amp; = 1000 \; 0000 \; \text{(Two's complement)} \newline
&amp; = 1000 \; 0000 \; \text{(1's complement)} + 1111 \; 1110 \; \text{(1's complement)} \newline
&amp; = 1000 \; 0001 \; \text{(2's complement)} + 1111 \; 1111 \; \text{(2's complement)} \newline
&amp; = 1000 \; 0000 \; \text{(2's complement)} \newline
&amp; \rightarrow -128
\end{aligned}
\]</div>
<p>As you might have noticed, all these calculations are additions, hinting at an important fact: <strong>computers' internal hardware circuits are primarily designed around addition operations</strong>. This is because addition is simpler to implement in hardware compared to other operations like multiplication, division, and subtraction, allowing for easier parallelization and faster computation.</p>
<p>It's important to note that this doesn't mean computers can only perform addition. <strong>By combining addition with basic logical operations, computers can execute a variety of other mathematical operations</strong>. For example, the subtraction <span class="arithmatex">\(a - b\)</span> can be translated into <span class="arithmatex">\(a + (-b)\)</span>; multiplication and division can be translated into multiple additions or subtractions.</p>
<p>We can now summarize the reason for using two's complement in computers: with two's complement representation, computers can use the same circuits and operations to handle both positive and negative number addition, eliminating the need for special hardware circuits for subtraction and avoiding the ambiguity of positive and negative zero. This greatly simplifies hardware design and enhances computational efficiency.</p>
<p>The design of two's complement is quite ingenious, and due to space constraints, we'll stop here. Interested readers are encouraged to explore further.</p>
<h2 id="332-floating-point-number-encoding">3.3.2 &nbsp; Floating-point number encoding<a class="headerlink" href="#332-floating-point-number-encoding" title="Permanent link">&para;</a></h2>
<p>You might have noticed something intriguing: despite having the same length of 4 bytes, why does a <code>float</code> have a much larger range of values compared to an <code>int</code>? This seems counterintuitive, as one would expect the range to shrink for <code>float</code> since it needs to represent fractions.</p>
<p>In fact, <strong>this is due to the different representation method used by floating-point numbers (<code>float</code>)</strong>. Let's consider a 32-bit binary number as:</p>
<p>You may have noticed that all the above calculations are addition operations. This hints at an important fact: <strong>the hardware circuits inside computers are mainly designed based on addition operations</strong>. This is because addition operations are simpler to implement in hardware compared to other operations (such as multiplication, division, and subtraction), easier to parallelize, and have faster operation speeds.</p>
<p>Please note that this does not mean that computers can only perform addition. <strong>By combining addition with some basic logical operations, computers can implement various other mathematical operations</strong>. For example, calculating the subtraction <span class="arithmatex">\(a - b\)</span> can be converted to calculating the addition <span class="arithmatex">\(a + (-b)\)</span>; calculating multiplication and division can be converted to calculating multiple additions or subtractions.</p>
<p>Now we can summarize the reasons why computers use 2's complement: based on 2's complement representation, computers can use the same circuits and operations to handle the addition of positive and negative numbers, without the need to design special hardware circuits to handle subtraction, and without the need to specially handle the ambiguity problem of positive and negative zero. This greatly simplifies hardware design and improves operational efficiency.</p>
<p>The design of 2's complement is very ingenious. Due to space limitations, we will stop here. Interested readers are encouraged to explore further.</p>
<h2 id="332-floating-point-number-encoding">3.3.2 &nbsp; Floating-Point Number Encoding<a class="headerlink" href="#332-floating-point-number-encoding" title="Permanent link">&para;</a></h2>
<p>Careful readers may have noticed: <code>int</code> and <code>float</code> have the same length, both are 4 bytes, but why does <code>float</code> have a much larger range than <code>int</code>? This is very counterintuitive because it stands to reason that <code>float</code> needs to represent decimals, so the range should be smaller.</p>
<p>In fact, <strong>this is because floating-point number <code>float</code> uses a different representation method</strong>. Let's denote a 32-bit binary number as:</p>
<div class="arithmatex">\[
b_{31} b_{30} b_{29} \ldots b_2 b_1 b_0
\]</div>
<p>According to the IEEE 754 standard, a 32-bit <code>float</code> consists of the following three parts:</p>
<p>According to the IEEE 754 standard, a 32-bit <code>float</code> consists of the following three parts.</p>
<ul>
<li>Sign bit <span class="arithmatex">\(\mathrm{S}\)</span>: Occupies 1 bit, corresponding to <span class="arithmatex">\(b_{31}\)</span>.</li>
<li>Exponent bit <span class="arithmatex">\(\mathrm{E}\)</span>: Occupies 8 bits, corresponding to <span class="arithmatex">\(b_{30} b_{29} \ldots b_{23}\)</span>.</li>
<li>Fraction bit <span class="arithmatex">\(\mathrm{N}\)</span>: Occupies 23 bits, corresponding to <span class="arithmatex">\(b_{22} b_{21} \ldots b_0\)</span>.</li>
<li>Sign bit <span class="arithmatex">\(\mathrm{S}\)</span>: occupies 1 bit, corresponding to <span class="arithmatex">\(b_{31}\)</span>.</li>
<li>Exponent bit <span class="arithmatex">\(\mathrm{E}\)</span>: occupies 8 bits, corresponding to <span class="arithmatex">\(b_{30} b_{29} \ldots b_{23}\)</span>.</li>
<li>Fraction bit <span class="arithmatex">\(\mathrm{N}\)</span>: occupies 23 bits, corresponding to <span class="arithmatex">\(b_{22} b_{21} \ldots b_0\)</span>.</li>
</ul>
<p>The value of a binary <code>float</code> number is calculated as:</p>
<p>The calculation method for the value corresponding to the binary <code>float</code> is:</p>
<div class="arithmatex">\[
\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)^{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
\]</div>
<p>Converted to a decimal formula, this becomes:</p>
<p>Converted to decimal, the calculation formula is:</p>
<div class="arithmatex">\[
\text{val} = (-1)^{\mathrm{S}} \times 2^{\mathrm{E} - 127} \times (1 + \mathrm{N})
\text {val}=(-1)^{\mathrm{S}} \times 2^{\mathrm{E} -127} \times (1 + \mathrm{N})
\]</div>
<p>The range of each component is:</p>
<div class="arithmatex">\[
\begin{aligned}
\mathrm{S} \in &amp; \{ 0, 1\}, \quad \mathrm{E} \in \{ 1, 2, \dots, 254 \} \newline
(1 + \mathrm{N}) = &amp; (1 + \sum_{i=1}^{23} b_{23-i} \times 2^{-i}) \subset [1, 2 - 2^{-23}]
(1 + \mathrm{N}) = &amp; (1 + \sum_{i=1}^{23} b_{23-i} 2^{-i}) \subset [1, 2 - 2^{-23}]
\end{aligned}
\]</div>
<p><a class="glightbox" href="../number_encoding.assets/ieee_754_float.png" data-type="image" data-width="100%" data-height="auto" data-desc-position="bottom"><img alt="Example calculation of a float in IEEE 754 standard" class="animation-figure" src="../number_encoding.assets/ieee_754_float.png" /></a></p>
<p align="center"> Figure 3-5 &nbsp; Example calculation of a float in IEEE 754 standard </p>
<p><a class="glightbox" href="../number_encoding.assets/ieee_754_float.png" data-type="image" data-width="100%" data-height="auto" data-desc-position="bottom"><img alt="Calculation example of float under IEEE 754 standard" class="animation-figure" src="../number_encoding.assets/ieee_754_float.png" /></a></p>
<p align="center"> Figure 3-5 &nbsp; Calculation example of float under IEEE 754 standard </p>
<p>Observing Figure 3-5, given an example data <span class="arithmatex">\(\mathrm{S} = 0\)</span>, <span class="arithmatex">\(\mathrm{E} = 124\)</span>, <span class="arithmatex">\(\mathrm{N} = 2^{-2} + 2^{-3} = 0.375\)</span>, we have:</p>
<p>Observing Figure 3-5, given example data <span class="arithmatex">\(\mathrm{S} = 0\)</span>, <span class="arithmatex">\(\mathrm{E} = 124\)</span>, <span class="arithmatex">\(\mathrm{N} = 2^{-2} + 2^{-3} = 0.375\)</span>, we have:</p>
<div class="arithmatex">\[
\text{val} = (-1)^0 \times 2^{124 - 127} \times (1 + 0.375) = 0.171875
\text { val } = (-1)^0 \times 2^{124 - 127} \times (1 + 0.375) = 0.171875
\]</div>
<p>Now we can answer the initial question: <strong>The representation of <code>float</code> includes an exponent bit, leading to a much larger range than <code>int</code></strong>. Based on the above calculation, the maximum positive number representable by <code>float</code> is approximately <span class="arithmatex">\(2^{254 - 127} \times (2 - 2^{-23}) \approx 3.4 \times 10^{38}\)</span>, and the minimum negative number is obtained by switching the sign bit.</p>
<p><strong>However, the trade-off for <code>float</code>'s expanded range is a sacrifice in precision</strong>. The integer type <code>int</code> uses all 32 bits to represent the number, with values evenly distributed; but due to the exponent bit, the larger the value of a <code>float</code>, the greater the difference between adjacent numbers.</p>
<p>Now we can answer the initial question: <strong>the representation of <code>float</code> includes an exponent bit, resulting in a range far greater than <code>int</code></strong>. According to the above calculation, the maximum positive number that <code>float</code> can represent is <span class="arithmatex">\(2^{254 - 127} \times (2 - 2^{-23}) \approx 3.4 \times 10^{38}\)</span>, and the minimum negative number can be obtained by switching the sign bit.</p>
<p><strong>Although floating-point number <code>float</code> expands the range, its side effect is sacrificing precision</strong>. The integer type <code>int</code> uses all 32 bits to represent numbers, and the numbers are evenly distributed; however, due to the existence of the exponent bit, the larger the value of floating-point number <code>float</code>, the larger the difference between two adjacent numbers tends to be.</p>
<p>As shown in Table 3-2, exponent bits <span class="arithmatex">\(\mathrm{E} = 0\)</span> and <span class="arithmatex">\(\mathrm{E} = 255\)</span> have special meanings, <strong>used to represent zero, infinity, <span class="arithmatex">\(\mathrm{NaN}\)</span>, etc.</strong></p>
<p align="center"> Table 3-2 &nbsp; Meaning of exponent bits </p>
@@ -4504,13 +4504,13 @@ b_{31} b_{30} b_{29} \ldots b_2 b_1 b_0
<tr>
<td><span class="arithmatex">\(0\)</span></td>
<td><span class="arithmatex">\(\pm 0\)</span></td>
<td>Subnormal Numbers</td>
<td>Subnormal Number</td>
<td><span class="arithmatex">\((-1)^{\mathrm{S}} \times 2^{-126} \times (0.\mathrm{N})\)</span></td>
</tr>
<tr>
<td><span class="arithmatex">\(1, 2, \dots, 254\)</span></td>
<td>Normal Numbers</td>
<td>Normal Numbers</td>
<td>Normal Number</td>
<td>Normal Number</td>
<td><span class="arithmatex">\((-1)^{\mathrm{S}} \times 2^{(\mathrm{E} -127)} \times (1.\mathrm{N})\)</span></td>
</tr>
<tr>
@@ -4522,8 +4522,8 @@ b_{31} b_{30} b_{29} \ldots b_2 b_1 b_0
</tbody>
</table>
</div>
<p>It's worth noting that subnormal numbers significantly improve the precision of floating-point numbers. The smallest positive normal number is <span class="arithmatex">\(2^{-126}\)</span>, and the smallest positive subnormal number is <span class="arithmatex">\(2^{-126} \times 2^{-23}\)</span>.</p>
<p>Double-precision <code>double</code> also uses a similar representation method to <code>float</code>, which is not elaborated here for brevity.</p>
<p>It is worth noting that subnormal numbers significantly improve the precision of floating-point numbers. The smallest positive normal number is <span class="arithmatex">\(2^{-126}\)</span>, and the smallest positive subnormal number is <span class="arithmatex">\(2^{-126} \times 2^{-23}\)</span>.</p>
<p>Double-precision <code>double</code> also uses a representation method similar to <code>float</code>, which will not be elaborated here.</p>
<!-- Source file information -->
@@ -4546,7 +4546,7 @@ aria-label="Footer"
<a
href="../basic_data_types/"
class="md-footer__link md-footer__link--prev"
aria-label="Previous: 3.2 Basic data types"
aria-label="Previous: 3.2 Basic Data Types"
rel="prev"
>
<div class="md-footer__button md-icon">
@@ -4558,7 +4558,7 @@ aria-label="Footer"
Previous
</span>
<div class="md-ellipsis">
3.2 Basic data types
3.2 Basic Data Types
</div>
</div>
</a>
@@ -4570,7 +4570,7 @@ aria-label="Footer"
<a
href="../character_encoding/"
class="md-footer__link md-footer__link--next"
aria-label="Next: 3.4 Character encoding *"
aria-label="Next: 3.4 Character Encoding *"
rel="next"
>
<div class="md-footer__title">
@@ -4578,7 +4578,7 @@ aria-label="Footer"
Next
</span>
<div class="md-ellipsis">
3.4 Character encoding *
3.4 Character Encoding *
</div>
</div>
<div class="md-footer__button md-icon">
@@ -4671,7 +4671,7 @@ aria-label="Footer"
<nav class="md-footer__inner md-grid" aria-label="Footer" >
<a href="../basic_data_types/" class="md-footer__link md-footer__link--prev" aria-label="Previous: 3.2 Basic data types">
<a href="../basic_data_types/" class="md-footer__link md-footer__link--prev" aria-label="Previous: 3.2 Basic Data Types">
<div class="md-footer__button md-icon">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11z"/></svg>
@@ -4681,20 +4681,20 @@ aria-label="Footer"
Previous
</span>
<div class="md-ellipsis">
3.2 Basic data types
3.2 Basic Data Types
</div>
</div>
</a>
<a href="../character_encoding/" class="md-footer__link md-footer__link--next" aria-label="Next: 3.4 Character encoding *">
<a href="../character_encoding/" class="md-footer__link md-footer__link--next" aria-label="Next: 3.4 Character Encoding *">
<div class="md-footer__title">
<span class="md-footer__direction">
Next
</span>
<div class="md-ellipsis">
3.4 Character encoding *
3.4 Character Encoding *
</div>
</div>
<div class="md-footer__button md-icon">