0

0

c++中如何使用std::ratio_multiply进行比例乘法_c++编译期计算【汇总】

穿越時空

穿越時空

发布时间:2026-01-22 12:02:02

|

886人浏览过

|

来源于php中文网

原创

std::ratio_multiply是C++11引入的编译期ratio乘法模板别名,用于在类型层面相乘两个std::ratio并自动约简,所有运算在编译期完成且零运行时代价。

c++中如何使用std::ratio_multiply进行比例乘法_c++编译期计算【汇总】

std::ratio_multiply 是什么,它真能做编译期比例运算?

是的,std::ratio_multiply 是 C++11 引入的编译期有理数运算工具,用于在类型层面相乘两个 std::ratio,结果仍是 std::ratio 类型,所有计算(分子、分母约分)都在编译期完成,零运行时代价。

它不是函数,而是一个模板别名(C++11 起定义为 template using ratio_multiply = ...),所以不能传变量,只能传字面量 ratio 类型。

  • 常见错误:试图用它乘运行时值,比如 ratio_multiply::numr1r2 是变量 —— 编译失败,因为模板参数必须是类型
  • 正确用法:只和字面量 ratio 类型组合,例如 std::kilostd::mega、或自定义的 std::ratio
  • 底层原理:它自动调用 std::gcdstd::lcm(C++17 起)对分子分母做最大公约数约简,确保结果最简

怎么写一个合法的 std::ratio_multiply 表达式?

必须保证两个操作数都是 std::ratio 类型(包括标准库预定义的如 std::milli),且结果可表示为整型常量表达式(即不溢出 intmax_t)。

示例中所有内容都可在 constexpr 上下文使用:

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

Kive
Kive

一站式AI图像生成和管理平台

下载
using r1 = std::ratio<2, 3>;
using r2 = std::ratio<5, 4>;
using product = std::ratio_multiply; // 等价于 ratio<10, 12> → 自动约简为 ratio<5, 6>

static_assert(product::num == 5, ""); static_assert(product::den == 6, "");

// 复合使用:毫秒 × 千 = 秒 using ms = std::milli; using k = std::kilo; using ms_times_k = std::ratio_multiply; // milli × kilo = ratio<1, 1> → 1:1,即 1 毫秒 × 1000 = 1 秒 static_assert(ms_times_k::num == 1 && ms_times_k::den == 1, "");

  • 注意:如果乘积导致分子或分母溢出(比如 ratio 相乘),编译器行为未定义,多数会报错或静默截断(取决于实现)
  • std::ratio_multiply 的等效计算是:ratio<:num r2::num gcd r1::den r2::den>,但你完全不用手算
  • 不要尝试用 double 或浮点字面量参与——std::ratio 只接受整型模板参数

和 std::ratio_add / std::ratio_divide 混用时要注意什么?

它们彼此独立,但组合使用时容易忽略约简时机和中间类型的精度限制。

  • std::ratio_add 要求先通分(分母取 lcm),再加分子;若 A::denB::den 很大,lcm 可能溢出,而 ratio_multiply 不涉及 lcm,相对更“安全”
  • 链式运算如 ratio_multiply, C> 是合法的,但建议用 using 拆解,否则嵌套过深影响可读性和错误定位
  • 标准库没提供 ratio_power,要算平方得写两次 ratio_multiply,三次就再套一层
  • C++17 前,std::gcd/std::lcm 未标准化,部分老编译器(如 GCC 4.9)可能用内部实现,但 ratio_multiply 本身仍可用

实际工程中哪些地方真正需要它?

主要出现在单位系统建模、硬件寄存器配置、定时器周期换算等要求**绝对编译期确定性**的场景。

  • 时间单位转换:把 “128 MHz 时钟 × 256 分频 × 1.5 倍频” 全部展开为 ratio 运算,生成最终频率类型,供 std::chrono::duration 使用
  • ADC 采样率配置:输入是 ratio(1 MHz),经两级分频 ratioratio,用 ratio_multiply 链式组合得到最终采样间隔
  • 避免宏或浮点常量:用 ratio 替代 #define CLK_DIV 256constexpr double clk_div = 256.0;,获得类型安全与编译期检查
  • 但它不适合动态配置——比如用户从串口输入分频系数,那就得用运行时计算,ratio_multiply 此时无用武之地

最容易被忽略的一点:std::ratio_multiply 的结果类型名极长(尤其嵌套后),调试时看编译错误信息会非常痛苦;建议始终用 using 给中间结果起短名,并搭配 static_assert 校验关键值。

相关专题

更多
java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1490

2023.10.24

typedef和define区别
typedef和define区别

typedef和define区别在类型检查、作用范围、可读性、错误处理和内存占用等。本专题为大家提供typedef和define相关的文章、下载、课程内容,供大家免费下载体验。

107

2023.09.26

define的用法
define的用法

define用法:1、定义常量;2、定义函数宏:3、定义条件编译;4、定义多行宏。更多关于define的用法的内容,大家可以阅读本专题下的文章。

335

2023.10.11

c++怎么把double转成int
c++怎么把double转成int

本专题整合了 c++ double相关教程,阅读专题下面的文章了解更多详细内容。

53

2025.08.29

C++中int、float和double的区别
C++中int、float和double的区别

本专题整合了c++中int和double的区别,阅读专题下面的文章了解更多详细内容。

100

2025.10.23

class在c语言中的意思
class在c语言中的意思

在C语言中,"class" 是一个关键字,用于定义一个类。想了解更多class的相关内容,可以阅读本专题下面的文章。

466

2024.01.03

python中class的含义
python中class的含义

本专题整合了python中class的相关内容,阅读专题下面的文章了解更多详细内容。

13

2025.12.06

Golang 性能分析与pprof调优实战
Golang 性能分析与pprof调优实战

本专题系统讲解 Golang 应用的性能分析与调优方法,重点覆盖 pprof 的使用方式,包括 CPU、内存、阻塞与 goroutine 分析,火焰图解读,常见性能瓶颈定位思路,以及在真实项目中进行针对性优化的实践技巧。通过案例讲解,帮助开发者掌握 用数据驱动的方式持续提升 Go 程序性能与稳定性。

2

2026.01.22

html编辑相关教程合集
html编辑相关教程合集

本专题整合了html编辑相关教程合集,阅读专题下面的文章了解更多详细内容。

40

2026.01.21

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
React 教程
React 教程

共58课时 | 4万人学习

Pandas 教程
Pandas 教程

共15课时 | 0.9万人学习

ASP 教程
ASP 教程

共34课时 | 3.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号