C++ abs 绝对值

在数学中,一个数的绝对值指的是它在数轴上到 0 的距离。简单来说,就是去掉数字前面的负号:正数或 0 的绝对值是它本身,负数的绝对值则是对应的正数。

在 C++ 中,如果想要求一个数的绝对值,我们可以直接调用 <cmath> 头文件中的 std::abs() 函数。

std::abs() 的基本用法

在使用 std::abs() 函数之前,我们需要先在代码顶部通过 #include <cmath> 引入头文件。其中,abs 是英文 “absolute(绝对值)” 的缩写。

语法:

std::abs(x)

说明:

参数 x 可以是 int、long、long long 等有符号整数,也可以是 float、double 等浮点数。调用后,std::abs(x) 会返回 x 的绝对值,且返回值类型与传入的 x 一致。

需要注意的是,如果负整数非常接近 int 的最小边界(如 -2147483648),求绝对值后会超出 int 正数上限 2147483647 而发生溢出。遇到较大整数时,我们可以把变量定义为 long long 类型再求绝对值。

示例 1:求整数和浮点数的绝对值

#include <cmath>
#include <iostream>

int main() {
    int a = -15;
    int b = 20;
    double c = -3.75;

    std::cout << std::abs(a) << '\n';
    std::cout << std::abs(b) << '\n';
    std::cout << std::abs(c) << '\n';
    return 0;
}

运行结果如下。

15
20
3.75

分析:

std::abs(a) 接收的是 int 整数,返回的也是 int 类型的 15。std::abs(c) 接收的是 double 浮点数,由于 C++ 支持函数重载,它会自动匹配对应的浮点数版本,返回 double 类型的 3.75。

注意 在早期 C 语言中,全局的 abs() 只支持整数。如果漏写 std:: 而直接写 abs(-3.75),在部分编译环境下会把小数截断成 3。平时写代码时,小伙伴们记得引入 <cmath> 并统一写成 std::abs()。

std::abs() 的常见应用

在实际开发中,我们很少只是对一个写死的负数求绝对值。std::abs() 最常用于以下 2 种场景:一种是 “计算两个数之间的距离”,另一种是 “判断两个浮点数是否相等”。

1. 计算两个数之间的距离

假设数轴上有两个坐标点,或者程序里有两件商品的价格,我们想知道它们之间 “相差多少”,其实就是求两数之差的绝对值。由于事先不确定哪个数更大,直接相减可能会算出负数,这时在外面套上一层 std::abs() 就能省去先比大小的麻烦。

示例 2:求两数之差的绝对值

#include <cmath>
#include <iostream>

int main() {
    int pos1 = 15;
    int pos2 = 40;

    int distance = std::abs(pos1 - pos2);    // 求两数之差的绝对值
    std::cout << distance << '\n';
    return 0;
}

运行结果如下。

25

分析:

std::abs(pos1 - pos2) 表示计算 pos1 与 pos2 差值的绝对值。这里 15 减去 40 得到 -25,经过 std::abs() 处理后直接变成正数 25。

如果不借助 std::abs(),我们就得先通过 if...else 语句判断谁大谁小,再拿较大的数减去较小的数。对于这个例子来说,下面 2 种方式是等价的。

// 方式 1(推荐)
int distance = std::abs(pos1 - pos2);

// 方式 2
int distance = 0;
if (pos1 > pos2) {
    distance = pos1 - pos2;
} else {
    distance = pos2 - pos1;
}

对比可以看出,方式 1 一行代码就能写完,可读性要好得多。

下面代码中,result 的最终值是 12,小伙伴们可以思考一下为什么。

int x = 3;
int y = 10;
int result = std::abs(-5) + std::abs(x - y);

2. 判断两个浮点数是否相等

由于 double 浮点数在计算机内部采用二进制存储,像 0.1 + 0.2 这样的小数在计算后会存在极微小的精度误差,因此我们不能直接使用 == 来判断两个浮点数是否相等。

在实际开发中,标准的做法是计算两个浮点数之差的绝对值 std::abs(a - b)。只要这个差值小于一个极小的误差上限,我们就认为这两个浮点数相等。常见的误差上限可以设为科学计数法中的 1e-6,也就是 0.000001。下面我们来看一个例子。

示例 3:误差范围内比较浮点数

#include <cmath>
#include <iostream>

int main() {
    double a = 0.1 + 0.2;
    double b = 0.3;

    if (a == b) {
        std::cout << "直接比较:相等\n";
    } else {
        std::cout << "直接比较:不相等\n";
    }

    if (std::abs(a - b) < 1e-6) {
        std::cout << "误差比较:相等\n";
    }
    return 0;
}

运行结果如下。

直接比较:不相等
误差比较:相等

分析:

从运行结果可以看出,在第 1 个 if 判断中直接使用 a == b 比较时,受底层二进制微小误差的影响,程序走到了不相等的分支。

而在第 2 个 if 判断中,由于事先不知道 a 会比 b 略大一点还是略小一点,a - b 的结果既可能是正数,也可能是负数。调用 std::abs(a - b) 去掉负号后,无论误差偏向哪一边,我们只需要判断差值是否小于 1e-6 就能得出准确结论。

上一篇:

下一篇:

给站长反馈

绿叶网正在不断完善中,小伙伴们如果发现任何问题,还望多多给站长反馈,谢谢!

邮箱:lvyenet@vip.qq.com

「绿叶网」服务号
绿叶网服务号放大
关注服务号,微信也能看教程。
绿叶网服务号