digitalmars.D.learn - Different results for int and long alias
- Andy Little <andy servocomm.freeserve.co.uk> Mar 03 2007
- Lionello Lunesu <lio lunesu.remove.com> Mar 03 2007
- Andy Little <andy servocomm.freeserve.co.uk> Mar 04 2007
- Frits van Bommel <fvbommel REMwOVExCAPSs.nl> Mar 04 2007
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
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
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
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








Frits van Bommel <fvbommel REMwOVExCAPSs.nl>