FixedDecimalException on alignment or coefficient overflow.FixedDecimal.opBinary
FixedDecimal opBinary(string op)(const FixedDecimal rhs) if (op == "+" || op == "-") const @safe pure`+`/`-` between values of the same instantiation: the result is that same instantiation (fixed-scale operands share their scale, so alignment is identity).
Throws
auto opBinary(string op, int S2)(const FixedDecimal!(I, S2) rhs) if ((op == "+" || op == "-") && S2 != Scale) const @safe pure`+`/`-` between fixed-scale forms of different compile-time scale (same storage): operands convert to the runtime form; the result is the runtime form at the aligned scale.
auto opBinary(string op, J2, int S2)(const FixedDecimal!(J2, S2) rhs) if ((op == "+" || op == "-") && !is(J2 == I)) const @safe pure`+`/`-` across storage classes: both operands widen to the Int128 runtime form (exact); the result is the wide runtime form.
auto opBinary(string op)(const long rhs) if (op == "+" || op == "-") const @safe pure`+`/`-` with a signed integer operand (exact conversion or throw).
`*` between values of the same instantiation. Fixed-scale operands yield the fixed-scale type of the summed scale (S + S, compile-time checked); runtime-scale operands yield the runtime form.
auto opBinary(string op, int S2)(const FixedDecimal!(I, S2) rhs) if (op == "*" && S2 != Scale) const @safe pure`*` between different scale forms of the same storage: fixed × fixed yields FixedDecimal!(I, S1 + S2) (compile-time checked); any runtime-scale operand yields the runtime form.
auto opBinary(string op, J2, int S2)(const FixedDecimal!(J2, S2) rhs) if (op == "*" && !is(J2 == I)) const @safe pure`*` across storage classes: both operands widen to the Int128 runtime form; the result is the wide runtime form.
auto opBinary(string op)(const long rhs) if (op == "*") const @safe pure`*` with a signed integer operand (exact conversion or throw).
Division: result scale is max(s1, s2) rounded half-even (convenience form, D4). Precision-critical callers use divideToScale. The result is the runtime-scale form.
Throws
FixedDecimalException on zero divisor or coefficient overflow.auto opBinary(string op, int S2)(const FixedDecimal!(I, S2) rhs) if (op == "/" && S2 != Scale) const @safe pureDitto, different scale forms of the same storage.
auto opBinary(string op, J2, int S2)(const FixedDecimal!(J2, S2) rhs) if (op == "/" && !is(J2 == I)) const @safe pureDitto, across storage classes (widen both; wide runtime result).
auto opBinary(string op)(const long rhs) if (op == "/") const @safe pure`/` by a signed integer (exact conversion or throw).