numerical-collection-cpp 0.10.0
A collection of algorithms in numerical analysis implemented in C++
Loading...
Searching...
No Matches
quad.h
Go to the documentation of this file.
1/*
2 * Copyright 2021 MusicScience37 (Kenta Kabashima)
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
20#pragma once
21
22#include <tuple>
23#include <type_traits>
24
26
28
32class quad {
33public:
37 constexpr quad() noexcept = default;
38
45 constexpr quad(double high, double low) noexcept : high_(high), low_(low) {}
46
53 template <typename Scalar,
54 std::enable_if_t<(std::is_integral_v<Scalar> ||
55 std::is_floating_point_v<Scalar>) &&
56 (!std::is_same_v<Scalar,
57 quad>)>* = nullptr>
58 constexpr quad(Scalar value) noexcept // NOLINT
59 : high_(static_cast<double>(value)) {}
60
66 [[nodiscard]] auto high() const noexcept -> double { return high_; }
67
73 [[nodiscard]] auto low() const noexcept -> double { return low_; }
74
80 auto operator-() const noexcept -> quad { return quad(-high_, -low_); }
81
88 auto operator+=(const quad& right) noexcept -> quad& {
89 auto [x_h, x_l] = impl::two_sum(high_, right.high_);
90 x_l += low_;
91 x_l += right.low_;
92 std::tie(high_, low_) = impl::quick_two_sum(x_h, x_l);
93 return *this;
94 }
95
102 auto operator-=(const quad& right) noexcept -> quad& {
103 return operator+=(-right);
104 }
105
112 auto operator*=(const quad& right) noexcept -> quad& {
113 auto [x_h, x_l] = impl::two_prod(high_, right.high_);
114 x_l += high_ * right.low_;
115 x_l += low_ * right.high_;
116 std::tie(high_, low_) = impl::quick_two_sum(x_h, x_l);
117 return *this;
118 }
119
126 auto operator/=(const quad& right) noexcept -> quad& {
127 const double inv_right_h = 1.0 / right.high_;
128 const double rate_right = right.low_ * inv_right_h;
129 const double x_h = high_ * inv_right_h;
130 const auto [r_1, r_2] = impl::two_prod(x_h, right.high_);
131 double x_l = ((high_ - r_1) - r_2) * inv_right_h;
132 x_l += x_h * ((low_ / high_) - rate_right);
133 std::tie(high_, low_) = impl::quick_two_sum(x_h, x_l);
134 return *this;
135 }
136
137private:
139 double high_{0.0};
140
142 double low_{0.0};
143};
144
152inline auto operator+(const quad& left, const quad& right) -> quad {
153 return quad(left) += right;
154}
155
163inline auto operator-(const quad& left, const quad& right) -> quad {
164 return quad(left) -= right;
165}
166
174inline auto operator*(const quad& left, const quad& right) -> quad {
175 return quad(left) *= right;
176}
177
185inline auto operator/(const quad& left, const quad& right) -> quad {
186 return quad(left) /= right;
187}
188
189} // namespace num_collect::multi_double
Definition of basic operations in multi-double calculations.
class of quadruple precision floating-point numbers
Definition quad.h:32
auto operator-=(const quad &right) noexcept -> quad &
subtract another number
Definition quad.h:102
auto operator*=(const quad &right) noexcept -> quad &
multiply with another number
Definition quad.h:112
auto operator+=(const quad &right) noexcept -> quad &
add another number
Definition quad.h:88
auto low() const noexcept -> double
get lower digits
Definition quad.h:73
double high_
higher digits
Definition quad.h:139
auto high() const noexcept -> double
get higher digits
Definition quad.h:66
double low_
lower digits
Definition quad.h:142
auto operator-() const noexcept -> quad
negate this number
Definition quad.h:80
auto operator/=(const quad &right) noexcept -> quad &
divide by another number
Definition quad.h:126
constexpr quad(Scalar value) noexcept
convert implicitly
Definition quad.h:58
constexpr quad() noexcept=default
construct zero
auto two_sum(double a, double b) -> std::tuple< double, double >
calculate sum of a and b, and error of the sum
auto two_prod(double a, double b) -> std::tuple< double, double >
calculate product of a and b, and error of the product
auto quick_two_sum(double a, double b) -> std::tuple< double, double >
calculate sum of a and b, and error of the sum on the condition that absolute value of a is larger th...
Namespace of multiple precision numbers with double numbers.
auto operator/(const quad &left, const quad &right) -> quad
divide a number by a number
Definition quad.h:185
auto operator*(const quad &left, const quad &right) -> quad
multiply a number by a number
Definition quad.h:174
auto operator+(const quad &left, const quad &right) -> quad
add two number
Definition quad.h:152
auto operator-(const quad &left, const quad &right) -> quad
subtract a number from a number
Definition quad.h:163