Is static_cast<T>(-1) the right way to generate all-one-bits data without numeric_limits?

拜拜、爱过 提交于 2019-12-03 01:11:55
Leandros

Use the bitwise NOT operator ~ on 0.

T allOnes = ~(T)0;

A static_cast<T>(-1) assumes two's complement, which is not portable. If you are only concerned about unsigned types, hvd's answer is the way to go.

Working example: https://ideone.com/iV28u0

Focusing on unsigned integral types, what do I put there? Specifically, is static_cast(-1) good enough

If you're only concerned about unsigned types, yes, converting -1 is correct for all standard C++ implementations. Operations on unsigned types, including conversions of signed types to unsigned types, are guaranteed to work modulo (max+1).

This disarmingly direct way.

T allOnes;
memset(&allOnes, ~0, sizeof(T));

Focusing on unsigned integral types, what do I put there? Specifically, is static_cast(-1) good enough

Yes, it is good enough.

But I prefer a hex value because my background is embedded systems, and I have always had to know the sizeof(T).

Even in desktop systems, we know the sizes of the following T:

uint8_t  allones8  = 0xff;
uint16_t allones16 = 0xffff;
uint32_t allones32 = 0xffffffff;
uint64_t allones64 = 0xffffffffffffffff;

Another way is

static_cast<T>(-1ull)

which would be more correct and works in any signed integer format, regardless of 1's complement, 2's complement or sign-magnitude. You can also use static_cast<T>(-UINTMAX_C(1))

Because unary minus of an unsigned value is defined as

The negative of an unsigned quantity is computed by subtracting its value from 2^n, where n is the number of bits in the promoted operand."

Therefore -1u will always return an all-one-bits data in unsigned int. ll suffix is to make it work for any types narrower than unsigned long long. There's no extended integer types (yet) in C++ so this should be fine

However a solution that expresses the intention clearer would be

static_cast<T>(~0ull)
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!