购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

2.2 数值类型的极限和其他属性

有时,知道并且使用数值类型(如char、int或double)能够表示的最小值和最大值是很有必要的,许多开发人员为此使用标准C语言的宏,例如CHAR_MIN/CHAR_MAX、INT_MIN/INT_MAX和DBL_MIN/DBL_MAX。C++提供了一个名为numeric_limits的类模板,它针对每种数值类型进行了特化,可以帮助你查询数值类型的最小值和最大值。然而,numeric_limits并不局限于这个功能,它还为类型属性查询(例如类型是否有符号,表示其值需要多少位,是否可以表示浮点类型的无穷大等)提供了额外的常量。在C++11之前,numeric_limits<T>的使用受到限制,因为它不能用在需要常量的地方(例如有数组大小和switch语句的地方),因此开发人员更喜欢在他们的代码中使用C语言的宏。C++11中解除了这种限制,因为numeric_limits<T>的所有静态成员现在都是constexpr,这意味着在需要使用常量表达式的任何地方它们都可以被使用。

2.2.1 准备工作

numeric_limits<T>类模板在头文件<limits>的命名空间std中可用。

2.2.2 使用方式

使用std::numeric_limits<T>查询数值类型T的各种属性:

❍ 使用min()和max()静态方法获取类型的最小值和最大值,以下是它们的使用方式示例:

❍ 使用其他静态方法和静态常量检索数值类型的其他属性。在下面的示例中,变量bits是一个std::bitset对象,它包含一系列位,这些位是表示变量n(整数类型)表示的数值所必需的位:

在C++11中,使用std::numeric_limits<T>没有限制,因此,最好在现代C++代码中使用它而不是C语言的宏。

2.2.3 工作原理

std::numeric_limits<T>类模板允许开发人员查询数值类型的属性。实际值可以通过特化获得,标准库为所有内置的数值类型(char、short、int、long、float、double等)提供了特化。此外,第三方可能为其他类型提供附加的实现,例如,实现了bigint整数类型和decimal类型的数值库为这些类型提供了numeric_limits的特化(例如numeric_limits<bigint>和numeric_limits<decimal>)。

以下数值类型的特化在头文件<limits>中可用。需要注意的是,char16_t和char32_t的特化是在C++11中新增的,其他的在C++11之前也可使用。除了前面列出的特化之外,该库还包括这些数值类型的每个cv(const volatile)限定特化版本,它们与非限定的特化是相同的。例如,类型int有4种实际的特化(它们是相同的):numeric_limits<int>、numeric_limits<const int>、numeric_limits<volatile int>、numeric_limits<const volatile int>:

如前所述,在C++11中,std::numeric_limits的所有静态成员都是constexpr,这意味着它们可以用在所有需要常量表达式的地方。与C++宏相比,它们有几个主要的优点:

❍ 它们更容易记住,因为你只需要知道类型的名称,而不是无数的宏名称。

❍ 它们支持C语言中不可用的类型,比如char16_t和char32_t。

❍ 对于不知道类型的模板,它们是唯一可能的解决方案。

❍ 最小值和最大值只是它提供的类型的两个属性,因此它的实际使用范围超出了numeric_limits所给定的属性。出于这个原因,类也许应该被称为numeric_properties,而不是numeric_limits。

下面的函数模板print_type_properties()打印了该类型的最小值和最大值,以及其他信息:

如果对unsigned short、int和double调用print_type_properties()函数,将得到以下输出结果:

请注意digits和digits10常量的区别:

❍ digits表示整数类型的位(不包括符号位)和填充位(如果有的话)的数量,以及浮点类型的尾数位数。

❍ digits10是一种无须更改即可表示的十进制位数的类型。为了更好地理解这一点,我们可以参考上述示例中unsigned short的情况,它是一个16位整数类型,代表0到65536之间的数字,不过最多可以表示5位的十进制数字(即10000到65536),但不能表示所有5位的十进制数字,因为表示从65537到99999的数字需要更多位。因此,在不增加位的情况下它可以表示的最大数字是4位的十进制数字(即从1000到9999),这是由digits10表示的值。对于整数类型,它与常量digits有直接关系;而对于整数类型T,digits10的值为std::numeric_limits<T>::digits * std::log10(2)。

值得一提的是,作为算术类型别名的标准库类型(如std::size_t)也可以使用std::numeric_limits进行检查。另外,其他非算术类型的标准类型(如std::complex<T>或std::nullptr_t)没有std::numeric_limits特化。

2.2.4 延伸阅读

❍ 阅读2.1节,以了解如何在数值类型和字符串类型之间进行转换。 E2dq4KDXkHKkTX3vlqwMoVG9NPj80OOwbZe9ogGKkTAcMrvlIP/7RXaOGCXy44Ja

点击中间区域
呼出菜单
上一章
目录
下一章
×

打开