实数型: floatdouble

图片

1、概念介绍

实数型(Floating-Point Types),也叫浮点型,用于存储带有小数部分的数字。

  • float: 单精度浮点数。通常占用4个字节(32位),精度较低(约7位有效数字),表示范围也较小。
  • double: 双精度浮点数。通常占用8个字节(64位),是C++中默认的浮点类型。它的精度更高(约15-17位有效数字),表示范围更大。在信息学竞赛中,几乎总是使用 double,因为 float 的精度通常不够。

2、使用步骤

  1. 声明double pi;
  2. 初始化double pi = 3.1415926535;
  3. 使用double area = pi * r * r;

3、算法可视化SVG图示

浮点数在内存中的存储比整数复杂,遵循IEEE 754标准,分为三个部分:符号位(Sign)、指数位(Exponent)和尾数位(Mantissa/Fraction)。

图片

double (8 字节 / 64位) 内存结构

  • S (Sign) : 1位,表示正负。
  • Exponent: 11位,用于存储科学计数法中的指数。
  • Mantissa: 52位,用于存储小数的有效数字。

4、核心特性

  • 非精确性: 浮点数是近似表示。大多数小数(如0.1)无法用二进制精确表示,会导致微小的精度误差
  • 范围广: 可以表示非常大或非常接近于0的数。
  • 比较陷阱: 由于精度误差,绝对不能用 == 直接比较两个浮点数。应该比较它们的差的绝对值是否小于一个极小的数(称为epsilon,如 1e-7)。

5、C++代码基础实现

#include <iostream>
#include <iomanip> // 用于控制输出格式,如 setprecision
#include <cmath>   // 用于数学函数,如 fabs (取绝对值)

int main() {
    // 1. 声明和初始化
    float f_pi = 3.1415926f// 'f'后缀表示 float
    double d_pi = 3.141592653589793;

    std::cout << std::fixed << std::setprecision(10); // 设置固定小数点格式,并显示10位小数
    std::cout << "Float PI: " << f_pi << std::endl;
    std::cout << "Double PI: " << d_pi << std::endl;

    // 2. 演示精度问题
    double a = 0.1;
    double b = 0.2;
    double c = 0.3;
    if (a + b == c) {
        std::cout << "0.1 + 0.2 == 0.3" << std::endl;
    } else {
        std::cout << "0.1 + 0.2 != 0.3" << std::endl// 这行会被输出
        std::cout << "a + b = " << a + b << std::endl;
    }

    // 3. 正确的比较方式
    const double EPSILON = 1e-9// 定义一个极小数
    if (std::fabs((a + b) - c) < EPSILON) {
        std::cout << "abs((a+b)-c) is small enough, they are considered equal." << std::endl;
    }
    
    return 0;
}

6、优化策略

  • 优先使用double: 在竞赛中,除非内存限制极其严格,否则始终使用 double 来避免不必要的精度问题。
  • 避免不必要的浮点运算: 浮点运算比整数运算慢。如果一个问题可以用整数解决(例如,通过扩大倍数将小数转为整数),应优先使用整数。

7、优缺点

  • 优点:
    • 能表示小数和极大/极小的数。
  • 缺点:
    • 存在精度误差,不完全精确。
    • 运算速度慢于整数。
    • 比较复杂,容易出错。

8、应用场景

  • 几何问题: 计算距离、面积、角度等。
  • 科学计算: 物理模拟、数据分析。
  • 需要除法的场景: 计算平均值、比例等,结果可能为小数。

9、扩展

  • long double: 精度更高的浮点类型(通常10或16字节),在极少数需要超高精度的题目中使用。
  • 科学计数法: C++中可以用 e 或 E 表示科学计数法,例如 double light_speed = 2.99792458e8; // 表示 2.99... × 10⁸

10、5个课后配套练习及C++代码实现答案

练习1: 计算圆的面积

  • 题目: 输入一个双精度浮点数 r 代表圆的半径,计算并输出圆的面积。π 取 3.1415926535。

  • 答案:

    #include <iostream>
    #include <iomanip>
    int main() {
        double r;
        const double PI = 3.1415926535;
        std::cin >> r;
        double area = PI * r * r;
        std::cout << std::fixed << std::setprecision(7) << area << std::endl;
        return 0;
    }
    

练习2: 华氏度转摄氏度

  • 题目: 输入一个华氏温度 F,根据公式 C = 5/9 * (F-32) 计算并输出摄氏温度 C

  • 答案:

    #include <iostream>
    #include <iomanip>
    int main() {
        double fahrenheit;
        std::cin >> fahrenheit;
        // 注意:5.0/9.0 确保是浮点数除法
        double celsius = 5.0 / 9.0 * (fahrenheit - 32);
        std::cout << std::fixed << std::setprecision(4) << celsius << std::endl;
        return 0;
    }
    

练习3: 计算平均分

  • 题目: 输入三个浮点数,代表三门课的成绩,计算并输出平均分。

  • 答案:

    #include <iostream>
    #include <iomanip>
    int main() {
        double score1, score2, score3;
        std::cin >> score1 >> score2 >> score3;
        double average = (score1 + score2 + score3) / 3.0;
        std::cout << std::fixed << std::setprecision(2) << average << std::endl;
        return 0;
    }
    

练习4: 两点间距离

  • 题目: 输入四个浮点数 x1, y1, x2, y2,代表平面上两个点的坐标,计算并输出这两点间的欧几里得距离。

  • 答案:

    #include <iostream>
    #include <iomanip>
    #include <cmath> // for sqrt
    int main() {
        double x1, y1, x2, y2;
        std::cin >> x1 >> y1 >> x2 >> y2;
        double dx = x1 - x2;
        double dy = y1 - y2;
        double distance = std::sqrt(dx * dx + dy * dy);
        std::cout << std::fixed << std::setprecision(5) << distance << std::endl;
        return 0;
    }
    

练习5: 判断三角形

  • 题目: 输入三个浮点数 a, b, c,判断它们是否能构成一个三角形。

  • 答案: (提示:两边之和大于第三边,注意浮点数比较)

    #include <iostream>
    #include <cmath>
    int main() {
        double a, b, c;
        std::cin >> a >> b >> c;
        const double EPSILON = 1e-9;
        if ((a + b > c + EPSILON) && (a + c > b + EPSILON) && (b + c > a + EPSILON)) {
            std::cout << "Yes" << std::endl;
        } else {
            std::cout << "No" << std::endl;
        }
        return 0;
    }
    

11、相关网络资源推荐

  • cppreference.com - Floating-point types - 浮点类型的权威参考。
  • What Every Computer Scientist Should Know About Floating-Point Arithmetic - 深入理解浮点数误差的经典文章。
  • OI Wiki - 浮点数 - 竞赛角度的浮点数讲解。
本站提供的所有下载资源均来自互联网,仅提供学习交流使用,版权归原作者所有。如需商业使用,请联系原作者获得授权。 如您发现有涉嫌侵权的内容,请联系我们 邮箱:[email protected]