www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Different results for int and long alias

reply Andy Little <andy servocomm.freeserve.co.uk> writes:
In the following example when I use an int in the marked section the code works
as expected, however if I use a long the output is incorrect.

Coming from C++ I don't understand the casting system. Is this the cause or is
this a bug?

regards
Andy Little


// compile time greatest common divisor
template gcd( T, T N, T D){
   static if (D == 0){
      static const T value = N;
   }
   else {
      static const T value = gcd!(T,D, (N % D)).value;
   }
}
// compile time rational implementation for signed rational 
template rational_impl_signed ( T, T N, T D){

   static const bool   n_positive = (N >= 0);
   static const bool   d_positive = (D >= 0);
   static const T    pos_nume_in = n_positive ? N : -N;
   static const T    pos_denom_in = d_positive ? D : -D;
   static const T    nume_in 
      = (n_positive==d_positive)? pos_nume_in : -pos_nume_in;
   static const T    gcd_ = gcd!(T,pos_nume_in,pos_denom_in).value;
   static const T  numerator = nume_in / gcd_;
   static const T  denominator = pos_denom_in / gcd_;
}

// compile time rational
template rational( T, T N, T D){
   class type{
      alias T value_type;
      static const T numerator = rational_impl_signed!(T,N,D).numerator;
      static const T denominator = rational_impl_signed!(T,N,D).denominator;
   }
}
// compile time add of two rationals
template add_rational_impl(TL, TR){
   alias typeof( TL.value_type + TR.value_type) value_type;
   static const value_type numerator 
   = TL.numerator * TR.denominator + TR.numerator * TL.denominator ;
   static const value_type denominator 
   = TL.denominator * TR.denominator;
   typedef rational!(value_type,numerator,denominator).type type;
}

template add_rational(TL, TR)
{
   alias add_rational_impl!(TL,TR).type type;
}

int main(char[][] args)
{
//#################################################################
/*
 if int_type is defined as long then gives invalid output of 2 / 0
 If int_type is defined as int then gives correct output of 2 / 1
*/
   static if (1){
      alias long int_type;
   }
   else {
      alias int int_type;
   }
//##################################################################

   alias add_rational!(rational!(int_type,3,2).type,rational!(int_
ype,1,2).type).type x;

   printf ("%d / %d\n",x.numerator,x.denominator);

   return 0;
}
Mar 03 2007
parent reply Lionello Lunesu <lio lunesu.remove.com> writes:
Andy Little wrote:
 In the following example when I use an int in the marked section the code
works as expected, however if I use a long the output is incorrect.
 
 Coming from C++ I don't understand the casting system. Is this the cause or is
this a bug?

"long" in D is a 64-bit integer, therefore you should use "%ld" to print it using printf. Generally, try to cut back on the use of printf since it doesn't check the arguments, causing many similar problems. You should use writefln/writef (from std.stdio) instead. In writefln you can simply use "%s" for all types. L.
Mar 03 2007
parent reply Andy Little <andy servocomm.freeserve.co.uk> writes:
Lionello Lunesu Wrote:

 Andy Little wrote:
 In the following example when I use an int in the marked section the code
works as expected, however if I use a long the output is incorrect.
 
 Coming from C++ I don't understand the casting system. Is this the cause or is
this a bug?

"long" in D is a 64-bit integer, therefore you should use "%ld" to print it using printf. Generally, try to cut back on the use of printf since it doesn't check the arguments, causing many similar problems. You should use writefln/writef (from std.stdio) instead. In writefln you can simply use "%s" for all types.

Great it works.. thanks. Presumably this means you need to provide an overload of some "toString(T)" function for your own types? regards Andy Little
Mar 04 2007
parent Frits van Bommel <fvbommel REMwOVExCAPSs.nl> writes:
Andy Little wrote:
 Lionello Lunesu Wrote:
 
 Andy Little wrote:
 In the following example when I use an int in the marked section the code
works as expected, however if I use a long the output is incorrect.

 Coming from C++ I don't understand the casting system. Is this the cause or is
this a bug?

it using printf. Generally, try to cut back on the use of printf since it doesn't check the arguments, causing many similar problems. You should use writefln/writef (from std.stdio) instead. In writefln you can simply use "%s" for all types.

Great it works.. thanks. Presumably this means you need to provide an overload of some "toString(T)" function for your own types?

Yes, except it's not a free function. Classes and structs (and IIRC unions too) that you want to pass to the writef[ln]() and format() functions should implement a "char[] toString()" member function. (For classes this comes pre-implemented in Object to return the class name, but that's not very informative. It's provided mainly for implementation reasons, so it can be overridden)
Mar 04 2007