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

Incorrect == with __uint128t/uint64_t #799

Open
libbooze opened this issue Jan 18, 2025 · 2 comments
Open

Incorrect == with __uint128t/uint64_t #799

libbooze opened this issue Jan 18, 2025 · 2 comments
Labels
Boost Review Collected Comments from Boost Review Period Bug Something isn't working

Comments

@libbooze
Copy link

libbooze commented Jan 18, 2025

Following code:

template<typename Dec>
void mixed_compare()
{
    std::print("{}\n", boost::typeindex::type_id<Dec>().pretty_name());
    const Dec a{2, 1};
    const auto b = __uint128_t{std::numeric_limits<__uint128_t>::max() - std::numeric_limits<uint64_t>::max() + 20};
    std::print("a:{:.30e}\nb:{}\n", a , b);
    std::print("same {} \n\n", a  == b );
}

on my machine prints

boost::decimal::decimal32
a:2.000000000000000000000000000000e+01
b:340282366920938463444927863358058659860
same true 

boost::decimal::decimal64
a:2.000000000000000000000000000000e+01
b:340282366920938463444927863358058659860
same true 

boost::decimal::decimal128
a:2.000000000000000000000000000000e+01
b:340282366920938463444927863358058659860
same false 

I guess it is clear from test construction what I think the bug is(truncation). _fast code works fine for all sizes(probably because it dispatches to different equal_parts_impl).

edit:
For decimal32 bug persists if we "halve" the types used in b

    const auto b = uint64_t{std::numeric_limits<uint64_t>::max() - std::numeric_limits<uint32_t>::max() + 20};
@libbooze libbooze changed the title Incorrect == with __uint128t Incorrect == with __uint128t/uint64_t Jan 18, 2025
@mborland
Copy link
Member

We didn't design or test for math against non-standard extensions like __uint128_t. Really the only functionality that exists for them is conversion from or too. In the uint64_t case there's likely narrowing somewhere. It works in the decimal32_fast case because I'm willing to bet that your machine has uint_fast32_t as uint64_t

@mborland mborland added Bug Something isn't working Boost Review Collected Comments from Boost Review Period labels Jan 20, 2025
@libbooze
Copy link
Author

I'm willing to bet that your machine has uint_fast32_t as uint64_t

I am on linux, this is what my IDE navigation resolves typedf to:
typedef unsigned long int uint_fast32_t;
so yes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Boost Review Collected Comments from Boost Review Period Bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants