信奥崔老师:实数型: float、double

实数型: 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++代码基础实现

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++中可以用 eE 表示科学计数法,例如 double light_speed = 2.99792458e8; // 表示 2.99... × 10⁸

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

练习1: 计算圆的面积

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

  • 答案:

    c 复制代码
    #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

  • 答案:

    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: 计算平均分

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

  • 答案:

    c 复制代码
    #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,代表平面上两个点的坐标,计算并输出这两点间的欧几里得距离。

  • 答案:

    c 复制代码
    #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,判断它们是否能构成一个三角形。

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

    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 - 浮点数 - 竞赛角度的浮点数讲解。
相关推荐
Source.Liu5 小时前
【CMakeLists.txt】CMake 编译定义带值参数详解
c++·qt·librecad
知花实央l5 小时前
【数字逻辑】数字逻辑实验实战:74HC151实现逻辑函数+74HC138搭全加器(附接线步骤+避坑指南)
算法·容器·测试用例·逻辑回归
CoovallyAIHub5 小时前
突破性开源模型DepthLM问世:视觉语言模型首次实现精准三维空间理解
深度学习·算法·计算机视觉
程序猿编码5 小时前
轻量级却实用:sigtrace 如何靠 ptrace 实现 Linux 信号的捕获与阻断(C/C++代码实现)
linux·c语言·c++·信号·捕获·ptrace
曦樂~5 小时前
【Qt】TCP连接--客户端和服务器
服务器·网络·c++·qt·tcp/ip
WoodWall5 小时前
WebServer 02 Reactor模式
c++·后端
WaWaJie_Ngen5 小时前
【OpenGL】模板测试(StencilTest)
c++·算法·游戏·游戏引擎·游戏程序·图形渲染
滴_咕噜咕噜5 小时前
【MFC】数据库操作:数据库动态生成
数据库·c++·mfc
WoodWall6 小时前
WebServer 00 重要前置知识
c++·后端