From 440f7adfdc4338082265dd5e6c0f6584d3c4ce9f Mon Sep 17 00:00:00 2001 From: John McFarlane Date: Wed, 9 Feb 2022 08:49:41 +0000 Subject: [PATCH 1/3] Add compiler error reported in 991 by @vrqq --- .../scaled_integer/rounding/rounding_scaled_integer.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/test/unit/scaled_integer/rounding/rounding_scaled_integer.cpp b/test/unit/scaled_integer/rounding/rounding_scaled_integer.cpp index 558b1d87c..e6b8bbafb 100644 --- a/test/unit/scaled_integer/rounding/rounding_scaled_integer.cpp +++ b/test/unit/scaled_integer/rounding/rounding_scaled_integer.cpp @@ -82,4 +82,12 @@ namespace { static_assert(identical(dest_type{0}, dest_type{source_type{.75}}), ""); static_assert(identical(dest_type{1}, dest_type{source_type{1.}}), ""); } + + TEST(rounding_scaled_integer, 991) + { + using DecX = cnl::scaled_integer, cnl::power<-1, 100>>; + DecX num1 = 10.554; + DecX num2 = 10.545; + std::cout< Date: Tue, 8 Feb 2022 18:44:35 +0000 Subject: [PATCH 2/3] 911 fix supplied by @vrqq --- include/cnl/_impl/num_traits/scale.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/include/cnl/_impl/num_traits/scale.h b/include/cnl/_impl/num_traits/scale.h index dd32a72f6..fca7eef53 100644 --- a/include/cnl/_impl/num_traits/scale.h +++ b/include/cnl/_impl/num_traits/scale.h @@ -46,6 +46,18 @@ namespace cnl { : _impl::default_scale { }; + template + class TNUM, typename S, typename Tag> + struct scale, _impl::enable_if_t<( + Digits<0 && cnl::_impl::is_integral::value)>> + { + CNL_NODISCARD constexpr auto operator()(TNUM const& s) const + -> decltype(s/_impl::power_value()) + { + return s/_impl::power_value(); + } + }; + namespace _impl { // cnl::_impl::scale - convenience wrapper for cnl::scale template From 0ff81a4779b26ddf6b6c478c66a6a4d1584cd4d8 Mon Sep 17 00:00:00 2001 From: vrqq Date: Thu, 9 Mar 2023 23:24:42 +0800 Subject: [PATCH 3/3] Try to fix issue #991 --- include/cnl/_impl/num_traits/scale.h | 12 ----- include/cnl/rounding_integer.h | 10 +++++ .../rounding/rounding_scaled_integer.cpp | 45 +++++++++++++++++++ 3 files changed, 55 insertions(+), 12 deletions(-) diff --git a/include/cnl/_impl/num_traits/scale.h b/include/cnl/_impl/num_traits/scale.h index fca7eef53..dd32a72f6 100644 --- a/include/cnl/_impl/num_traits/scale.h +++ b/include/cnl/_impl/num_traits/scale.h @@ -46,18 +46,6 @@ namespace cnl { : _impl::default_scale { }; - template - class TNUM, typename S, typename Tag> - struct scale, _impl::enable_if_t<( - Digits<0 && cnl::_impl::is_integral::value)>> - { - CNL_NODISCARD constexpr auto operator()(TNUM const& s) const - -> decltype(s/_impl::power_value()) - { - return s/_impl::power_value(); - } - }; - namespace _impl { // cnl::_impl::scale - convenience wrapper for cnl::scale template diff --git a/include/cnl/rounding_integer.h b/include/cnl/rounding_integer.h index 5eab887a9..72ba9fd93 100644 --- a/include/cnl/rounding_integer.h +++ b/include/cnl/rounding_integer.h @@ -71,6 +71,16 @@ namespace cnl { scale{}(_impl::to_rep(s))); } }; + + template + struct scale, + _impl::enable_if_t::value>> { + CNL_NODISCARD constexpr auto operator()(_impl::number const& s) const + -> decltype(s/_impl::power_value()) + { + return s/_impl::power_value(); + } + }; //////////////////////////////////////////////////////////////////////////////// // cnl::set_rep diff --git a/test/unit/scaled_integer/rounding/rounding_scaled_integer.cpp b/test/unit/scaled_integer/rounding/rounding_scaled_integer.cpp index e6b8bbafb..c89397a07 100644 --- a/test/unit/scaled_integer/rounding/rounding_scaled_integer.cpp +++ b/test/unit/scaled_integer/rounding/rounding_scaled_integer.cpp @@ -90,4 +90,49 @@ namespace { DecX num2 = 10.545; std::cout<, cnl::power<-2, 10>>; + using DecX_4 = cnl::scaled_integer, cnl::power<-4, 10>>; + + DecX_2 n1 = 10.0151; + DecX_2 n2 = 10.0249; + EXPECT_EQ(n1, n2); // 10.02 + + int64_t xn = (int64_t)n1; + double xm = (double)n2; + EXPECT_EQ(xn, 10); + EXPECT_DOUBLE_EQ(xm, 10.02); + + static_assert(std::is_same_v); + EXPECT_EQ(n1*n2, DecX_4{100.4004}); + EXPECT_DOUBLE_EQ((double)(n1*n2), 100.4004); + + n1 += 0.6; + EXPECT_EQ((int)n1, 11); + + n1 += 0.38; + EXPECT_EQ(n1, 11); + + xn += n1; + xm -= n1; + } + + TEST(rounding_scaled_integer, 991CmpTest) + { + using DecX_2 = cnl::scaled_integer, cnl::power<-2, 10>>; + + DecX_2 n1; + DecX_2 n2 = 10.019; + DecX_2 n3{20.029}; + EXPECT_DOUBLE_EQ((double)n2, 10.02); + EXPECT_DOUBLE_EQ((double)n3, 20.03); + + n1 = 3.999; //4.00 instead + n3 = DecX_2(8); + EXPECT_NE(n1, 3.9899999999999999999999999); + EXPECT_EQ(n1, 4.0000000000000000000000001); + EXPECT_EQ(n3, 8); + } }