每周技巧 #175:C++14 和 C++17 中字面常量的变化

本节阅读量:

本文翻译自 Abseil 官网的 Tip of the Week #175: Changes to Literal Constants in C++14 and C++17

原文最初作为 TotW #175 发布于 2020 年 1 月 30 日。

作者:James Dennett

更新于 2020 年 4 月 6 日。

快捷链接:abseil.io/tips/175

“唯一不变的就是变化。” – Melissa Etheridge

概览

C++ 现在有一些特性,可以让数字字面量更易读。

整数文字现在可以写成二进制(0b00101010),也可以继续使用自古以来就支持的十进制(42)、十六进制(0x2A)和八进制(052)格式。

单引号(')可作为数字分隔符,用于对任意进制数字字面量分组(0xDEAD'C0DE)。

浮点字面量可以用十六进制表示(0x2A0p-4)。

二进制字面量

在操作位集合或处理底层协议时,0b1110'0000 这样的二进制字面量可能比十六进制(次优选择)更易读。

数字分隔符

C++14 允许使用单引号(')对数字字面量中的数字分组。这些数字分隔符不会影响常量的值;它们唯一的作用是帮助读者。它们能让人一眼看出有多少位数字,并确认没有漏掉。例如,1'000'000'0001000000000 更明显是一十亿(而且与 1e9 不同,它是整数,不是浮点值)。

每组必须有多少位并没有限制,甚至不要求同一个字面量中的分组保持一致:0b1'001'0001 是数字 145 的一种合法写法(对于一个被解释为三个独立字段的字节,这种写法甚至可能有意义)。

十六进制浮点字面量

大多数十进制浮点字面量无法被大多数计算机使用的二进制浮点格式精确表示,而十六进制浮点字面量只要可用位数足够,就能直接映射到浮点位模式。这样可以避免把字面量转换为浮点格式时产生舍入误差(不过如果十六进制数字太多,仍可能有截断误差)。

十六进制浮点字面量用 p(或 P)分隔有效数和指数;十进制浮点字面量则使用 e(或 E)。例如,0x2Ap12 是写出 0x2A << 12 的另一种方式,也就是 0x2A000,只不过它是浮点值,不是整数。因此,我们的风格指南要求把它写成 0x2A.0p12,明确它是浮点值,而不是整数的另一种写法。

指数总是用十进制书写,表示 2 的幂,并且可以为负:0x1p-10 精确等于 1.0/1024

建议

  • 二进制字面量应谨慎使用,只用于关心位操作的代码。
  • 当数字字面量太长,无法一眼看清时,考虑使用数字分隔符。
  • 使用数字分隔符时,采用惯常的分组大小:
    • 十进制中,除非有冲突的惯例(例如某些货币),否则使用三位一组。
    • 二进制中,优选四位(半字节)或八位(八位组/字节)一组,除非这些数字本身有更有意义的语义分组。
    • 十六进制中,使用 2、4 或 8 个十六进制数字一组。

相关阅读

每周技巧 #173:用选项结构体包装参数

上一节

每周技巧 #176:优先使用返回值,而不是输出参数

下一节