From 022b1da059ee02d5086a0231e05f037a181a141d Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Sat, 27 Apr 2024 07:57:27 -0400 Subject: [PATCH] xo-unit: + width2x + use in nu_product, nu_ratio --- include/xo/unit/scaled_unit.hpp | 76 +++++++++++++++++++++++---------- 1 file changed, 54 insertions(+), 22 deletions(-) diff --git a/include/xo/unit/scaled_unit.hpp b/include/xo/unit/scaled_unit.hpp index 6f0d9268..e529b4ce 100644 --- a/include/xo/unit/scaled_unit.hpp +++ b/include/xo/unit/scaled_unit.hpp @@ -48,6 +48,27 @@ namespace xo { } namespace detail { + template + struct width2x; + + template <> + struct width2x { + using type = std::int32_t; + }; + + template <> + struct width2x { + using type = std::int64_t; + }; + + template <> + struct width2x { + using type = __int128_t; + }; + + template + using width2x_t = width2x::type; + template constexpr detail::bpu2_rescale_result @@ -78,52 +99,57 @@ namespace xo { rr.outer_scale_sq_); }; - template + template > constexpr scaled_unit nu_product(const natural_unit & lhs_bpu_array, const natural_unit & rhs_bpu_array) { - natural_unit prod = lhs_bpu_array; + natural_unit prod = lhs_bpu_array.template to_repr(); /* accumulate product of scalefactors spun off by rescaling * any basis-units in rhs_bpu_array that conflict with the same dimension * in lh_bpu_array */ - auto sfr = (detail::outer_scalefactor_result - (scalefactor_ratio_type(1, 1) /*outer_scale_exact*/, + auto sfr = (detail::outer_scalefactor_result + (ratio::ratio(1, 1) /*outer_scale_exact*/, 1.0 /*outer_scale_sq*/)); for (std::size_t i = 0; i < rhs_bpu_array.n_bpu(); ++i) { - auto sfr2 = nu_product_inplace(&prod, rhs_bpu_array[i]); + auto sfr2 = nu_product_inplace(&prod, rhs_bpu_array[i].template to_repr()); sfr.outer_scale_exact_ = sfr.outer_scale_exact_ * sfr2.outer_scale_exact_; sfr.outer_scale_sq_ *= sfr2.outer_scale_sq_; } - return scaled_unit(prod, - sfr.outer_scale_exact_, - sfr.outer_scale_sq_); + return scaled_unit(prod.template to_repr(), + sfr.outer_scale_exact_, + sfr.outer_scale_sq_); } - template + /* use Int2x to accumulate scalefactor + * + * TODO: rename to su_ratio() + * + */ + template > constexpr scaled_unit nu_ratio(const natural_unit & nu_lhs, const natural_unit & nu_rhs) { - natural_unit ratio = nu_lhs; + natural_unit ratio = nu_lhs.template to_repr(); /* accumulate product of scalefactors spun off by rescaling * any basis-units in rhs_bpu_array that conflict with the same dimension * in lh_bpu_array */ - auto sfr = (detail::outer_scalefactor_result - (scalefactor_ratio_type(1, 1) /*outer_scale_exact*/, + auto sfr = (detail::outer_scalefactor_result + (ratio::ratio(1, 1) /*outer_scale_exact*/, 1.0 /*outer_scale_sq*/)); for (std::size_t i = 0; i < nu_rhs.n_bpu(); ++i) { - auto sfr2 = nu_ratio_inplace(&ratio, nu_rhs[i]); + auto sfr2 = nu_ratio_inplace(&ratio, nu_rhs[i].template to_repr()); /* note: nu_ratio_inplace() reports multiplicative outer scaling factors, * so multiply is correct here @@ -132,37 +158,43 @@ namespace xo { sfr.outer_scale_sq_ *= sfr2.outer_scale_sq_; } - return scaled_unit(ratio, + return scaled_unit(ratio.template to_repr(), sfr.outer_scale_exact_, sfr.outer_scale_sq_); } } - template + template > inline constexpr scaled_unit operator* (const scaled_unit & x_unit, const scaled_unit & y_unit) { - auto rr = detail::nu_product(x_unit.natural_unit_, - y_unit.natural_unit_); + auto rr = detail::nu_product(x_unit.natural_unit_, + y_unit.natural_unit_); return (scaled_unit (rr.natural_unit_, - rr.outer_scale_exact_ * x_unit.outer_scale_exact_ * y_unit.outer_scale_exact_, + (ratio::ratio(rr.outer_scale_exact_) + * ratio::ratio(x_unit.outer_scale_exact_) + * ratio::ratio(y_unit.outer_scale_exact_)), rr.outer_scale_sq_ * x_unit.outer_scale_sq_ * y_unit.outer_scale_sq_)); } - template + template > inline constexpr scaled_unit operator/ (const scaled_unit & x_unit, const scaled_unit & y_unit) { - auto rr = detail::nu_ratio(x_unit.natural_unit_, - y_unit.natural_unit_); + auto rr = detail::nu_ratio(x_unit.natural_unit_, + y_unit.natural_unit_); return (scaled_unit (rr.natural_unit_, - rr.outer_scale_exact_ * x_unit.outer_scale_exact_ * y_unit.outer_scale_exact_, + (ratio::ratio(rr.outer_scale_exact_) + * ratio::ratio(x_unit.outer_scale_exact_) + * ratio::ratio(y_unit.outer_scale_exact_)), rr.outer_scale_sq_ * x_unit.outer_scale_sq_ * y_unit.outer_scale_sq_)); } } /*namespace qty*/