| 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>::numandratio<U,V>::denare the same as the corresponding members ofratio<T1,T2>would be in the absence of arithmetic overflow whereT1has the valueR1::num * R2::den + R2::num * R1::denandT2has the valueR1::den * R2::den. If the required values ofratio<U,V>::numandratio<U,V>::dencannot be represented inintmax_tthen the program is illformed. Correct calculation of the result if either ofT1orT2cannot be represented inintmax_tis 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>::numandratio<U,V>::denare the same as the corresponding members ofratio<T1,T2>would be in the absence of arithmetic overflow whereT1has the valueR1::num * R2::den - R2::num * R1::denandT2has the valueR1::den * R2::den. If the required values ofratio<U,V>::numandratio<U,V>::dencannot be represented inintmax_tthen the program is illformed. Correct calculation of the result if either ofT1orT2cannot be represented inintmax_tis 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>::numandratio<U,V>::denare the same as the corresponding members ofratio<T1,T2>would be in the absence of arithmetic overflow whereT1has the valueR1::num * R2::numandT2has the valueR1::den * R2::den. If the required values ofratio<U,V>::numandratio<U,V>::dencannot be represented inintmax_tthen the program is illformed. Correct calculation of the result if either ofT1orT2cannot be represented inintmax_tis 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>::numandratio<U,V>::denare the same as the corresponding members ofratio<T1,T2>would be in the absence of arithmetic overflow whereT1has the valueR1::num * R2::denandT2has the valueR1::den * R2::num. If the required values ofratio<U,V>::numandratio<U,V>::dencannot be represented inintmax_tthen the program is illformed. Correct calculation of the result if either ofT1orT2cannot be represented inintmax_tis 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]