Document Number: | N3131=10-0121 |
Date: | 2010-08-20 |
Author: | Anthony
Williams Just Software Solutions Ltd |
Comment GB 89 on the FCD (see N3102) raised the issue of how compile-time rational arithmetic should be done when the result is representable, but a simple application of arithmetic rules would result in overflow.
e.g. ratio_multiply<ratio<INTMAX_MAX,2>,ratio<2,INTMAX_MAX>>
can be
reduced to ratio<1,1>
, but the direct result
of ratio<INTMAX_MAX*2,INTMAX_MAX*2>
would result
in overflow.
The consensus in Rapperswil was to allow but not require the implementation to handle such overflow if the final result was representable.
Change the wording in 20.6.2 [ratio.arithmetic] as follows:
Implementations may use other algorithms to compute these values. If overflow occurs in the calculation of the result, the program is ill-formed. [Note: Implementations are encouraged to use alternative algorithms that avoid overflow in the calculation if the final result is representable. Such provision is conditionally supported. -- End Note]
template <class R1, class R2> using ratio_add = see below;The type
ratio_add<R1, R2>
shall be a synonym forratio<T1,T2>
ratio<U, V>
such thatratio<U,V>::num
andratio<U,V>::den
are the same as the corresponding members ofratio<T1,T2>
would be in the absence of arithmetic overflow whereT1
has the valueR1::num * R2::den + R2::num * R1::den
andT2
has the valueR1::den * R2::den
. If the required values ofratio<U,V>::num
andratio<U,V>::den
cannot be represented inintmax_t
then the program is illformed. Correct calculation of the result if either ofT1
orT2
cannot be represented inintmax_t
is conditionally supported ([defns.cond.supp])template <class R1, class R2> using ratio_subtract = see below;The type
ratio_subtract<R1, R2>
shall be a synonym forratio<T1,T2>
ratio<U, V>
such thatratio<U,V>::num
andratio<U,V>::den
are the same as the corresponding members ofratio<T1,T2>
would be in the absence of arithmetic overflow whereT1
has the valueR1::num * R2::den - R2::num * R1::den
andT2
has the valueR1::den * R2::den
. If the required values ofratio<U,V>::num
andratio<U,V>::den
cannot be represented inintmax_t
then the program is illformed. Correct calculation of the result if either ofT1
orT2
cannot be represented inintmax_t
is conditionally supported ([defns.cond.supp])template <class R1, class R2> using ratio_multiply = see below;The type
ratio_multiply<R1, R2>
shall be a synonym forratio<T1,T2>
ratio<U, V>
such thatratio<U,V>::num
andratio<U,V>::den
are the same as the corresponding members ofratio<T1,T2>
would be in the absence of arithmetic overflow whereT1
has the valueR1::num * R2::num
andT2
has the valueR1::den * R2::den
. If the required values ofratio<U,V>::num
andratio<U,V>::den
cannot be represented inintmax_t
then the program is illformed. Correct calculation of the result if either ofT1
orT2
cannot be represented inintmax_t
is conditionally supported ([defns.cond.supp])template <class R1, class R2> using ratio_divide = see below;The type
ratio_divide<R1, R2>
shall be a synonym forratio<T1,T2>
ratio<U, V>
such thatratio<U,V>::num
andratio<U,V>::den
are the same as the corresponding members ofratio<T1,T2>
would be in the absence of arithmetic overflow whereT1
has the valueR1::num * R2::den
andT2
has the valueR1::den * R2::num
. If the required values ofratio<U,V>::num
andratio<U,V>::den
cannot be represented inintmax_t
then the program is illformed. Correct calculation of the result if either ofT1
orT2
cannot be represented inintmax_t
is conditionally supported ([defns.cond.supp])[Example --
static_assert(ratio_add<ratio<1,3>,ratio<1,6>>::num==1,"1/3+1/6==1/2"); static_assert(ratio_add<ratio<1,3>,ratio<1,6>>::den==2,"1/3+1/6==1/2"); static_assert(ratio_add<ratio<1,INTMAX_MAX>,ratio<1,INTMAX_MAX>>::num==2,"1/MAX+1/MAX==2/MAX"); // conditionally supported static_assert(ratio_add<ratio<1,INTMAX_MAX>,ratio<1,INTMAX_MAX>>::den==INTMAX_MAX,"1/MAX+1/MAX==2/MAX"); // conditionally supported static_assert(ratio_multiply<ratio<1,3>,ratio<3,2>>::num==1,"1/3*3/2==1/2"); static_assert(ratio_multiply<ratio<1,3>,ratio<3,2>>::den==2,"1/3*3/2==1/2"); static_assert(ratio_multiply<ratio<1,INTMAX_MAX>,ratio<INTMAX_MAX,2>>::num==1,"1/MAX * MAX/2==1/2"); // conditionally supported static_assert(ratio_multiply<ratio<1,INTMAX_MAX>,ratio<INTMAX_MAX,2>>::den==2,"1/MAX * MAX/2==1/2"); // conditionally supported--End Example]