Macro representing maximum value for uint64_t
Asked Answered
Y

2

35

I'm seeking for a macro representing the maximum value of uint64_t as UINT_MAX is for unsigned int. i.e. I need this value to guaranteed to be (1<<64)-1.

I tried to use UINT64_MAX, but compiling with g++ results in:

'UINT64_MAX' was not declared in this scope

It's worth to mention that I have this line #define __STDC_LIMIT_MACROS in the code before using UINT64_MAX.

I was surprised to not find helpful information around the web about it.

Yours answered 30/4, 2013 at 11:20 Comment(11)
idk what #define __STDC_LIMIT_MACROS is, but you probably want it before the includes, not before use of UINTwhateverMotorman
C++11 implementations ship with cstdint which provides UINT64_MAX. Boost also provides an implementation of this header, if it is available to you.Debug
Why macro in c++? Doesn't std::numeric_limits<uint64_t>::max() work?Feil
@IgorR. I thought the same, but there is no hard requirement on an implementation to provide a numeric_limits specialization for those types, although chances are good that there is one. Although, max() is less useful without constexpr.Debug
@LuchianGrigore, correct. I have it before the relevant include.Yours
@pmr, I'm linked with the Boost libraries. Do you know to specify the macro/constant that I need?Yours
@IgorR, std::numeric_limits<uint64_t>::max() did the trick. Thanks. You can put it as an answer if you want to.Yours
@Debug The Standard requires numeric_limit::max() to be constexpr. But you're right in that some popular implementations are non-conforming.Feil
@IgorR. Yes, I'm not sure which compilers OP wants to support and this has a large bearing on those answers. I tried reflecting that in my answer.Debug
There's always #ifndef UINT64_MAX #define UINT64_MAX 18446744073709551615 , with the relevant suffix (if ull is not supported, then perhaps ui64)Merry
Or #define UINT64_MAX = 0xFFFFFFFFFFFFFFFFULL.Kite
D
32

Using the cstdint header portably can be quite a challenge (it is missing from some MSVC implementations). At the same time numeric_limits::max() can be hard to use without constexpr and it is not actually required to work with uint64_t. If you don't care about those things too much, std::numeric_limits<uint64_t>::max() will most likely do the trick.

Boost.Integer has an implementation of cstdint and comes with an extra traits class to get a constant maximal value. A compliant implementation of cstdint should also provide the macro UINT64_MAX, but I'm not sure about boost.

Debug answered 30/4, 2013 at 11:56 Comment(9)
I second boost integer. It's header only I believe and can be used anywhere on most any compiler.Dostie
Thanks for the detailed answer. Just curious why isn't there a macro for it as UINT_MAX, to save the function call?Yours
@Yours There is no function call with numeric_limits in C++11, because max is constexpr.Debug
Thanks for responding. I don't use C++11 :(Yours
@Yours So, you really want the Boost.Integer library.Debug
The thing is, I coudln't find any appropriate constant there.Yours
@Yours boost::integer_traits has a member const_maxDebug
how can i do it without boost .Foxing
@BhawinParkeria If you have C++11, try numeric_limits.Debug
V
0

While including the header <limits> and calling std::numeric_limits<uint64_t>::max() will solve the question,

here is the simplest way of actual implementation using typecasting, in case that you don't remember the spelling of std::numeric_limits<uint64_t>::max(). (Amnesia can actually happen to all of you! ...at some point in the past or in the future...)

  • Note: The usability of this method depends on how your language version treats the negative value. The "two's complement" is the issue around 2023... but you have to try this once, if you haven't tried.

It writes:

uint64_t(-1)  // functional notation

or

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

For example, you can print the exact value of its max number like this:

#include <iostream>
int main() {
    std::cout << "max value = " << uint64_t(-1);
}

and the result of output is:

max value = 18446744073709551615

Voilà!

==== further reading below ====

Indeed, many compiler headers use this kind of typecasting as the value of those pre-defined "limits" macro. For example, in my macOS dev environment with XCode and g++, my C++ header file limits.h says, inside the template <class _Type, bool = is_arithmetic<_Type>::value> class __libcpp_numeric_limits:

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

it's a clever way of checking the signed-unsigned type. And then,

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);

the min uses the calculation that involves a special template, while the max uses is_signed result. The min template is:

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

which looks similar to your expression in your question (1<<64)-1 except the -1 part.

Try checking the limits headers in your own computer and see what it says!

Vicinity answered 17/9, 2023 at 6:34 Comment(2)
You might want to mention that this depends on C++23, which is the first C++ to mandate 2's-complement representation for signed integers.Gameto
I have inserted a note according to your comment, @TobySpeight. Thank you!Vicinity

© 2022 - 2024 — McMap. All rights reserved.