Exact rational numbers

OK, I tryed to filled the task with your function, The first result r1 is correct, but the second and third results r2 and r3 are almost right, but there are small errors. I don’t know how to fix it.
Here is the code:

let to_cents (q : Q.t) : Z.t =
  let cents = Q.(q * (of_int 100)) in
  let whole_cents = Q.to_bigint cents in
  if Q.(geq (cents - of_bigint whole_cents) (1//2))
  then Z.(whole_cents + one)
  else whole_cents

let to_dollars_and_cents (q : Q.t) : Z.t * Z.t =
  let cents = to_cents q in
  Z.(cents / (of_int 100), cents mod (of_int 100))

let p1 = Q.mul (Q.of_string "4000000000000000") (Q.of_float 5.50) ;;
let p2 = Q.mul (Q.of_int 2) (Q.of_float 2.86) ;;

let r1 = Q.add p1 p2 ;;
let r2 = Q.mul r1 (Q.of_float (7.65 /. 100.)) ;;
let r3 = Q.add r1 r2 ;;

let my_to_string v =
  let d, c = to_dollars_and_cents v in
  Printf.sprintf "%s.%s" (Z.to_string d) (Z.to_string c) ;;

# my_to_string r1 ;;
- : string = "22000000000000005.72"
(* expected: "22000000000000005.72" OK *)

# my_to_string r2 ;;
- : string = "1683000000000000.41"
(* expected: "1683000000000000.44" *)

# my_to_string r3 ;;
- : string = "23683000000000006.13"
(* expected: "23683000000000006.16" *)