# money.convert Converts a `Money` into another currency at a rate the caller supplies. It does not look rates up: which rate applies (the day's ECB reference rate, the rate on the invoice date, a contract rate) is the caller's decision, and this takes it as an argument, so the same inputs always give the same answer. **The rate is an exact fraction**, a `math.rational` `Rational`, in major units, the way rates are quoted: GBP to EUR at 1.1734 is `{ base: "GBP", quote: "EUR", rate: { numerator: 11734, denominator: 10000 } }`. A decimal quote becomes a fraction by moving the point (`math.basis-points` style), and the inverse rate is the same fraction upside down, exactly, so converting back uses precisely the reciprocal rather than 1/1.1734 cut off at some number of places. A fraction was chosen over "rate in micro-units" because micro-units cannot hold a reciprocal and cap every rate at six decimal places. **Minor units are handled for you.** The rate is in major units, so the amount is scaled by each currency's ISO 4217 decimal places (from `money.currency-digits`): 10.00 GBP at 190.12 is 1,901 JPY, not 190,120. **One rounding**, at the end, to the quote currency's minor unit, with the `math.round-div` mode you pass. Everything before it is exact. 1.00 EUR at 1.005 is exactly 1.005 USD; `half-up` gives 1.01, where a float computes 100 × 1.005 as 100.49999999999999 and rounds it to 1.00. **The rate carries its currencies.** Applying a GBP-to-EUR rate to a USD amount is an error, not a conversion. To go the other way, swap `base` and `quote` and turn the fraction over; this never inverts a rate on its own. Edges: the rate must be positive; zero converts to zero; negative amounts (refunds) convert symmetrically under `half-up` and `half-even`. Intermediate values follow `math.rational`'s limits (numerator and denominator within 2^53 - 1 after reducing); an amount and rate so large that the exact product does not fit is refused with "rational overflow" rather than rounded.