1 auto r = rational(10, 2); // If you called rational(n, d), value is reduced. 2 assert(r.num == 5); // 10 / 2 => 5 / 1 3 assert(r.den == 1); 4 5 assert(r == rational(5)); // rational(5) == rational(5, 1) 6 7 assert(r == 5.over(1)); // UFCS : n.over(d) == n.rational(d) == rational(n, d) 8 9 r *= -1.over(5); 10 assert(r.num == -1); // If rational value is negative, numerator is always negative. 11 assert(r.den == 1); // But denominator is always positive. 12 assert(r == rational(1, 1)); // (5 / 1) * (1 / 5) == (1 / 1) 13 assert(r == 1); // Can check equality to T by "==" operator. 14 assert(r > 2); // Also comparison operator. 15 16 r1 = 2.over(5) + 3; // You can use Rational!T like T. 17 18 import std.bigint; 19 Rational!BigInt rb = 10.over(33);// You can use BigInt as T. 20 rb ^^= -10; 21 assert(rb == Rational!BigInt(BigInt(33)^^10, BigInt(10)^^10));
If T can be operated in pure nothrow @safe function, Rational!T can be too.
1 void foo() pure nothrow @safe 2 { 3 auto r = rational(1, 3); //int is pure nothrow @safe type 4 r += 3.over(4); 5 ... 6 }
You can use "%(...%)" format when formatted write. Where inner format "..." can be T's format, first one is numerator's format, second is denominator's format.
1 import std.format; 2 3 void main(){ 4 auto writer = appender!string; 5 6 formattedWrite(writer, "%(%04d / %04d%)", rational(10, 33)); 7 assert(writer.data == "0010 / 0033"); 8 9 writer = appender!string; 10 formattedWrite(writer, "%(den : %2$s , num : %1$s%)", rational(10, 33)); 11 assert(writer.data == "den : 33 , num : 10"); 12 13 writer = appender!string; 14 formattedWrite(writer, "%04d", rational(10, 30)); 15 assert(writer.data == "0010/0030"); 16 }
This is the type that you can calculate fraction. Rational!T has two integral T values.