Skip to content

Unnormalized limbs in multiprecision user-defined literals #766

Description

@ryanavella

I am encountering unusual behavior where a number does not compare equal to itself after masking with a sufficiently wide bitmask.

Here is a simple reproducer:

#include <cassert>
#include <boost/multiprecision/cpp_int.hpp>
#include <iostream>

// Comment this out to fix the uint384_t limbs
// vvvvvvvvvvvvv
#define CRASH_ME

namespace Mp = boost::multiprecision;

using uint384_t = Mp::number<Mp::cpp_int_backend<384, 384, Mp::unsigned_magnitude, Mp::unchecked, void>>;
BOOST_MP_DEFINE_SIZED_CPP_INT_LITERAL(384)

template <char... TStr>
constexpr uint384_t operator""_u384()
{
#ifdef CRASH_ME
    return operator""_cppui384 < TStr...>();
#else
    return operator""_cppui384 < TStr...>() + 1 - 1;
#endif
}

int main()
{
    constexpr auto value = 0x00000001111111111111111111111111111111111111111111111111111111111111111111111111111111111111_u384;
    constexpr auto mask  = 0x0000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF_u384;

    constexpr auto masked = value & mask;

    std::cout << std::hex << "value:  0x" << value  << "\n";
    std::cout << std::hex << "masked: 0x" << masked << "\n";
    assert(value == masked);
}

Output:

value:  0x1111111111111111111111111111111111111111111111111111111111111111111111111111111111111
masked: 0x1111111111111111111111111111111111111111111111111111111111111111111111111111111111111
Assertion failed: value == masked, file main.cpp, line 33

Environment

Windows 11 (10.0.26200.8655)

Boost 1.88.0

MSVC 19.40.33813.0 (VS 2022, toolchain version 14.40)

I have not had much luck reproducing this under Linux/GCC, it may be MSVC specific.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions