11debfc3dSmrg// ratio -*- C++ -*- 21debfc3dSmrg 3*8feb0f0bSmrg// Copyright (C) 2008-2020 Free Software Foundation, Inc. 41debfc3dSmrg// 51debfc3dSmrg// This file is part of the GNU ISO C++ Library. This library is free 61debfc3dSmrg// software; you can redistribute it and/or modify it under the 71debfc3dSmrg// terms of the GNU General Public License as published by the 81debfc3dSmrg// Free Software Foundation; either version 3, or (at your option) 91debfc3dSmrg// any later version. 101debfc3dSmrg 111debfc3dSmrg// This library is distributed in the hope that it will be useful, 121debfc3dSmrg// but WITHOUT ANY WARRANTY; without even the implied warranty of 131debfc3dSmrg// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 141debfc3dSmrg// GNU General Public License for more details. 151debfc3dSmrg 161debfc3dSmrg// Under Section 7 of GPL version 3, you are granted additional 171debfc3dSmrg// permissions described in the GCC Runtime Library Exception, version 181debfc3dSmrg// 3.1, as published by the Free Software Foundation. 191debfc3dSmrg 201debfc3dSmrg// You should have received a copy of the GNU General Public License and 211debfc3dSmrg// a copy of the GCC Runtime Library Exception along with this program; 221debfc3dSmrg// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 231debfc3dSmrg// <http://www.gnu.org/licenses/>. 241debfc3dSmrg 251debfc3dSmrg/** @file include/ratio 261debfc3dSmrg * This is a Standard C++ Library header. 27*8feb0f0bSmrg * @ingroup ratio 281debfc3dSmrg */ 291debfc3dSmrg 301debfc3dSmrg#ifndef _GLIBCXX_RATIO 311debfc3dSmrg#define _GLIBCXX_RATIO 1 321debfc3dSmrg 331debfc3dSmrg#pragma GCC system_header 341debfc3dSmrg 351debfc3dSmrg#if __cplusplus < 201103L 361debfc3dSmrg# include <bits/c++0x_warning.h> 371debfc3dSmrg#else 381debfc3dSmrg 391debfc3dSmrg#include <type_traits> 40c0a68be4Smrg#include <cstdint> // intmax_t, uintmax_t 411debfc3dSmrg 421debfc3dSmrgnamespace std _GLIBCXX_VISIBILITY(default) 431debfc3dSmrg{ 441debfc3dSmrg_GLIBCXX_BEGIN_NAMESPACE_VERSION 451debfc3dSmrg 461debfc3dSmrg /** 471debfc3dSmrg * @defgroup ratio Rational Arithmetic 481debfc3dSmrg * @ingroup utilities 491debfc3dSmrg * 501debfc3dSmrg * Compile time representation of finite rational numbers. 511debfc3dSmrg * @{ 521debfc3dSmrg */ 531debfc3dSmrg 54*8feb0f0bSmrg /// @cond undocumented 55*8feb0f0bSmrg 561debfc3dSmrg template<intmax_t _Pn> 571debfc3dSmrg struct __static_sign 581debfc3dSmrg : integral_constant<intmax_t, (_Pn < 0) ? -1 : 1> 591debfc3dSmrg { }; 601debfc3dSmrg 611debfc3dSmrg template<intmax_t _Pn> 621debfc3dSmrg struct __static_abs 631debfc3dSmrg : integral_constant<intmax_t, _Pn * __static_sign<_Pn>::value> 641debfc3dSmrg { }; 651debfc3dSmrg 661debfc3dSmrg template<intmax_t _Pn, intmax_t _Qn> 671debfc3dSmrg struct __static_gcd 681debfc3dSmrg : __static_gcd<_Qn, (_Pn % _Qn)> 691debfc3dSmrg { }; 701debfc3dSmrg 711debfc3dSmrg template<intmax_t _Pn> 721debfc3dSmrg struct __static_gcd<_Pn, 0> 731debfc3dSmrg : integral_constant<intmax_t, __static_abs<_Pn>::value> 741debfc3dSmrg { }; 751debfc3dSmrg 761debfc3dSmrg template<intmax_t _Qn> 771debfc3dSmrg struct __static_gcd<0, _Qn> 781debfc3dSmrg : integral_constant<intmax_t, __static_abs<_Qn>::value> 791debfc3dSmrg { }; 801debfc3dSmrg 811debfc3dSmrg // Let c = 2^(half # of bits in an intmax_t) 821debfc3dSmrg // then we find a1, a0, b1, b0 s.t. N = a1*c + a0, M = b1*c + b0 831debfc3dSmrg // The multiplication of N and M becomes, 841debfc3dSmrg // N * M = (a1 * b1)c^2 + (a0 * b1 + b0 * a1)c + a0 * b0 851debfc3dSmrg // Multiplication is safe if each term and the sum of the terms 861debfc3dSmrg // is representable by intmax_t. 871debfc3dSmrg template<intmax_t _Pn, intmax_t _Qn> 881debfc3dSmrg struct __safe_multiply 891debfc3dSmrg { 901debfc3dSmrg private: 911debfc3dSmrg static const uintmax_t __c = uintmax_t(1) << (sizeof(intmax_t) * 4); 921debfc3dSmrg 931debfc3dSmrg static const uintmax_t __a0 = __static_abs<_Pn>::value % __c; 941debfc3dSmrg static const uintmax_t __a1 = __static_abs<_Pn>::value / __c; 951debfc3dSmrg static const uintmax_t __b0 = __static_abs<_Qn>::value % __c; 961debfc3dSmrg static const uintmax_t __b1 = __static_abs<_Qn>::value / __c; 971debfc3dSmrg 981debfc3dSmrg static_assert(__a1 == 0 || __b1 == 0, 991debfc3dSmrg "overflow in multiplication"); 1001debfc3dSmrg static_assert(__a0 * __b1 + __b0 * __a1 < (__c >> 1), 1011debfc3dSmrg "overflow in multiplication"); 1021debfc3dSmrg static_assert(__b0 * __a0 <= __INTMAX_MAX__, 1031debfc3dSmrg "overflow in multiplication"); 1041debfc3dSmrg static_assert((__a0 * __b1 + __b0 * __a1) * __c 1051debfc3dSmrg <= __INTMAX_MAX__ - __b0 * __a0, 1061debfc3dSmrg "overflow in multiplication"); 1071debfc3dSmrg 1081debfc3dSmrg public: 1091debfc3dSmrg static const intmax_t value = _Pn * _Qn; 1101debfc3dSmrg }; 1111debfc3dSmrg 1121debfc3dSmrg // Some double-precision utilities, where numbers are represented as 1131debfc3dSmrg // __hi*2^(8*sizeof(uintmax_t)) + __lo. 1141debfc3dSmrg template<uintmax_t __hi1, uintmax_t __lo1, uintmax_t __hi2, uintmax_t __lo2> 1151debfc3dSmrg struct __big_less 1161debfc3dSmrg : integral_constant<bool, (__hi1 < __hi2 1171debfc3dSmrg || (__hi1 == __hi2 && __lo1 < __lo2))> 1181debfc3dSmrg { }; 1191debfc3dSmrg 1201debfc3dSmrg template<uintmax_t __hi1, uintmax_t __lo1, uintmax_t __hi2, uintmax_t __lo2> 1211debfc3dSmrg struct __big_add 1221debfc3dSmrg { 1231debfc3dSmrg static constexpr uintmax_t __lo = __lo1 + __lo2; 1241debfc3dSmrg static constexpr uintmax_t __hi = (__hi1 + __hi2 + 1251debfc3dSmrg (__lo1 + __lo2 < __lo1)); // carry 1261debfc3dSmrg }; 1271debfc3dSmrg 1281debfc3dSmrg // Subtract a number from a bigger one. 1291debfc3dSmrg template<uintmax_t __hi1, uintmax_t __lo1, uintmax_t __hi2, uintmax_t __lo2> 1301debfc3dSmrg struct __big_sub 1311debfc3dSmrg { 1321debfc3dSmrg static_assert(!__big_less<__hi1, __lo1, __hi2, __lo2>::value, 1331debfc3dSmrg "Internal library error"); 1341debfc3dSmrg static constexpr uintmax_t __lo = __lo1 - __lo2; 1351debfc3dSmrg static constexpr uintmax_t __hi = (__hi1 - __hi2 - 1361debfc3dSmrg (__lo1 < __lo2)); // carry 1371debfc3dSmrg }; 1381debfc3dSmrg 1391debfc3dSmrg // Same principle as __safe_multiply. 1401debfc3dSmrg template<uintmax_t __x, uintmax_t __y> 1411debfc3dSmrg struct __big_mul 1421debfc3dSmrg { 1431debfc3dSmrg private: 1441debfc3dSmrg static constexpr uintmax_t __c = uintmax_t(1) << (sizeof(intmax_t) * 4); 1451debfc3dSmrg static constexpr uintmax_t __x0 = __x % __c; 1461debfc3dSmrg static constexpr uintmax_t __x1 = __x / __c; 1471debfc3dSmrg static constexpr uintmax_t __y0 = __y % __c; 1481debfc3dSmrg static constexpr uintmax_t __y1 = __y / __c; 1491debfc3dSmrg static constexpr uintmax_t __x0y0 = __x0 * __y0; 1501debfc3dSmrg static constexpr uintmax_t __x0y1 = __x0 * __y1; 1511debfc3dSmrg static constexpr uintmax_t __x1y0 = __x1 * __y0; 1521debfc3dSmrg static constexpr uintmax_t __x1y1 = __x1 * __y1; 1531debfc3dSmrg static constexpr uintmax_t __mix = __x0y1 + __x1y0; // possible carry... 1541debfc3dSmrg static constexpr uintmax_t __mix_lo = __mix * __c; 1551debfc3dSmrg static constexpr uintmax_t __mix_hi 1561debfc3dSmrg = __mix / __c + ((__mix < __x0y1) ? __c : 0); // ... added here 1571debfc3dSmrg typedef __big_add<__mix_hi, __mix_lo, __x1y1, __x0y0> _Res; 1581debfc3dSmrg public: 1591debfc3dSmrg static constexpr uintmax_t __hi = _Res::__hi; 1601debfc3dSmrg static constexpr uintmax_t __lo = _Res::__lo; 1611debfc3dSmrg }; 1621debfc3dSmrg 1631debfc3dSmrg // Adapted from __udiv_qrnnd_c in longlong.h 1641debfc3dSmrg // This version assumes that the high bit of __d is 1. 1651debfc3dSmrg template<uintmax_t __n1, uintmax_t __n0, uintmax_t __d> 1661debfc3dSmrg struct __big_div_impl 1671debfc3dSmrg { 1681debfc3dSmrg private: 1691debfc3dSmrg static_assert(__d >= (uintmax_t(1) << (sizeof(intmax_t) * 8 - 1)), 1701debfc3dSmrg "Internal library error"); 1711debfc3dSmrg static_assert(__n1 < __d, "Internal library error"); 1721debfc3dSmrg static constexpr uintmax_t __c = uintmax_t(1) << (sizeof(intmax_t) * 4); 1731debfc3dSmrg static constexpr uintmax_t __d1 = __d / __c; 1741debfc3dSmrg static constexpr uintmax_t __d0 = __d % __c; 1751debfc3dSmrg 1761debfc3dSmrg static constexpr uintmax_t __q1x = __n1 / __d1; 1771debfc3dSmrg static constexpr uintmax_t __r1x = __n1 % __d1; 1781debfc3dSmrg static constexpr uintmax_t __m = __q1x * __d0; 1791debfc3dSmrg static constexpr uintmax_t __r1y = __r1x * __c + __n0 / __c; 1801debfc3dSmrg static constexpr uintmax_t __r1z = __r1y + __d; 1811debfc3dSmrg static constexpr uintmax_t __r1 1821debfc3dSmrg = ((__r1y < __m) ? ((__r1z >= __d) && (__r1z < __m)) 1831debfc3dSmrg ? (__r1z + __d) : __r1z : __r1y) - __m; 1841debfc3dSmrg static constexpr uintmax_t __q1 1851debfc3dSmrg = __q1x - ((__r1y < __m) 1861debfc3dSmrg ? ((__r1z >= __d) && (__r1z < __m)) ? 2 : 1 : 0); 1871debfc3dSmrg static constexpr uintmax_t __q0x = __r1 / __d1; 1881debfc3dSmrg static constexpr uintmax_t __r0x = __r1 % __d1; 1891debfc3dSmrg static constexpr uintmax_t __n = __q0x * __d0; 1901debfc3dSmrg static constexpr uintmax_t __r0y = __r0x * __c + __n0 % __c; 1911debfc3dSmrg static constexpr uintmax_t __r0z = __r0y + __d; 1921debfc3dSmrg static constexpr uintmax_t __r0 1931debfc3dSmrg = ((__r0y < __n) ? ((__r0z >= __d) && (__r0z < __n)) 1941debfc3dSmrg ? (__r0z + __d) : __r0z : __r0y) - __n; 1951debfc3dSmrg static constexpr uintmax_t __q0 1961debfc3dSmrg = __q0x - ((__r0y < __n) ? ((__r0z >= __d) 1971debfc3dSmrg && (__r0z < __n)) ? 2 : 1 : 0); 1981debfc3dSmrg 1991debfc3dSmrg public: 2001debfc3dSmrg static constexpr uintmax_t __quot = __q1 * __c + __q0; 2011debfc3dSmrg static constexpr uintmax_t __rem = __r0; 2021debfc3dSmrg 2031debfc3dSmrg private: 2041debfc3dSmrg typedef __big_mul<__quot, __d> _Prod; 2051debfc3dSmrg typedef __big_add<_Prod::__hi, _Prod::__lo, 0, __rem> _Sum; 2061debfc3dSmrg static_assert(_Sum::__hi == __n1 && _Sum::__lo == __n0, 2071debfc3dSmrg "Internal library error"); 2081debfc3dSmrg }; 2091debfc3dSmrg 2101debfc3dSmrg template<uintmax_t __n1, uintmax_t __n0, uintmax_t __d> 2111debfc3dSmrg struct __big_div 2121debfc3dSmrg { 2131debfc3dSmrg private: 2141debfc3dSmrg static_assert(__d != 0, "Internal library error"); 2151debfc3dSmrg static_assert(sizeof (uintmax_t) == sizeof (unsigned long long), 2161debfc3dSmrg "This library calls __builtin_clzll on uintmax_t, which " 2171debfc3dSmrg "is unsafe on your platform. Please complain to " 2181debfc3dSmrg "http://gcc.gnu.org/bugzilla/"); 2191debfc3dSmrg static constexpr int __shift = __builtin_clzll(__d); 2201debfc3dSmrg static constexpr int __coshift_ = sizeof(uintmax_t) * 8 - __shift; 2211debfc3dSmrg static constexpr int __coshift = (__shift != 0) ? __coshift_ : 0; 2221debfc3dSmrg static constexpr uintmax_t __c1 = uintmax_t(1) << __shift; 2231debfc3dSmrg static constexpr uintmax_t __c2 = uintmax_t(1) << __coshift; 2241debfc3dSmrg static constexpr uintmax_t __new_d = __d * __c1; 2251debfc3dSmrg static constexpr uintmax_t __new_n0 = __n0 * __c1; 2261debfc3dSmrg static constexpr uintmax_t __n1_shifted = (__n1 % __d) * __c1; 2271debfc3dSmrg static constexpr uintmax_t __n0_top = (__shift != 0) ? (__n0 / __c2) : 0; 2281debfc3dSmrg static constexpr uintmax_t __new_n1 = __n1_shifted + __n0_top; 2291debfc3dSmrg typedef __big_div_impl<__new_n1, __new_n0, __new_d> _Res; 2301debfc3dSmrg 2311debfc3dSmrg public: 2321debfc3dSmrg static constexpr uintmax_t __quot_hi = __n1 / __d; 2331debfc3dSmrg static constexpr uintmax_t __quot_lo = _Res::__quot; 2341debfc3dSmrg static constexpr uintmax_t __rem = _Res::__rem / __c1; 2351debfc3dSmrg 2361debfc3dSmrg private: 2371debfc3dSmrg typedef __big_mul<__quot_lo, __d> _P0; 2381debfc3dSmrg typedef __big_mul<__quot_hi, __d> _P1; 2391debfc3dSmrg typedef __big_add<_P0::__hi, _P0::__lo, _P1::__lo, __rem> _Sum; 2401debfc3dSmrg // No overflow. 2411debfc3dSmrg static_assert(_P1::__hi == 0, "Internal library error"); 2421debfc3dSmrg static_assert(_Sum::__hi >= _P0::__hi, "Internal library error"); 2431debfc3dSmrg // Matches the input data. 2441debfc3dSmrg static_assert(_Sum::__hi == __n1 && _Sum::__lo == __n0, 2451debfc3dSmrg "Internal library error"); 2461debfc3dSmrg static_assert(__rem < __d, "Internal library error"); 2471debfc3dSmrg }; 2481debfc3dSmrg 249*8feb0f0bSmrg /// @endcond 250*8feb0f0bSmrg 2511debfc3dSmrg /** 2521debfc3dSmrg * @brief Provides compile-time rational arithmetic. 2531debfc3dSmrg * 2541debfc3dSmrg * This class template represents any finite rational number with a 2551debfc3dSmrg * numerator and denominator representable by compile-time constants of 2561debfc3dSmrg * type intmax_t. The ratio is simplified when instantiated. 2571debfc3dSmrg * 2581debfc3dSmrg * For example: 2591debfc3dSmrg * @code 2601debfc3dSmrg * std::ratio<7,-21>::num == -1; 2611debfc3dSmrg * std::ratio<7,-21>::den == 3; 2621debfc3dSmrg * @endcode 2631debfc3dSmrg * 2641debfc3dSmrg */ 2651debfc3dSmrg template<intmax_t _Num, intmax_t _Den = 1> 2661debfc3dSmrg struct ratio 2671debfc3dSmrg { 2681debfc3dSmrg static_assert(_Den != 0, "denominator cannot be zero"); 2691debfc3dSmrg static_assert(_Num >= -__INTMAX_MAX__ && _Den >= -__INTMAX_MAX__, 2701debfc3dSmrg "out of range"); 2711debfc3dSmrg 2721debfc3dSmrg // Note: sign(N) * abs(N) == N 2731debfc3dSmrg static constexpr intmax_t num = 2741debfc3dSmrg _Num * __static_sign<_Den>::value / __static_gcd<_Num, _Den>::value; 2751debfc3dSmrg 2761debfc3dSmrg static constexpr intmax_t den = 2771debfc3dSmrg __static_abs<_Den>::value / __static_gcd<_Num, _Den>::value; 2781debfc3dSmrg 2791debfc3dSmrg typedef ratio<num, den> type; 2801debfc3dSmrg }; 2811debfc3dSmrg 2821debfc3dSmrg template<intmax_t _Num, intmax_t _Den> 2831debfc3dSmrg constexpr intmax_t ratio<_Num, _Den>::num; 2841debfc3dSmrg 2851debfc3dSmrg template<intmax_t _Num, intmax_t _Den> 2861debfc3dSmrg constexpr intmax_t ratio<_Num, _Den>::den; 2871debfc3dSmrg 288*8feb0f0bSmrg /// @cond undocumented 289*8feb0f0bSmrg 2901debfc3dSmrg template<typename _R1, typename _R2> 2911debfc3dSmrg struct __ratio_multiply 2921debfc3dSmrg { 2931debfc3dSmrg private: 2941debfc3dSmrg static const intmax_t __gcd1 = 2951debfc3dSmrg __static_gcd<_R1::num, _R2::den>::value; 2961debfc3dSmrg static const intmax_t __gcd2 = 2971debfc3dSmrg __static_gcd<_R2::num, _R1::den>::value; 2981debfc3dSmrg 2991debfc3dSmrg public: 3001debfc3dSmrg typedef ratio< 3011debfc3dSmrg __safe_multiply<(_R1::num / __gcd1), 3021debfc3dSmrg (_R2::num / __gcd2)>::value, 3031debfc3dSmrg __safe_multiply<(_R1::den / __gcd2), 3041debfc3dSmrg (_R2::den / __gcd1)>::value> type; 3051debfc3dSmrg 3061debfc3dSmrg static constexpr intmax_t num = type::num; 3071debfc3dSmrg static constexpr intmax_t den = type::den; 3081debfc3dSmrg }; 3091debfc3dSmrg 3101debfc3dSmrg template<typename _R1, typename _R2> 3111debfc3dSmrg constexpr intmax_t __ratio_multiply<_R1, _R2>::num; 3121debfc3dSmrg 3131debfc3dSmrg template<typename _R1, typename _R2> 3141debfc3dSmrg constexpr intmax_t __ratio_multiply<_R1, _R2>::den; 3151debfc3dSmrg 316*8feb0f0bSmrg /// @endcond 317*8feb0f0bSmrg 3181debfc3dSmrg /// ratio_multiply 3191debfc3dSmrg template<typename _R1, typename _R2> 3201debfc3dSmrg using ratio_multiply = typename __ratio_multiply<_R1, _R2>::type; 3211debfc3dSmrg 322*8feb0f0bSmrg /// @cond undocumented 323*8feb0f0bSmrg 3241debfc3dSmrg template<typename _R1, typename _R2> 3251debfc3dSmrg struct __ratio_divide 3261debfc3dSmrg { 3271debfc3dSmrg static_assert(_R2::num != 0, "division by 0"); 3281debfc3dSmrg 3291debfc3dSmrg typedef typename __ratio_multiply< 3301debfc3dSmrg _R1, 3311debfc3dSmrg ratio<_R2::den, _R2::num>>::type type; 3321debfc3dSmrg 3331debfc3dSmrg static constexpr intmax_t num = type::num; 3341debfc3dSmrg static constexpr intmax_t den = type::den; 3351debfc3dSmrg }; 3361debfc3dSmrg 3371debfc3dSmrg template<typename _R1, typename _R2> 3381debfc3dSmrg constexpr intmax_t __ratio_divide<_R1, _R2>::num; 3391debfc3dSmrg 3401debfc3dSmrg template<typename _R1, typename _R2> 3411debfc3dSmrg constexpr intmax_t __ratio_divide<_R1, _R2>::den; 3421debfc3dSmrg 343*8feb0f0bSmrg /// @endcond 344*8feb0f0bSmrg 3451debfc3dSmrg /// ratio_divide 3461debfc3dSmrg template<typename _R1, typename _R2> 3471debfc3dSmrg using ratio_divide = typename __ratio_divide<_R1, _R2>::type; 3481debfc3dSmrg 3491debfc3dSmrg /// ratio_equal 3501debfc3dSmrg template<typename _R1, typename _R2> 3511debfc3dSmrg struct ratio_equal 3521debfc3dSmrg : integral_constant<bool, _R1::num == _R2::num && _R1::den == _R2::den> 3531debfc3dSmrg { }; 3541debfc3dSmrg 3551debfc3dSmrg /// ratio_not_equal 3561debfc3dSmrg template<typename _R1, typename _R2> 3571debfc3dSmrg struct ratio_not_equal 3581debfc3dSmrg : integral_constant<bool, !ratio_equal<_R1, _R2>::value> 3591debfc3dSmrg { }; 3601debfc3dSmrg 361*8feb0f0bSmrg /// @cond undocumented 362*8feb0f0bSmrg 3631debfc3dSmrg // Both numbers are positive. 3641debfc3dSmrg template<typename _R1, typename _R2, 3651debfc3dSmrg typename _Left = __big_mul<_R1::num,_R2::den>, 3661debfc3dSmrg typename _Right = __big_mul<_R2::num,_R1::den> > 3671debfc3dSmrg struct __ratio_less_impl_1 3681debfc3dSmrg : integral_constant<bool, __big_less<_Left::__hi, _Left::__lo, 3691debfc3dSmrg _Right::__hi, _Right::__lo>::value> 3701debfc3dSmrg { }; 3711debfc3dSmrg 3721debfc3dSmrg template<typename _R1, typename _R2, 3731debfc3dSmrg bool = (_R1::num == 0 || _R2::num == 0 3741debfc3dSmrg || (__static_sign<_R1::num>::value 3751debfc3dSmrg != __static_sign<_R2::num>::value)), 3761debfc3dSmrg bool = (__static_sign<_R1::num>::value == -1 3771debfc3dSmrg && __static_sign<_R2::num>::value == -1)> 3781debfc3dSmrg struct __ratio_less_impl 3791debfc3dSmrg : __ratio_less_impl_1<_R1, _R2>::type 3801debfc3dSmrg { }; 3811debfc3dSmrg 3821debfc3dSmrg template<typename _R1, typename _R2> 3831debfc3dSmrg struct __ratio_less_impl<_R1, _R2, true, false> 3841debfc3dSmrg : integral_constant<bool, _R1::num < _R2::num> 3851debfc3dSmrg { }; 3861debfc3dSmrg 3871debfc3dSmrg template<typename _R1, typename _R2> 3881debfc3dSmrg struct __ratio_less_impl<_R1, _R2, false, true> 3891debfc3dSmrg : __ratio_less_impl_1<ratio<-_R2::num, _R2::den>, 3901debfc3dSmrg ratio<-_R1::num, _R1::den> >::type 3911debfc3dSmrg { }; 3921debfc3dSmrg 393*8feb0f0bSmrg /// @endcond 394*8feb0f0bSmrg 3951debfc3dSmrg /// ratio_less 3961debfc3dSmrg template<typename _R1, typename _R2> 3971debfc3dSmrg struct ratio_less 3981debfc3dSmrg : __ratio_less_impl<_R1, _R2>::type 3991debfc3dSmrg { }; 4001debfc3dSmrg 4011debfc3dSmrg /// ratio_less_equal 4021debfc3dSmrg template<typename _R1, typename _R2> 4031debfc3dSmrg struct ratio_less_equal 4041debfc3dSmrg : integral_constant<bool, !ratio_less<_R2, _R1>::value> 4051debfc3dSmrg { }; 4061debfc3dSmrg 4071debfc3dSmrg /// ratio_greater 4081debfc3dSmrg template<typename _R1, typename _R2> 4091debfc3dSmrg struct ratio_greater 4101debfc3dSmrg : integral_constant<bool, ratio_less<_R2, _R1>::value> 4111debfc3dSmrg { }; 4121debfc3dSmrg 4131debfc3dSmrg /// ratio_greater_equal 4141debfc3dSmrg template<typename _R1, typename _R2> 4151debfc3dSmrg struct ratio_greater_equal 4161debfc3dSmrg : integral_constant<bool, !ratio_less<_R1, _R2>::value> 4171debfc3dSmrg { }; 4181debfc3dSmrg 4191debfc3dSmrg#if __cplusplus > 201402L 4201debfc3dSmrg template <typename _R1, typename _R2> 4211debfc3dSmrg inline constexpr bool ratio_equal_v = ratio_equal<_R1, _R2>::value; 4221debfc3dSmrg template <typename _R1, typename _R2> 4231debfc3dSmrg inline constexpr bool ratio_not_equal_v = ratio_not_equal<_R1, _R2>::value; 4241debfc3dSmrg template <typename _R1, typename _R2> 4251debfc3dSmrg inline constexpr bool ratio_less_v = ratio_less<_R1, _R2>::value; 4261debfc3dSmrg template <typename _R1, typename _R2> 4271debfc3dSmrg inline constexpr bool ratio_less_equal_v = 4281debfc3dSmrg ratio_less_equal<_R1, _R2>::value; 4291debfc3dSmrg template <typename _R1, typename _R2> 4301debfc3dSmrg inline constexpr bool ratio_greater_v = ratio_greater<_R1, _R2>::value; 4311debfc3dSmrg template <typename _R1, typename _R2> 4321debfc3dSmrg inline constexpr bool ratio_greater_equal_v 4331debfc3dSmrg = ratio_greater_equal<_R1, _R2>::value; 4341debfc3dSmrg#endif // C++17 4351debfc3dSmrg 436*8feb0f0bSmrg /// @cond undocumented 437*8feb0f0bSmrg 4381debfc3dSmrg template<typename _R1, typename _R2, 4391debfc3dSmrg bool = (_R1::num >= 0), 4401debfc3dSmrg bool = (_R2::num >= 0), 4411debfc3dSmrg bool = ratio_less<ratio<__static_abs<_R1::num>::value, _R1::den>, 4421debfc3dSmrg ratio<__static_abs<_R2::num>::value, _R2::den> >::value> 4431debfc3dSmrg struct __ratio_add_impl 4441debfc3dSmrg { 4451debfc3dSmrg private: 4461debfc3dSmrg typedef typename __ratio_add_impl< 4471debfc3dSmrg ratio<-_R1::num, _R1::den>, 4481debfc3dSmrg ratio<-_R2::num, _R2::den> >::type __t; 4491debfc3dSmrg public: 4501debfc3dSmrg typedef ratio<-__t::num, __t::den> type; 4511debfc3dSmrg }; 4521debfc3dSmrg 4531debfc3dSmrg // True addition of nonnegative numbers. 4541debfc3dSmrg template<typename _R1, typename _R2, bool __b> 4551debfc3dSmrg struct __ratio_add_impl<_R1, _R2, true, true, __b> 4561debfc3dSmrg { 4571debfc3dSmrg private: 4581debfc3dSmrg static constexpr uintmax_t __g = __static_gcd<_R1::den, _R2::den>::value; 4591debfc3dSmrg static constexpr uintmax_t __d2 = _R2::den / __g; 4601debfc3dSmrg typedef __big_mul<_R1::den, __d2> __d; 4611debfc3dSmrg typedef __big_mul<_R1::num, _R2::den / __g> __x; 4621debfc3dSmrg typedef __big_mul<_R2::num, _R1::den / __g> __y; 4631debfc3dSmrg typedef __big_add<__x::__hi, __x::__lo, __y::__hi, __y::__lo> __n; 4641debfc3dSmrg static_assert(__n::__hi >= __x::__hi, "Internal library error"); 4651debfc3dSmrg typedef __big_div<__n::__hi, __n::__lo, __g> __ng; 4661debfc3dSmrg static constexpr uintmax_t __g2 = __static_gcd<__ng::__rem, __g>::value; 4671debfc3dSmrg typedef __big_div<__n::__hi, __n::__lo, __g2> __n_final; 4681debfc3dSmrg static_assert(__n_final::__rem == 0, "Internal library error"); 4691debfc3dSmrg static_assert(__n_final::__quot_hi == 0 && 4701debfc3dSmrg __n_final::__quot_lo <= __INTMAX_MAX__, "overflow in addition"); 4711debfc3dSmrg typedef __big_mul<_R1::den / __g2, __d2> __d_final; 4721debfc3dSmrg static_assert(__d_final::__hi == 0 && 4731debfc3dSmrg __d_final::__lo <= __INTMAX_MAX__, "overflow in addition"); 4741debfc3dSmrg public: 4751debfc3dSmrg typedef ratio<__n_final::__quot_lo, __d_final::__lo> type; 4761debfc3dSmrg }; 4771debfc3dSmrg 4781debfc3dSmrg template<typename _R1, typename _R2> 4791debfc3dSmrg struct __ratio_add_impl<_R1, _R2, false, true, true> 4801debfc3dSmrg : __ratio_add_impl<_R2, _R1> 4811debfc3dSmrg { }; 4821debfc3dSmrg 4831debfc3dSmrg // True subtraction of nonnegative numbers yielding a nonnegative result. 4841debfc3dSmrg template<typename _R1, typename _R2> 4851debfc3dSmrg struct __ratio_add_impl<_R1, _R2, true, false, false> 4861debfc3dSmrg { 4871debfc3dSmrg private: 4881debfc3dSmrg static constexpr uintmax_t __g = __static_gcd<_R1::den, _R2::den>::value; 4891debfc3dSmrg static constexpr uintmax_t __d2 = _R2::den / __g; 4901debfc3dSmrg typedef __big_mul<_R1::den, __d2> __d; 4911debfc3dSmrg typedef __big_mul<_R1::num, _R2::den / __g> __x; 4921debfc3dSmrg typedef __big_mul<-_R2::num, _R1::den / __g> __y; 4931debfc3dSmrg typedef __big_sub<__x::__hi, __x::__lo, __y::__hi, __y::__lo> __n; 4941debfc3dSmrg typedef __big_div<__n::__hi, __n::__lo, __g> __ng; 4951debfc3dSmrg static constexpr uintmax_t __g2 = __static_gcd<__ng::__rem, __g>::value; 4961debfc3dSmrg typedef __big_div<__n::__hi, __n::__lo, __g2> __n_final; 4971debfc3dSmrg static_assert(__n_final::__rem == 0, "Internal library error"); 4981debfc3dSmrg static_assert(__n_final::__quot_hi == 0 && 4991debfc3dSmrg __n_final::__quot_lo <= __INTMAX_MAX__, "overflow in addition"); 5001debfc3dSmrg typedef __big_mul<_R1::den / __g2, __d2> __d_final; 5011debfc3dSmrg static_assert(__d_final::__hi == 0 && 5021debfc3dSmrg __d_final::__lo <= __INTMAX_MAX__, "overflow in addition"); 5031debfc3dSmrg public: 5041debfc3dSmrg typedef ratio<__n_final::__quot_lo, __d_final::__lo> type; 5051debfc3dSmrg }; 5061debfc3dSmrg 5071debfc3dSmrg template<typename _R1, typename _R2> 5081debfc3dSmrg struct __ratio_add 5091debfc3dSmrg { 5101debfc3dSmrg typedef typename __ratio_add_impl<_R1, _R2>::type type; 5111debfc3dSmrg static constexpr intmax_t num = type::num; 5121debfc3dSmrg static constexpr intmax_t den = type::den; 5131debfc3dSmrg }; 5141debfc3dSmrg 5151debfc3dSmrg template<typename _R1, typename _R2> 5161debfc3dSmrg constexpr intmax_t __ratio_add<_R1, _R2>::num; 5171debfc3dSmrg 5181debfc3dSmrg template<typename _R1, typename _R2> 5191debfc3dSmrg constexpr intmax_t __ratio_add<_R1, _R2>::den; 5201debfc3dSmrg 521*8feb0f0bSmrg /// @endcond 522*8feb0f0bSmrg 5231debfc3dSmrg /// ratio_add 5241debfc3dSmrg template<typename _R1, typename _R2> 5251debfc3dSmrg using ratio_add = typename __ratio_add<_R1, _R2>::type; 5261debfc3dSmrg 527*8feb0f0bSmrg /// @cond undocumented 528*8feb0f0bSmrg 5291debfc3dSmrg template<typename _R1, typename _R2> 5301debfc3dSmrg struct __ratio_subtract 5311debfc3dSmrg { 5321debfc3dSmrg typedef typename __ratio_add< 5331debfc3dSmrg _R1, 5341debfc3dSmrg ratio<-_R2::num, _R2::den>>::type type; 5351debfc3dSmrg 5361debfc3dSmrg static constexpr intmax_t num = type::num; 5371debfc3dSmrg static constexpr intmax_t den = type::den; 5381debfc3dSmrg }; 5391debfc3dSmrg 5401debfc3dSmrg template<typename _R1, typename _R2> 5411debfc3dSmrg constexpr intmax_t __ratio_subtract<_R1, _R2>::num; 5421debfc3dSmrg 5431debfc3dSmrg template<typename _R1, typename _R2> 5441debfc3dSmrg constexpr intmax_t __ratio_subtract<_R1, _R2>::den; 5451debfc3dSmrg 546*8feb0f0bSmrg /// @endcond 547*8feb0f0bSmrg 5481debfc3dSmrg /// ratio_subtract 5491debfc3dSmrg template<typename _R1, typename _R2> 5501debfc3dSmrg using ratio_subtract = typename __ratio_subtract<_R1, _R2>::type; 5511debfc3dSmrg 5521debfc3dSmrg 5531debfc3dSmrg typedef ratio<1, 1000000000000000000> atto; 5541debfc3dSmrg typedef ratio<1, 1000000000000000> femto; 5551debfc3dSmrg typedef ratio<1, 1000000000000> pico; 5561debfc3dSmrg typedef ratio<1, 1000000000> nano; 5571debfc3dSmrg typedef ratio<1, 1000000> micro; 5581debfc3dSmrg typedef ratio<1, 1000> milli; 5591debfc3dSmrg typedef ratio<1, 100> centi; 5601debfc3dSmrg typedef ratio<1, 10> deci; 5611debfc3dSmrg typedef ratio< 10, 1> deca; 5621debfc3dSmrg typedef ratio< 100, 1> hecto; 5631debfc3dSmrg typedef ratio< 1000, 1> kilo; 5641debfc3dSmrg typedef ratio< 1000000, 1> mega; 5651debfc3dSmrg typedef ratio< 1000000000, 1> giga; 5661debfc3dSmrg typedef ratio< 1000000000000, 1> tera; 5671debfc3dSmrg typedef ratio< 1000000000000000, 1> peta; 5681debfc3dSmrg typedef ratio< 1000000000000000000, 1> exa; 5691debfc3dSmrg 570*8feb0f0bSmrg /// @} group ratio 5711debfc3dSmrg_GLIBCXX_END_NAMESPACE_VERSION 5721debfc3dSmrg} // namespace 5731debfc3dSmrg 5741debfc3dSmrg#endif // C++11 5751debfc3dSmrg 5761debfc3dSmrg#endif //_GLIBCXX_RATIO 577