Skip to main content
Fixed typo bug in code.
Source Link
Davislor
  • 9.2k
  • 19
  • 39

A bit of necromancy, since this came up in a web search.

  • On Clang and ICX, the __int128_t and __uint128_t types work with no warnings. #ifdef __clang__ detects either of them.
  • On GCC, the __int128__ and unsigned __int128__ types work with no warnings, even with -Wpedantic on. So you can remove those #pragma GCC diagnostic commands. Since several other compilers also define __GNUC__, check this afterward. or test __GNUC >= 10 (since other compilers that pretend to be GCC pretend to be a very early version).
  • MSVC does not have this type, but does support a few AVX intrinsics that can accelerate bitwise operations on 128-bit data, including left-shift, right-shift, and, or and xor. One way to synthesize multiplication would be from SIMD high- and low-word horizontal multiplications of the four 64-bit halves of the two operands.
  • C23 now supports _BitInt and unsigned _BitInt, and some compilers, including Clang, add that as an extension to C++. (This, however, does generate a compiler warning.)
  • A future implementation that adds support for int128_t will be required to define INT128_MAX in <cstdint>/<stdint.h>, so you can check that this is defined, at least before including any other headers that might define it.

Even though support is spotty and compilers do not accept constants larger than UINT64_MAX, the following declarations work for many definitions of these types:

#define INT128_MAX (~((int128_t)1 << 127U))
#define INT128_MIN ((int128_t)1 << 127U)
#define UINT128_MAX ((uint128_t)-1)
#define UINT128_MIN ((uint128_t)0)

With these definitions, GCC 20 and Clang 15 do not support stream output with <<, but do support <format>, so this works (although not in C++14):

std::println("{:L} {:L} {:#x} {:x}", INT128_MAX, INT128_MIN, UINT128_MAX, UINT128_MIN);

Most importantly, if you declare your 16-byte datatype alignas(1516), all atomic operations on it are lock-free on x86_64 and ARM64. This the most practical use for them (given that both targets have other ways to get the high word of 64-bit multiplication).

A bit of necromancy, since this came up in a web search.

  • On Clang and ICX, the __int128_t and __uint128_t types work with no warnings. #ifdef __clang__ detects either of them.
  • On GCC, the __int128__ and unsigned __int128__ types work with no warnings, even with -Wpedantic on. So you can remove those #pragma GCC diagnostic commands. Since several other compilers also define __GNUC__, check this afterward. or test __GNUC >= 10 (since other compilers that pretend to be GCC pretend to be a very early version).
  • MSVC does not have this type, but does support a few AVX intrinsics that can accelerate bitwise operations on 128-bit data, including left-shift, right-shift, and, or and xor. One way to synthesize multiplication would be from SIMD high- and low-word horizontal multiplications of the four 64-bit halves of the two operands.
  • C23 now supports _BitInt and unsigned _BitInt, and some compilers, including Clang, add that as an extension to C++. (This, however, does generate a compiler warning.)
  • A future implementation that adds support for int128_t will be required to define INT128_MAX in <cstdint>/<stdint.h>, so you can check that this is defined, at least before including any other headers that might define it.

Even though support is spotty and compilers do not accept constants larger than UINT64_MAX, the following declarations work for many definitions of these types:

#define INT128_MAX (~((int128_t)1 << 127U))
#define INT128_MIN ((int128_t)1 << 127U)
#define UINT128_MAX ((uint128_t)-1)
#define UINT128_MIN ((uint128_t)0)

With these definitions, GCC 20 and Clang 15 do not support stream output with <<, but do support <format>, so this works (although not in C++14):

std::println("{:L} {:L} {:#x} {:x}", INT128_MAX, INT128_MIN, UINT128_MAX, UINT128_MIN);

Most importantly, if you declare your 16-byte datatype alignas(15), all atomic operations on it are lock-free on x86_64 and ARM64. This the most practical use for them (given that both targets have other ways to get the high word of 64-bit multiplication).

A bit of necromancy, since this came up in a web search.

  • On Clang and ICX, the __int128_t and __uint128_t types work with no warnings. #ifdef __clang__ detects either of them.
  • On GCC, the __int128__ and unsigned __int128__ types work with no warnings, even with -Wpedantic on. So you can remove those #pragma GCC diagnostic commands. Since several other compilers also define __GNUC__, check this afterward. or test __GNUC >= 10 (since other compilers that pretend to be GCC pretend to be a very early version).
  • MSVC does not have this type, but does support a few AVX intrinsics that can accelerate bitwise operations on 128-bit data, including left-shift, right-shift, and, or and xor. One way to synthesize multiplication would be from SIMD high- and low-word horizontal multiplications of the four 64-bit halves of the two operands.
  • C23 now supports _BitInt and unsigned _BitInt, and some compilers, including Clang, add that as an extension to C++. (This, however, does generate a compiler warning.)
  • A future implementation that adds support for int128_t will be required to define INT128_MAX in <cstdint>/<stdint.h>, so you can check that this is defined, at least before including any other headers that might define it.

Even though support is spotty and compilers do not accept constants larger than UINT64_MAX, the following declarations work for many definitions of these types:

#define INT128_MAX (~((int128_t)1 << 127U))
#define INT128_MIN ((int128_t)1 << 127U)
#define UINT128_MAX ((uint128_t)-1)
#define UINT128_MIN ((uint128_t)0)

With these definitions, GCC 20 and Clang 15 do not support stream output with <<, but do support <format>, so this works (although not in C++14):

std::println("{:L} {:L} {:#x} {:x}", INT128_MAX, INT128_MIN, UINT128_MAX, UINT128_MIN);

Most importantly, if you declare your 16-byte datatype alignas(16), all atomic operations on it are lock-free on x86_64 and ARM64. This the most practical use for them (given that both targets have other ways to get the high word of 64-bit multiplication).

added 170 characters in body
Source Link
Davislor
  • 9.2k
  • 19
  • 39

A bit of necromancy, since this came up in a web search.

  • On Clang and ICX, the __int128_t and __uint128_t types work with no warnings. #ifdef __clang__ detects either of them.
  • On GCC, the __int128__ and unsigned __int128__ types work with no warnings, even with -Wpedantic on. So you can remove those #pragma GCC diagnostic commands. Since several other compilers also define __GNUC__, check this afterward. or test __GNUC >= 10 (since other compilers that pretend to be GCC pretend to be a very early version).
  • MSVC does not have this type, but does support a few AVX intrinsics that can accelerate bitwise operations on 128-bit data, including left-shift, right-shift, and, or and xor. One way to synthesize multiplication would be from SIMD high- and low-word horizontal multiplications of the four 64-bit halves of the two operands.
  • C23 now supports _BitInt and unsigned _BitInt, and some compilers, including Clang, add that as an extension to C++. (This, however, does generate a compiler warning.)
  • A future implementation that adds support for int128_t will be required to define INT128_MAX in <cstdint>/<stdint.h>, so you can check that this is defined, at least before including any other headers that might define it.

Even though support is spotty and compilers do not accept constants larger than UINT64_MAX, the following declarations work for many definitions of these types:

#define INT128_MAX (~((int128_t)1 << 127U))
#define INT128_MIN ((int128_t)1 << 127U)
#define UINT128_MAX ((uint128_t)-1)
#define UINT128_MIN ((uint128_t)0)

With these definitions, GCC 20 and Clang 15 do not support stream output with <<, but do support <format>, so this works (although not in C++14):

std::println("{:L} {:L} {:#x} {:x}", INT128_MAX, INT128_MIN, UINT128_MAX, UINT128_MIN);

Most importantly, if you declare your 16-byte datatype alignas(15), all atomic operations on it are lock-free on x86_64 and ARM64. This the most practical use for them (given that both targets have other ways to get the high word of 64-bit multiplication).

A bit of necromancy, since this came up in a web search.

  • On Clang and ICX, the __int128_t and __uint128_t types work with no warnings. #ifdef __clang__ detects either of them.
  • On GCC, the __int128__ and unsigned __int128__ types work with no warnings, even with -Wpedantic on. So you can remove those #pragma GCC diagnostic commands. Since several other compilers also define __GNUC__, check this afterward. or test __GNUC >= 10 (since other compilers that pretend to be GCC pretend to be a very early version).
  • MSVC does not have this type, but does support a few AVX intrinsics that can accelerate bitwise operations on 128-bit data, including left-shift, right-shift, and, or and xor. One way to synthesize multiplication would be from SIMD high- and low-word horizontal multiplications of the four 64-bit halves of the two operands.
  • C23 now supports _BitInt and unsigned _BitInt, and some compilers, including Clang, add that as an extension to C++.
  • A future implementation that adds support for int128_t will be required to define INT128_MAX in <cstdint>.

Even though support is spotty and compilers do not accept constants larger than UINT64_MAX, the following declarations work for many definitions of these types:

#define INT128_MAX (~((int128_t)1 << 127U))
#define INT128_MIN ((int128_t)1 << 127U)
#define UINT128_MAX ((uint128_t)-1)
#define UINT128_MIN ((uint128_t)0)

With these definitions, GCC 20 and Clang 15 do not support stream output with <<, but do support <format>, so this works (although not in C++14):

std::println("{:L} {:L} {:#x} {:x}", INT128_MAX, INT128_MIN, UINT128_MAX, UINT128_MIN);

Most importantly, if you declare your 16-byte datatype alignas(15), all atomic operations on it are lock-free on x86_64 and ARM64. This the most practical use for them (given that both targets have other ways to get the high word of 64-bit multiplication).

A bit of necromancy, since this came up in a web search.

  • On Clang and ICX, the __int128_t and __uint128_t types work with no warnings. #ifdef __clang__ detects either of them.
  • On GCC, the __int128__ and unsigned __int128__ types work with no warnings, even with -Wpedantic on. So you can remove those #pragma GCC diagnostic commands. Since several other compilers also define __GNUC__, check this afterward. or test __GNUC >= 10 (since other compilers that pretend to be GCC pretend to be a very early version).
  • MSVC does not have this type, but does support a few AVX intrinsics that can accelerate bitwise operations on 128-bit data, including left-shift, right-shift, and, or and xor. One way to synthesize multiplication would be from SIMD high- and low-word horizontal multiplications of the four 64-bit halves of the two operands.
  • C23 now supports _BitInt and unsigned _BitInt, and some compilers, including Clang, add that as an extension to C++. (This, however, does generate a compiler warning.)
  • A future implementation that adds support for int128_t will be required to define INT128_MAX in <cstdint>/<stdint.h>, so you can check that this is defined, at least before including any other headers that might define it.

Even though support is spotty and compilers do not accept constants larger than UINT64_MAX, the following declarations work for many definitions of these types:

#define INT128_MAX (~((int128_t)1 << 127U))
#define INT128_MIN ((int128_t)1 << 127U)
#define UINT128_MAX ((uint128_t)-1)
#define UINT128_MIN ((uint128_t)0)

With these definitions, GCC 20 and Clang 15 do not support stream output with <<, but do support <format>, so this works (although not in C++14):

std::println("{:L} {:L} {:#x} {:x}", INT128_MAX, INT128_MIN, UINT128_MAX, UINT128_MIN);

Most importantly, if you declare your 16-byte datatype alignas(15), all atomic operations on it are lock-free on x86_64 and ARM64. This the most practical use for them (given that both targets have other ways to get the high word of 64-bit multiplication).

added 248 characters in body
Source Link
Davislor
  • 9.2k
  • 19
  • 39

A bit of necromancy, since this came up in a web search.

  • On Clang and ICX, the __int128_t and __uint128_t types work with no warnings. #ifdef __clang__ detects either of them.
  • On GCC, the __int128__ and unsigned __int128__ types work with no warnings, even with -Wpedantic on. So you can remove those #pragma GCC diagnostic commands. Since several other compilers also define __GNUC__, check this afterward. or test __GNUC >= 10 (since other compilers that pretend to be GCC pretend to be a very early version).
  • MSVC does not have this type, but does support a few AVX intrinsics that can accelerate bitwise operations on 128-bit data, including left-shift, right-shift, and, or and xor. One way to synthesize multiplication would be from SIMD high- and low-word horizontal multiplications of the four 64-bit halves of the two operands.
  • C23 now supports _BitInt and unsigned _BitInt, and some compilers, including Clang, add that as an extension to C++.
  • A future implementation that adds support for int128_t will be required to define INT128_MAX in <cstdint>.

Even though support is spotty and compilers do not accept constants larger than UINT64_MAX, the following declarations work for many definitions of these types:

#define INT128_MAX (~((int128_t)1 << 127U))
#define INT128_MIN ((int128_t)1 << 127U)
#define UINT128_MAX ((uint128_t)-1)
#define UINT128_MIN ((uint128_t)0)

With these definitions, GCC 20 and Clang 15 do not support stream output with <<, but do support <format>, so this works (although not in C++14):

std::println("{:L} {:L} {:#x} {:x}", INT128_MAX, INT128_MIN, UINT128_MAX, UINT128_MIN);

Most importantly, if you declare your 16-byte datatype alignas(15), all atomic operations on it are lock-free on x86_64 and ARM64. This the most practical use for them (given that both targets have other ways to get the high word of 64-bit multiplication).

A bit of necromancy, since this came up in a web search.

  • On Clang and ICX, the __int128_t and __uint128_t types work with no warnings. #ifdef __clang__ detects either of them.
  • On GCC, the __int128__ and unsigned __int128__ types work with no warnings, even with -Wpedantic on. So you can remove those #pragma GCC diagnostic commands. Since several other compilers also define __GNUC__, check this afterward. or test __GNUC >= 10 (since other compilers that pretend to be GCC pretend to be a very early version).
  • MSVC does not have this type, but does support a few AVX intrinsics that can accelerate bitwise operations on 128-bit data, including left-shift, right-shift, and, or and xor.
  • C23 now supports _BitInt and unsigned _BitInt, and some compilers, including Clang, add that as an extension to C++.
  • A future implementation that adds support for int128_t will be required to define INT128_MAX in <cstdint>.

Even though support is spotty and compilers do not accept constants larger than UINT64_MAX, the following declarations work for many definitions of these types:

#define INT128_MAX (~((int128_t)1 << 127U))
#define INT128_MIN ((int128_t)1 << 127U)
#define UINT128_MAX ((uint128_t)-1)
#define UINT128_MIN ((uint128_t)0)

With these definitions, GCC 20 and Clang 15 do not support stream output with <<, but do support <format>, so this works (although not in C++14):

std::println("{:L} {:L} {:#x} {:x}", INT128_MAX, INT128_MIN, UINT128_MAX, UINT128_MIN);

Most importantly, if you declare your 16-byte datatype alignas(15), all atomic operations on it are lock-free on x86_64 and ARM64. This the most practical use for them (given that both targets have other ways to get the high word of 64-bit multiplication).

A bit of necromancy, since this came up in a web search.

  • On Clang and ICX, the __int128_t and __uint128_t types work with no warnings. #ifdef __clang__ detects either of them.
  • On GCC, the __int128__ and unsigned __int128__ types work with no warnings, even with -Wpedantic on. So you can remove those #pragma GCC diagnostic commands. Since several other compilers also define __GNUC__, check this afterward. or test __GNUC >= 10 (since other compilers that pretend to be GCC pretend to be a very early version).
  • MSVC does not have this type, but does support a few AVX intrinsics that can accelerate bitwise operations on 128-bit data, including left-shift, right-shift, and, or and xor. One way to synthesize multiplication would be from SIMD high- and low-word horizontal multiplications of the four 64-bit halves of the two operands.
  • C23 now supports _BitInt and unsigned _BitInt, and some compilers, including Clang, add that as an extension to C++.
  • A future implementation that adds support for int128_t will be required to define INT128_MAX in <cstdint>.

Even though support is spotty and compilers do not accept constants larger than UINT64_MAX, the following declarations work for many definitions of these types:

#define INT128_MAX (~((int128_t)1 << 127U))
#define INT128_MIN ((int128_t)1 << 127U)
#define UINT128_MAX ((uint128_t)-1)
#define UINT128_MIN ((uint128_t)0)

With these definitions, GCC 20 and Clang 15 do not support stream output with <<, but do support <format>, so this works (although not in C++14):

std::println("{:L} {:L} {:#x} {:x}", INT128_MAX, INT128_MIN, UINT128_MAX, UINT128_MIN);

Most importantly, if you declare your 16-byte datatype alignas(15), all atomic operations on it are lock-free on x86_64 and ARM64. This the most practical use for them (given that both targets have other ways to get the high word of 64-bit multiplication).

added 248 characters in body
Source Link
Davislor
  • 9.2k
  • 19
  • 39
Loading
Spelling and grammar
Source Link
Toby Speight
  • 88.7k
  • 14
  • 104
  • 327
Loading
added 344 characters in body
Source Link
Davislor
  • 9.2k
  • 19
  • 39
Loading
added 79 characters in body
Source Link
Davislor
  • 9.2k
  • 19
  • 39
Loading
Source Link
Davislor
  • 9.2k
  • 19
  • 39
Loading