1 module fixedpoint.arithmetic; 2 import std.conv : to; 3 import fixedpoint.fixed : Fixed; 4 5 /// Before the operation the arguments are casted to the specified type 6 T addTo(T, int a, V, int b, U)(Fixed!(a, V) lhs, Fixed!(b, U) rhs) 7 { 8 static if (a >= b) 9 { 10 return (lhs.value.to!T + rhs.value.to!T * 10 ^^ (a - b)) / lhs.factor; 11 } 12 else 13 { 14 return (lhs.value.to!T * 10 ^^ (b - a) + rhs.value.to!T) / rhs.factor; 15 } 16 } 17 18 T subTo(T, int a, V, int b, U)(Fixed!(a, V) lhs, Fixed!(b, U) rhs) 19 { 20 static if (a >= b) 21 { 22 return (lhs.value.to!T - rhs.value.to!T * 10 ^^ (a - b)) / lhs.factor; 23 } 24 else 25 { 26 return (lhs.value.to!T * 10 ^^ (b - a) - rhs.value.to!T) / rhs.factor; 27 } 28 } 29 30 T mulTo(T, int a, V, int b, U)(Fixed!(a, V) lhs, Fixed!(b, U) rhs) 31 { 32 return (lhs.value.to!T * rhs.value.to!T) / (lhs.factor * rhs.factor); 33 } 34 35 T divTo(T, int a, V, int b, U)(Fixed!(a, V) lhs, Fixed!(b, U) rhs) 36 { 37 static if (a >= b) 38 { 39 return (lhs.value.to!T / rhs.value.to!T) / 10 ^^ (a - b); 40 } 41 else 42 { 43 return (lhs.value.to!T / rhs.value.to!T) * 10 ^^ (b - a); 44 } 45 } 46 47 unittest 48 { 49 import std.stdio : writeln; 50 import fixedpoint.fixed : Fixed; 51 import std.math : isClose; 52 53 auto op1 = Fixed!2("1.11"); 54 auto op2 = Fixed!2("1.11"); 55 auto op3 = Fixed!3("1.111"); 56 assert(isClose(addTo!double(op1, op2), 2.22)); 57 assert(isClose(subTo!double(op1, op2), 0.0)); 58 assert(isClose(mulTo!double(op1, op2), 1.2321)); 59 assert(isClose(divTo!double(op1, op2), 1.0)); 60 assert(isClose(op1.addTo!double(op2), 2.22)); 61 assert(isClose(op1.subTo!double(op2), 0.0)); 62 assert(isClose(op1.mulTo!double(op2), 1.2321)); 63 assert(isClose(op1.divTo!double(op2), 1.0)); 64 assert(isClose(addTo!double(op1, op3), 2.221)); 65 assert(isClose(subTo!double(op1, op3), -0.001)); 66 assert(isClose(mulTo!double(op1, op3), 1.23321)); 67 assert(isClose(divTo!double(op1, op3), 0.99909990999)); 68 assert(isClose(addTo!double(op3, op1), 2.221)); 69 assert(isClose(subTo!double(op3, op1), 0.001)); 70 assert(isClose(mulTo!double(op3, op1), 1.23321)); 71 assert(isClose(divTo!double(op3, op1), 1.0009009009)); 72 }