Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

U128 v2 #887

Open
wants to merge 192 commits into
base: develop
Choose a base branch
from
Open
Changes from 1 commit
Commits
Show all changes
192 commits
Select commit Hold shift + click to select a range
b5d1963
Add default constructors
mborland Feb 28, 2025
4b46eb9
Add signed and unsigned arithmetic constructors
mborland Feb 28, 2025
3ef7ae8
Add signed and unsigned assignment operators
mborland Feb 28, 2025
508ce87
Add bool and integer conversion operators
mborland Feb 28, 2025
5b50d95
Add float conversion operators
mborland Feb 28, 2025
cee89c1
Reduce in-class clutter
mborland Feb 28, 2025
46a48f2
Add unary arithmetic operators
mborland Feb 28, 2025
a4879d1
Fix clang tidy warnings
mborland Feb 28, 2025
1e7ef13
Add arithmetic constructor tests
mborland Feb 28, 2025
27be82a
Add missing STL headers
mborland Feb 28, 2025
d8ba848
Test assignment operators
mborland Feb 28, 2025
be86995
Test integer conversion operators
mborland Feb 28, 2025
9bf4219
Add float conversion operators testing
mborland Feb 28, 2025
4f4a9a5
Test 128-bit ints and fix sign conversion warning
mborland Feb 28, 2025
5f113ff
Test bool conversion
mborland Feb 28, 2025
6c6df06
test unary plus and minus
mborland Feb 28, 2025
6207105
Add equality operators
mborland Feb 28, 2025
a96199e
Add and test inequality operator
mborland Feb 28, 2025
81a9233
Add 128 bit equality and inequality
mborland Feb 28, 2025
fd4f7d0
Add operator<
mborland Feb 28, 2025
8206317
Remove unary operators from being friends
mborland Feb 28, 2025
8010ec2
Make equality a non-friend template
mborland Feb 28, 2025
bc5bdf1
Simplify operator!= to a non-friend template
mborland Feb 28, 2025
9889e11
Simplify operator< to a non-friend template
mborland Feb 28, 2025
19befde
Add hardware bug workaround
mborland Feb 28, 2025
e2eb2f3
Fix SFINAE
mborland Mar 3, 2025
5d0531c
Add operator< for bool test
mborland Mar 3, 2025
e238bb6
Add operator LE
mborland Mar 3, 2025
eac2575
Add operator>
mborland Mar 3, 2025
87958d4
Improve testing and 128-bit operators
mborland Mar 3, 2025
397396e
Add and test operator ge
mborland Mar 3, 2025
28d71c7
Operator not
mborland Mar 3, 2025
40bc160
Operator or
mborland Mar 3, 2025
34b5e41
Operator and
mborland Mar 3, 2025
cd12a43
Operator xor
mborland Mar 3, 2025
42f3d27
Left shift operator
mborland Mar 3, 2025
0978879
Right shift operator
mborland Mar 3, 2025
706bc68
Add optimized 128-bit addition
mborland Mar 3, 2025
a224d47
Re-work ARM ASM so it can be used with C++14 instead of 20
mborland Mar 4, 2025
c8e1d6a
Implement and test unsigned addition
mborland Mar 4, 2025
18b3acf
Add macro for subborrow
mborland Mar 4, 2025
de0c75c
Implement and test addition
mborland Mar 4, 2025
17298f0
Add subtraction test set
mborland Mar 4, 2025
f697e83
Add unsigned subtraction
mborland Mar 4, 2025
26eca65
Add signed subtraction
mborland Mar 4, 2025
82c2450
Add compound addition
mborland Mar 4, 2025
007c217
Add compound subtraction
mborland Mar 4, 2025
79938c9
Add increment operators
mborland Mar 4, 2025
d879751
Add test set
mborland Mar 4, 2025
f613d45
Add 128 bit impls
mborland Mar 4, 2025
dfb7313
Add mul for all unsigned integers
mborland Mar 4, 2025
84b1175
Add better traits
mborland Mar 5, 2025
0684d26
Simplify member operators
mborland Mar 5, 2025
c3d2219
Improve correctness with new traits
mborland Mar 5, 2025
7e02ea3
Add traits testing
mborland Mar 5, 2025
93be0b5
Add optimized signed mul
mborland Mar 5, 2025
b932e79
Add benchmarks of u128 types
mborland Mar 5, 2025
b412e63
Add single and double word ops
mborland Mar 5, 2025
a0e8dff
Add additional benchmarks
mborland Mar 5, 2025
2cdcbf8
Remove complicated and slower impls
mborland Mar 5, 2025
57e52a0
Simplify mul
mborland Mar 5, 2025
cc96acb
Use native x64 u128 for sub
mborland Mar 5, 2025
4098c3c
Improve ordering
mborland Mar 5, 2025
31e7981
Micro optimizations
mborland Mar 5, 2025
9428b0d
Make benchmarks safe for platforms without builtin
mborland Mar 6, 2025
51db7f4
Fix config for ARM Windows
mborland Mar 6, 2025
855c3fb
Force inline mul
mborland Mar 6, 2025
9b6efb9
Fix benchmarks for pre C++17
mborland Mar 6, 2025
71c5926
Add div benchmarks
mborland Mar 6, 2025
9dba617
Fix testing on GCC
mborland Mar 6, 2025
b359e39
Add additional benchmark permutations
mborland Mar 6, 2025
8a53517
Add random width benchmarks
mborland Mar 6, 2025
1814263
Add division test set
mborland Mar 6, 2025
2c94c92
Add 128-bit division
mborland Mar 6, 2025
07ae38c
Add compound multiplication operator
mborland Mar 6, 2025
d51cd6f
Improve x64 mul
mborland Mar 7, 2025
61b668c
Fix benchmarks for MSVC
mborland Mar 7, 2025
1c15be5
Remove MSVC specialized mul since it's worse
mborland Mar 7, 2025
e45a6d5
Avoid division trapping on windows platforms
mborland Mar 7, 2025
d60aa82
Begin adding tests for platforms without native __int128
mborland Mar 7, 2025
c2511fe
Add comparisons testing
mborland Mar 7, 2025
3c2948a
Default init to fix warnings
mborland Mar 7, 2025
93d88f7
Fix benchmarks for MSVC
mborland Mar 7, 2025
e350293
Remove MSVC specialized mul since it's worse
mborland Mar 7, 2025
1de3932
Avoid division trapping on windows platforms
mborland Mar 7, 2025
d9b35f9
Add testing of operator and
mborland Mar 7, 2025
9b947be
Merge remote-tracking branch 'origin/u128_v2' into u128_v2
mborland Mar 7, 2025
25533b9
Fix comparisons with negative numbers
mborland Mar 7, 2025
68ab0d1
Add operators testing
mborland Mar 7, 2025
40b4252
Use two word div and avoid trapping on zero
mborland Mar 7, 2025
d17d03c
Fix inverted division
mborland Mar 10, 2025
19af2d1
Add and test AARCH64 div operator
mborland Mar 10, 2025
2443914
Add and test x64 DIV
mborland Mar 10, 2025
a45c863
Speed up x86 mul by using memcpy instead of cast
mborland Mar 10, 2025
e7c1a44
Add signed division
mborland Mar 10, 2025
e597017
Add compound division operator
mborland Mar 10, 2025
62ad488
Fix division logic
mborland Mar 10, 2025
b06aa21
Add std::numeric_limits overload
mborland Mar 11, 2025
8cd43cb
Add portable definition of assume
mborland Mar 11, 2025
2839528
Fix references
mborland Mar 11, 2025
4667c2d
Add additional default division path
mborland Mar 11, 2025
520bde7
Adjust switching logic
mborland Mar 11, 2025
7310583
Add compound bitwise operators
mborland Mar 11, 2025
2f437e2
Fix MSVC error class vs struct
mborland Mar 11, 2025
fefb9ef
Add testing of numeric limits
mborland Mar 11, 2025
b75659e
Fix C++14 linkage
mborland Mar 11, 2025
b179d1d
Fix 128 by 64 division for windows
mborland Mar 11, 2025
cbacfbd
Improve PPC64LE and S390x DIV performance
mborland Mar 11, 2025
33b32ef
Optimize x64 division
mborland Mar 11, 2025
53d9b53
Improve PPC64 mul
mborland Mar 12, 2025
11e8b2f
Fix testing of conversion to __float128 and __ibm128
mborland Mar 12, 2025
b41e581
Simplify float conversion operators
mborland Mar 12, 2025
baeda79
Add tests for modulo
mborland Mar 12, 2025
d1afc8b
Add benchmarks for modulo
mborland Mar 12, 2025
b0f37ba
Add 128-bit modulo
mborland Mar 12, 2025
c238814
Add modulo implementation details
mborland Mar 12, 2025
a211bde
Implement generic unsigned modulo
mborland Mar 12, 2025
24d2023
Fix implicit type conversion
mborland Mar 12, 2025
e3593ab
Fix copy-paste error
mborland Mar 12, 2025
b89a782
Add signed modulo operator
mborland Mar 12, 2025
58dd8e3
Add compound modulo operators
mborland Mar 12, 2025
a9be79b
Fix and test compound or
mborland Mar 12, 2025
feaac25
Fix and test compound and
mborland Mar 12, 2025
f84fda5
Fix and test compound xor
mborland Mar 12, 2025
59208e4
Fix and test compound left shift
mborland Mar 12, 2025
dd27190
Fix and test compound right shift
mborland Mar 12, 2025
c3cf01b
Add compound add testing and fix copy-paste error sub test
mborland Mar 12, 2025
fb86867
Fix signed subtraction
mborland Mar 12, 2025
a810fef
Test remaining compound operators
mborland Mar 12, 2025
1f50d75
Add ostream operator
mborland Mar 12, 2025
eac0584
Add ostream operator testing
mborland Mar 12, 2025
58ad2c2
Add testing of numbers with high word
mborland Mar 12, 2025
441629d
Fix modulo of big num
mborland Mar 12, 2025
b743379
Add istream operator testing
mborland Mar 12, 2025
c8378b3
Add istream operator
mborland Mar 12, 2025
e13bf19
Fix MSVC warning/error
mborland Mar 12, 2025
f32c50b
Collect ARM64 benchmarks
mborland Mar 13, 2025
47ff462
Specialize countl_zero
mborland Mar 13, 2025
bc391f5
Add table of the powers of 10
mborland Mar 13, 2025
4d7a577
Add digit counting method for new type
mborland Mar 13, 2025
fb42f8f
Add testing of digit counting
mborland Mar 13, 2025
0f5778e
Add benchmark of digit counting
mborland Mar 13, 2025
df1aa30
Fix unsigned conversion warning
mborland Mar 13, 2025
ecd25ad
Fix multiple definition warnings
mborland Mar 13, 2025
3be2304
Fix potential buffer overrun
mborland Mar 13, 2025
a365eb5
Move generic strlen to it's own header
mborland Mar 13, 2025
0bc2b6c
Fix decimal type io
mborland Mar 13, 2025
d926a71
Fix sign conversion warning in benchmarks
mborland Mar 13, 2025
3b3830c
Fix copy paste error
mborland Mar 13, 2025
0f4bc13
Deactivate qemu run for now
mborland Mar 13, 2025
b3b0e8d
Ignore additional warnings/errors
mborland Mar 13, 2025
4301fc1
Bring down non-apple AARCH64 mul timing
mborland Mar 13, 2025
c8cec3a
Fix macro for x64 windows platforms
mborland Mar 13, 2025
628903f
Fix ignored diagnostic for older GCC versions
mborland Mar 13, 2025
8c7d20e
Add method that is better for slow CLZ instructions
mborland Mar 13, 2025
696efbc
Remove shift of negative values
mborland Mar 13, 2025
930ae22
Reduce runtime
mborland Mar 14, 2025
0f10179
Deactivate signed shift testing with UBSAN
mborland Mar 14, 2025
c70ff2f
Fix syntax error
mborland Mar 14, 2025
dafd20a
Attempt reduction and see where timeout is occuring
mborland Mar 17, 2025
4d01328
Workaround for MSVC chrono missing
mborland Mar 17, 2025
707307a
Fix macro definition for clang on win
mborland Mar 17, 2025
7c72a3f
Change logic for old clangs
mborland Mar 17, 2025
5a99586
Significantly reduce test runs on old platforms for debug
mborland Mar 17, 2025
c3fada6
Update div macro
mborland Mar 18, 2025
a973b06
Update div macros
mborland Mar 18, 2025
84fe447
Update sub macro
mborland Mar 18, 2025
3af824a
Reduce duplication and increase readability
mborland Mar 18, 2025
ba02bce
Revert hang inspection
mborland Mar 18, 2025
f8cf0c5
Add additional div path where numeric limits not defined
mborland Mar 18, 2025
9141ce6
Add generic function to replace max/min
mborland Mar 18, 2025
eddc124
Fix stackoverflow
mborland Mar 18, 2025
c4fcc35
Fix intel warning
mborland Mar 18, 2025
c8c87dd
Fix definition location
mborland Mar 18, 2025
eb67ff5
Ignore big endian platforms reorder constructor warning
mborland Mar 18, 2025
11319cd
Add UBSAN define to drone run
mborland Mar 18, 2025
dc0d920
Change reorder ignore
mborland Mar 18, 2025
8fdeb39
Move UBSAN to GHA
mborland Mar 19, 2025
6dd3bf9
Add benchmark against MSVC internal std::_Unsigned128
mborland Mar 24, 2025
fe80ab2
Add x64 specific intrinsics path
mborland Mar 24, 2025
a70809b
Add additional path for x64 MSVC intrinsics
mborland Mar 24, 2025
bc8a904
Add reduced adaptation of knuth division
mborland Mar 25, 2025
0689245
Specialize knuth division
mborland Mar 25, 2025
ae9fc89
Use x64 intrinsic if available and not constexpr
mborland Mar 25, 2025
1fe66a7
Use new impl in 128 by 64 division case
mborland Mar 25, 2025
bdbe32a
Fix parens
mborland Mar 25, 2025
99fe692
Add non-zero divisor assumption
mborland Mar 25, 2025
93de98d
Fix overcounting zeros
mborland Mar 25, 2025
6c492f3
Update mod methods
mborland Mar 25, 2025
10771cb
Add MSVC testing of operator mod
mborland Mar 25, 2025
9341dc7
Simplify mixed width div
mborland Mar 25, 2025
c89cb39
Restore PPC64LE runs
mborland Mar 26, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Add operator<
mborland committed Feb 28, 2025

Verified

This commit was signed with the committer’s verified signature.
mborland Matt Borland
commit fd4f7d0cdafa905cda720ffb8e85a8b5d636bc22
138 changes: 138 additions & 0 deletions include/boost/decimal/detail/u128.hpp
Original file line number Diff line number Diff line change
@@ -215,6 +215,39 @@ u128
friend constexpr bool operator!=(unsigned __int128 lhs, u128 rhs) noexcept;

#endif // BOOST_DECIMAL_HAS_INT128

// Less than for signed integers
friend constexpr bool operator<(u128 lhs, std::int8_t rhs) noexcept;
friend constexpr bool operator<(u128 lhs, std::int16_t rhs) noexcept;
friend constexpr bool operator<(u128 lhs, std::int32_t rhs) noexcept;
friend constexpr bool operator<(u128 lhs, std::int64_t rhs) noexcept;

friend constexpr bool operator<(std::int8_t lhs, u128 rhs) noexcept;
friend constexpr bool operator<(std::int16_t lhs, u128 rhs) noexcept;
friend constexpr bool operator<(std::int32_t lhs, u128 rhs) noexcept;
friend constexpr bool operator<(std::int64_t lhs, u128 rhs) noexcept;

// Less than for unsigned integers
friend constexpr bool operator<(u128 lhs, std::uint8_t rhs) noexcept;
friend constexpr bool operator<(u128 lhs, std::uint16_t rhs) noexcept;
friend constexpr bool operator<(u128 lhs, std::uint32_t rhs) noexcept;
friend constexpr bool operator<(u128 lhs, std::uint64_t rhs) noexcept;

friend constexpr bool operator<(std::uint8_t lhs, u128 rhs) noexcept;
friend constexpr bool operator<(std::uint16_t lhs, u128 rhs) noexcept;
friend constexpr bool operator<(std::uint32_t lhs, u128 rhs) noexcept;
friend constexpr bool operator<(std::uint64_t lhs, u128 rhs) noexcept;

// Less than for 128-bit types
friend constexpr bool operator<(u128 lhs, u128 rhs) noexcept;

#ifdef BOOST_DECIMAL_HAS_INT128
friend constexpr bool operator<(u128 lhs, __int128 rhs) noexcept;
friend constexpr bool operator<(__int128 lhs, u128 rhs) noexcept;

friend constexpr bool operator<(u128 lhs, unsigned __int128 rhs) noexcept;
friend constexpr bool operator<(unsigned __int128 lhs, u128 rhs) noexcept;
#endif // BOOST_DECIMAL_HAS_INT128
};

// Signed assignment operators
@@ -541,6 +574,111 @@ constexpr bool operator!=(const unsigned __int128 lhs, const u128 rhs) noexcept

#endif // BOOST_DECIMAL_HAS_INT128

constexpr bool operator<(const u128 lhs, const std::int8_t rhs) noexcept
{
return rhs > 0 && lhs.high == UINT64_C(0) && lhs.low < static_cast<std::uint64_t>(rhs);
}

constexpr bool operator<(const u128 lhs, const std::int16_t rhs) noexcept
{
return rhs > 0 && lhs.high == UINT64_C(0) && lhs.low < static_cast<std::uint64_t>(rhs);
}

constexpr bool operator<(const u128 lhs, const std::int32_t rhs) noexcept
{
return rhs > 0 && lhs.high == UINT64_C(0) && lhs.low < static_cast<std::uint64_t>(rhs);
}

constexpr bool operator<(const u128 lhs, const std::int64_t rhs) noexcept
{
return rhs > 0 && lhs.high == UINT64_C(0) && lhs.low < static_cast<std::uint64_t>(rhs);
}

constexpr bool operator<(const u128 lhs, const std::uint8_t rhs) noexcept
{
return lhs.high == UINT64_C(0) && lhs.low < static_cast<std::uint64_t>(rhs);
}

constexpr bool operator<(const u128 lhs, const std::uint16_t rhs) noexcept
{
return lhs.high == UINT64_C(0) && lhs.low < static_cast<std::uint64_t>(rhs);
}

constexpr bool operator<(const u128 lhs, const std::uint32_t rhs) noexcept
{
return lhs.high == UINT64_C(0) && lhs.low < static_cast<std::uint64_t>(rhs);
}

constexpr bool operator<(const u128 lhs, const std::uint64_t rhs) noexcept
{
return lhs.high == UINT64_C(0) && lhs.low < static_cast<std::uint64_t>(rhs);
}

constexpr bool operator<(const std::int8_t lhs, const u128 rhs) noexcept
{
return lhs > 0 && rhs.high == UINT64_C(0) && static_cast<std::uint64_t>(lhs) < rhs.low;
}

constexpr bool operator<(const std::int16_t lhs, const u128 rhs) noexcept
{
return lhs > 0 && rhs.high == UINT64_C(0) && static_cast<std::uint64_t>(lhs) < rhs.low;
}

constexpr bool operator<(const std::int32_t lhs, const u128 rhs) noexcept
{
return lhs > 0 && rhs.high == UINT64_C(0) && static_cast<std::uint64_t>(lhs) < rhs.low;
}

constexpr bool operator<(const std::int64_t lhs, const u128 rhs) noexcept
{
return lhs > 0 && rhs.high == UINT64_C(0) && static_cast<std::uint64_t>(lhs) < rhs.low;
}

constexpr bool operator<(const std::uint8_t lhs, const u128 rhs) noexcept
{
return rhs.high == UINT64_C(0) && static_cast<std::uint64_t>(lhs) < rhs.low;
}

constexpr bool operator<(const std::uint16_t lhs, const u128 rhs) noexcept
{
return rhs.high == UINT64_C(0) && static_cast<std::uint64_t>(lhs) < rhs.low;
}

constexpr bool operator<(const std::uint32_t lhs, const u128 rhs) noexcept
{
return rhs.high == UINT64_C(0) && static_cast<std::uint64_t>(lhs) < rhs.low;
}

constexpr bool operator<(const std::uint64_t lhs, const u128 rhs) noexcept
{
return rhs.high == UINT64_C(0) && static_cast<std::uint64_t>(lhs) < rhs.low;
}

constexpr bool operator<(const u128 lhs, const u128 rhs) noexcept
{
return lhs.high == rhs.high ? lhs.low < rhs.low : lhs.high < rhs.high;
}

constexpr bool operator<(const u128 lhs, const __int128 rhs) noexcept
{
return lhs < static_cast<u128>(rhs);
}

constexpr bool operator<(const __int128 lhs, const u128 rhs) noexcept
{
return static_cast<u128>(lhs) < rhs;
}

constexpr bool operator<(const u128 lhs, const unsigned __int128 rhs) noexcept
{
return lhs < static_cast<u128>(rhs);
}

constexpr bool operator<(const unsigned __int128 lhs, const u128 rhs) noexcept
{
return static_cast<u128>(lhs) < rhs;
}

} // namespace detail
} // namespace decimal
} // namespace boost
30 changes: 30 additions & 0 deletions test/test_u128.cpp
Original file line number Diff line number Diff line change
@@ -243,6 +243,24 @@ void test_operator_inequality()
BOOST_TEST((true != bool_val) == (bool_val != true));
}

template <typename IntType>
void test_operator_less()
{
boost::random::uniform_int_distribution<IntType> dist(std::numeric_limits<IntType>::min(),
std::numeric_limits<IntType>::max());

for (std::size_t i {}; i < N; ++i)
{
const IntType value {dist(rng)};
const IntType value2 {dist(rng)};
unsigned __int128 builtin_value = static_cast<unsigned __int128>(value);
boost::decimal::detail::u128 emulated_value {value};

BOOST_TEST(((value2 < emulated_value) == (emulated_value < value2)) ==
((value2 < builtin_value) == (builtin_value < value2)));
}
}

int main()
{
test_arithmetic_constructor<std::int8_t>();
@@ -316,6 +334,18 @@ int main()
test_operator_inequality<std::uint64_t>();
test_operator_inequality<unsigned __int128>();

test_operator_less<std::int8_t>();
test_operator_less<std::int16_t>();
test_operator_less<std::int32_t>();
test_operator_less<std::int64_t>();
test_operator_less<__int128>();

test_operator_less<std::uint8_t>();
test_operator_less<std::uint16_t>();
test_operator_less<std::uint32_t>();
test_operator_less<std::uint64_t>();
test_operator_less<unsigned __int128>();

return boost::report_errors();
}