uint64_t的最大值的宏常量

34

我正在寻找一个宏来代表uint64_t的最大值,就像UINT_MAX是代表unsigned int的最大值一样。 也就是说,我需要保证这个值为(1<<64)-1。

我尝试使用UINT64_MAX,但在使用g++编译时会出现错误:

'UINT64_MAX' was not declared in this scope

值得一提的是,在使用 UINT64_MAX 之前,我的代码中有这行 #define __STDC_LIMIT_MACROS

令我惊讶的是,在网上没有找到有用的信息。


我不知道#define __STDC_LIMIT_MACROS是什么,但你可能想在包含头文件之前定义它,而不是在使用UINTwhatever之前。 - Luchian Grigore
7
为什么要在C++中使用宏?std::numeric_limits<uint64_t>::max()不行吗? - Igor R.
1
@IgorR。我也是这么想的,但实现并没有硬性要求为这些类型提供numeric_limits特化,尽管很有可能会有一个。不过,如果没有constexprmax()的用处就较小了。 - pmr
1
@IgorR,std::numeric_limits<uint64_t>::max()解决了问题。谢谢。如果你愿意,你可以把它作为答案。 - Subway
总是有 #ifndef UINT64_MAX #define UINT64_MAX 18446744073709551615 ,附带相应的后缀(如果不支持 ull,则可能是 ui64)。 - M.M
显示剩余6条评论
2个回答

30

使用cstdint头文件可能会面临一些挑战(它在一些MSVC实现中缺失)。与此同时,如果不使用constexprnumeric_limits::max()很难使用,并且其实并不需要使用uint64_t。如果您不太关心这些问题,std::numeric_limits<uint64_t>::max()很可能就能解决问题。

Boost.Integer具有cstdint的实现,并带有一个额外的特性类来获取常量最大值。符合规范的cstdint应该还提供宏UINT64_MAX,但是我不确定boost是否提供。


我推荐使用Boost Integer库。我相信它是一个头文件库,可以在大多数编译器上的任何地方使用。 - user1356386
感谢您提供详细的答案。只是好奇为什么没有一个宏来代替函数调用,比如UINT_MAX? - Subway
1
@Subway 在C++11中没有使用numeric_limits进行函数调用,因为max是constexpr。 - pmr
我该如何在不使用Boost的情况下完成它。 - Master Yoda
1
如果你有C++11,可以尝试使用 numeric_limits - pmr
显示剩余4条评论

0
包含头文件<limits>并调用std::numeric_limits<uint64_t>::max()可以解决这个问题,但以下是使用类型转换的最简单实现方式,以防你忘记了std::numeric_limits<uint64_t>::max()的拼写。(健忘症实际上可能发生在你们所有人身上!...在过去或将来的某个时刻...)
  • 注意:这种方法的可用性取决于你的语言版本如何处理负值。"二进制补码"是2023年左右的问题...但如果你还没有尝试过,你必须试一试。

它写道:

uint64_t(-1)  // functional notation

或者

(uint64_t)-1   // c-like cast notation

例如,您可以像这样打印其最大值的确切值:
#include <iostream>
int main() {
    std::cout << "max value = " << uint64_t(-1);
}

输出的结果是:
max value = 18446744073709551615

看这里!

==== 以下有更多阅读内容 ====

事实上,许多编译器头文件使用这种类型转换作为那些预定义的“limits”宏的值。例如,在我的macOS开发环境中,使用XCode和g++,我的C++头文件limits.h中说,在template <class _Type, bool = is_arithmetic<_Type>::value> class __libcpp_numeric_limits内:

static constexpr const bool is_signed = _Type(-1) < _Type(0);

这是一种聪明的检查有符号和无符号类型的方法。然后,
static constexpr const _Type __min = __libcpp_compute_min<_Type, digits, is_signed>::value;
static constexpr const _Type __max = is_signed ? _Type(_Type(~0) ^ __min) : _Type(~0);

最小值使用了一个涉及特殊模板的计算方法,而最大值则使用了is_signed结果。最小值的模板如下:

template <class _Type, int __digits, bool _IsSigned>
struct __libcpp_compute_min {
    static constexpr const _Type value = _Type(_Type(1) << __digits);
};

这个表达与你问题中的表达式 (1<<64)-1 相似,只是没有了 -1 部分。

试试在你自己的电脑上检查限制头文件,看看它说了什么!


1
你可能想提到这取决于C++23,这是第一个要求有符号整数使用二进制补码表示的C++版本。 - undefined
1
根据你的评论,@TobySpeight,我已经插入了一条注释。谢谢! - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接