C++怎么求绝对值 C++常用数学函数库汇总【手册】

1次阅读

std::abs 可统一包含 调用,自动匹配整数和浮点数重载;若只含 对 double 调用 abs,会隐式截断为 int

C++怎么求绝对值 C++常用数学函数库汇总【手册】

std::abs 求整数和浮点数的绝对值

直接调用 std::abs 就行,它在 <cstdlib></cstdlib>(对整数)和 <cmath></cmath>(对浮点数)里都有重载,但现代 c++ 推荐统一包含 <cmath></cmath> 后使用——编译器会自动选对版本。

常见错误是只包含 <cstdlib></cstdlib> 然后对 double 调用 abs,结果调到 C 风格的 int abs(int),导致隐式截断:

double x = -3.14; std::cout << abs(x); // ❌ 可能输出 -3(被转成 int 再取 abs)

正确写法:

  • 统一包含 <cmath></cmath>
  • std::abs(带命名空间),避免宏或 C 版本干扰
  • long longFloatdoublelong double 都能安全工作

std::absfabs 有什么区别

fabs 是纯 C 风格函数,只接受浮点类型(doublefloatlong double),定义在 <cmath></cmath>std::abs 是 C++ 重载版本,覆盖整型浮点型,语义更一致。

立即学习C++免费学习笔记(深入)”;

实际影响不大,但混用容易出问题:

  • fabs(-5) 会把 int 隐式转成 double,多一次转换,无害但不必要
  • std::abs(-5LL) 能直接处理 long long,而 fabs 不支持整型参数
  • 某些老编译器(如旧版 MSVC)对 fabsffloat 版)支持不稳定,std::abs 更可靠

复数、自定义类型的绝对值怎么算

std::absstd::complex<t></t> 也提供重载,返回模长(即 sqrt(real² + imag²)),头文件仍是 <cmath></cmath>

自定义类型不能直接用 std::abs,除非你显式提供重载:

  • 在自己命名空间里定义 abs(const MyType&) 函数
  • 确保它被 ADL(参数依赖查找)发现:函数必须和 MyType 在同一命名空间
  • 别试图在 std 命名空间里加东西——这是未定义行为

例如:

namespace mylib {     struct Vec2 { float x, y; };     float abs(const Vec2& v) { return std::sqrt(v.x*v.x + v.y*v.y); } } mylib::Vec2 v{3,4}; std::cout << abs(v); // ✅ 正确触发 ADL

性能和跨平台要注意什么

std::abs 基本是零开销抽象:整数版常被编译器优化为单条 cdq/ xor/sub 指令;浮点版通常映射到 CPU 的 andps(x86)或 fabs(ARM)指令。

但有三个实际坑点:

  • 在嵌入式平台(如 ARM Cortex-M0),没 FPU 时 std::abs(float) 可能链接到软件浮点库,体积和速度都受影响
  • 启用 -ffast-math 时,某些编译器可能把 std::abs(x) 替换成位操作,但会破坏 NaN/符号零行为
  • windows 上用 MinGW 编译时,若链接了旧版 libstdc++std::abs(long long) 可能缺失,得换用 _abs64 或改用 llabs

真正在意性能或兼容性时,别只看函数名——查生成汇编,或者跑个 nm 看符号是否真实存在。

text=ZqhQzanResources