Topic: Assignation between equivalent ratios
Author: viboes <vicente.botet@wanadoo.fr>
Date: Wed, 16 Dec 2009 10:52:46 CST Raw View
On Dec 7, 11:15 am, Anthony Williams <anthony....@gmail.com> wrote:
> viboes <vicente.bo...@wanadoo.fr> writes:
> > I was wondering if we need to be able to make assignations between
> > equivalent ratios. e.g.
>
> > ratio<1,3> r1;
>
> > ratio<3,9> r2;
>
> > r1 = r2; // (1)
>
> > Even if they are equivalents (synonym ) as its num and den are the
> > same, there is no defined assignation in N3000. So (1) should not
> > compile with the current recommendation.
>
> True, but that doesn't matter. std::ratio does not hold any values, so
> runtime assignments and so forth don't make any sense. Either the values
> are equivalent, so assignment is unnecessary, or they are not, so
> assignment can't work.
See Howard reply.
> > Other example
>
> > ratio<1,3> r1;
>
> > ratio<2,3> r2;
>
> > r1 = r2-r1; // the type of this expression could be ratio<3,9> so the
> > compilation fails.
>
> Runtime subtraction using operator- is not defined for std::ratio. It is
> for compile-time arithmetic only. Ratio subtraction is defined with
> std::ratio_sub<R1,R2>::type. The result is defined to be over the lowest
> common denominator, so ratio_sub<ratio<2,3>,ratio<1,3>>::type is
> ratio<1,3>
You are right. I misused the operator-. I don't see where N3000 says
that "the result of std::ratio_sub<R1,R2>::type is defined to be over
the lowest common denominator". Could you point me where? It says
"template <class R1, class R2> struct ratio_subtract {
typedef see below type;
};
3 The nested typedef type shall be a synonym for ratio<T1, T2> where
T1 has the value R1::num *
R2::den - R2::num * R1::den and T2 has the value R1::den * R2::den.
"
> > Otherwise the recommendation should clarify the meaning of synonym on
> > the ratio arithmetic operators
>
> > [ratio.arithmetic] 3
>
> > "The nested typedef type shall be a synonym for ratio<T1, T2> where T1
> > has the value R1::num * R2::den - R2::num * R1::den and T2 has the
> > value R1::den * R2::den."
>
> > Maybe we should talk of normalized ratio and not of synonym. BTW,
> > where is synonym defined?
>
> Synonym takes on its usual meaning: a word that means the same as
> another word. Thus using ratio_sub<ratio<2,3>,ratio<1,3>>::type "means
> the same" as using ratio<1,3> i.e. it is the same type.
This is common sense, but the text in N3000 don't force this. I
understand that ratio<1,3> could be a synonym for ratio<3,9>, but, why
ratio<3,9> is not a synonym of itself? I proposed something like
The nested typedef type shall be a synonym for ratio<T1,
T2>***:type*** where T1
has the value R1::num * R2::den - R2::num * R1::den and T2 has the
value R1::den * R2::den.
and the nested typedef type represent the normalized ratio and defined
as follows
template <intmax_t T1, intmax_t T2>
ratio {
...
typedef ratio<num,den> type; // normalized type.
}
> > In addition I think that we need also to add that the declaration of
> > no normalized ratios, as ratio<3,9>, should fail at compile time as if
> > we allows them we can not assign any arithmetic expression if
> > arithmetic operator can normalize normalize.
>
> There is no runtime assignment or operations, and all compile-time
> arithmetic is defined to take care of denormalized ratios, so this is
> not a problem.
You are right there is no run-time operator on the ratio class, but at
least there is the default assignement. Forget this point, I have
extrapolated from another example which had runtime operators.
The example I had in mind was a class quantity
template <class R1, class R2> // R1 R2 are ratio classes
class quantity
{
double q_;
public:
typedef R1 time_dim;
typedef R2 distance_dim;
quantity() : q_(1) {}
double get() const {return q_;}
void set(double q) {q_ = q;}
};
// other specializations adding specific constructors
typedef quantity<boost::ratio<1>, boost::ratio<0> > Time; //
second
typedef quantity<boost::ratio<0>, boost::ratio<1> > Distance; //
meter
typedef quantity<boost::ratio<-1>, boost::ratio<1> > Speed; //
meter/second
template <class R1, class R2, class R3, class R4>
quantity<typename boost::ratio_subtract<R1, R3>::type, typename
boost::ratio_subtract<R2, R4>::type>
operator/(const quantity<R1, R2>& x, const quantity<R3, R4>& y);
Distance d( mile(110) );
Time t( boost::chrono::hours(2) );
Speed s= d / t;
If boost::ratio_subtract<R1, R3>::type is not normalized this do not
compiles.
Now suppose the boost::ratio_subtract<R1, R3>::type is normalized.
Do we want the following compile?
quantity<boost::ratio<-2>, boost::ratio<2> > s= d / t;
If yes we need to add assignment operator able to assign equivalent
types.
If not we should forbid the declaration of quantity<boost::ratio<-2>,
boost::ratio<2> > at compile time as nothing can be done with.
> Anthony
> --
Vicente
--
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]
Author: Howard Hinnant <howard.hinnant@gmail.com>
Date: Tue, 8 Dec 2009 01:32:50 CST Raw View
On Dec 7, 5:15 am, Anthony Williams <anthony....@gmail.com> wrote:
> viboes <vicente.bo...@wanadoo.fr> writes:
> > I was wondering if we need to be able to make assignations between
> > equivalent ratios. e.g.
>
> > ratio<1,3> r1;
>
> > ratio<3,9> r2;
>
> > r1 = r2; // (1)
>
> > Even if they are equivalents (synonym ) as its num and den are the
> > same, there is no defined assignation in N3000. So (1) should not
> > compile with the current recommendation.
>
> True, but that doesn't matter. std::ratio does not hold any values, so
> runtime assignments and so forth don't make any sense. Either the values
> are equivalent, so assignment is unnecessary, or they are not, so
> assignment can't work.
Agreed. However a converting copy constructor with this behavior
might be very useful for tag dispatching:
void foo(ratio<1, 4>); // handle 1/4 cases
void foo(ratio<1, 2>); // handle 1/2 cases
void foo(ratio<3, 4>); // handle 3/4 cases
It would be unfortunate if foo(ratio<75, 100>()) did not compile.
Especially if the 75 and 100 were the result of an encapsulated
compile-time computation instead of literals. And if it is useful to
have this converting copy constructor (and I believe it is), then I
think the assignment should be consistent if only for consistency's
sake.
-Howard
--
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]