📜  为什么浮点值不代表精确值

📅  最后修改于: 2021-10-28 02:17:07             🧑  作者: Mango

浮点数用作数学实数的粗略近似。它们不代表确切的值。为此,我们将浮点变量的算术结果与最小容差值进行比较。
例子:

C++
// C++ program to illustrate the
// floating point values
#include 
using namespace std;
 
// Driver Code
int main()
{
    double num1 = 10000.29;
    double num2 = 10000.2;
 
    // Output should be 0.0900000000
    cout << std::setprecision(15)
         << (num1 - num2);
    return 0;
}


Java
// Java program to illustrate the
// floating point values
import java.text.DecimalFormat;
 
class GFG{
 
// Driver Code
public static void main(String[] args)
{
    double num1 = 10000.29;
    double num2 = 10000.2;
 
    // Output should be 0.0900000000
    DecimalFormat df = new DecimalFormat(
        "#.################");
         
    System.out.println(df.format(num1 - num2));
}
}
 
// This code is contributed by 29AjayKumar


Python3
# Python3 program to illustrate
# the floating povalues
# Driver Code
if __name__ == '__main__':
    num1 = 10000.29;
    num2 = 10000.2;
 
    # Output should be 0.0900000000
    print ("{0:.10f}".format(num1 - num2));
 
# This code is contributed by Rajput-Ji


C#
// C# program to illustrate the
// floating point values
using System;
 
class GFG{
 
// Driver Code
public static void Main(String[] args)
{
    double num1 = 10000.29;
    double num2 = 10000.2;
 
    // Output should be 0.0900000000
    Console.WriteLine(
        string.Format("{0:F15}",
        Decimal.Parse((num1 - num2).ToString())));
}
}
 
// This code is contributed by 29AjayKumar


输出:
0.0900000000001455


解释:
预期输出为 0.09 作为输出。但是,输出不是 0.09。要理解这一点,您首先必须了解计算机如何处理浮点值。一个浮点变量初始化时,计算机将其作为指数值,分配4个字节(32位)内存,其中尾数部分占24位指数部分占7位,剩下的1位用来表示符号。
对于 double 类型,计算机执行相同的操作,但与 float 类型相比分配更大的内存。在十进制系统中,小数部分中从(从左到右)的每个位置都是其左侧位置的十分之一。如果我们从右向左移动,那么每个位置都是其右侧位置的 10 倍。
在二进制系统中,因子为 2,如下表所示:

16 8 4 2 1 . \frac{1}{2} \frac{1}{4} \frac{1}{8}
2^4 2^3 2^2 2^1 2^0 . 2^{-1} 2^{-2} 2^{-3}

为简化起见,让我们考虑一个名为 small float(见上图)的神话类型,它仅由 5 位组成——与 float 和 double 相比非常小。 small float 类型的前三位代表尾数,后两位代表指数部分。为简单起见,我们不考虑符号。所以尾数部分只能有 8 个可能的值,指数部分只能有 4 个可能的值。请参阅下表:

bit pattern binary value decimal value
000 (0.000)2 0.000
001 (0.001)2 0.125
010 (0.010)2 0.250
011 (0.011)2 0.375
100 (0.100)2 0.500
101 (0.101)2 0.625
110 (0.110)2 0.750
111 (0.111)2 0.875
Binary pattern Binary value Decimal value
00 (00)2 1
01 (01)2 2
10 (10)2 4
11 (11)2 8

因此,尾数和指数部分的一种组合可以是 11100,其中最左边的两位代表指数部分,其余三位代表尾数部分。该值计算如下:

从这两个表中,我们可以很容易地说,一个小浮点数只能包含32个数字,神话类型的范围是0到7。范围不是同样密集。如果您仔细查看下图,您会发现大多数值都在 0 和 1 之间。从右向左移动得越多,数字就越稀疏。

小浮点数不能代表1.3、2.4、5.6 等。在这种情况下,小浮点数接近它们。它不能表示大于 7 的数字。此外,许多组合表示相同的值。例如: 00000, 00001, 00010, 00011表示相同的十进制值,即 (0.000)。 32 种组合中有 12 种是多余的。
如果我们增加分配给小浮点数的位数,密集部分会增加。由于浮点值保留 32 位,因此与小浮点数相比,浮点值可以表示更多的数字。但是使用浮点值和双精度值可以观察到一些问题。没有办法克服这一点。具有无限内存和快速预处理器的计算机只能计算精确的浮点数或双精度值,这对我们来说是一种幻想。

想要从精选的视频和练习题中学习,请查看C++ 基础课程,从基础到高级 C++ 和C++ STL 课程,了解语言和 STL。要完成从学习语言到 DS Algo 等的准备工作,请参阅完整的面试准备课程