J'ai essayé d'optimiser truncate avec mais les tests ne passe plus:
let rec truncate m a p = if Z.equal a Z.zero then zero else let last = Z.findlastset a in (* of the absolute value *) let first = Z.findfirstset a in let i = max first (last-(m-1)) in (Z.shift_right_trunc a i,p+i)let m32 = 24let m64 = 53let round_f32 (a,p) = truncate m32 a plet round_f64 (a,p) = truncate m64 a plet round ?(bits=80) (a,p) = truncate bits a p
À ma connaissance, il n'y a pas d'algorithme malin. La conversion d'un rationnel vers un flottant revient toujours tôt ou tard à faire une division entière entre un nombre de p + k bits par un nombre de k bits. Il y a quelques optimisations triviales qui prennent en compte les zéros présents à la fin des nombres afin d'éviter de diviser ou de décaler des nombres artificiellement grands. Il y a une optimisation beaucoup plus subtile qui consiste à détecter qu'il est possible de faire une division de p + k par k + 1, mais je ne crois pas qu'elle en vaille la peine au niveau performance.
Par contre, il y a évidemment toutes les optimisations de la division entière, mais ça c'est le boulot de GMP, ça ne nous concerne pas.