use strict; use warnings; use Math::MPFR qw(:mpfr); print FMOD(900719925474099.7, 2147483647.83), "\n"; print MPFR_FMOD(900719925474099.7, 2147483647.83), "\n"; sub FMOD { return $_[0] - int($_[0] / $_[1]) * $_[1]; } sub MPFR_FMOD { # Do exactly what FMOD does - but on Math::MPFR objects, performing # the calculation at 200-bit precision. my $arg0 = Math::MPFR->new($_[0]); # 53 bit precision representation of $_[0] my $arg1 = Math::MPFR->new($_[1]); # 53 bit precision representation of $_[1] # Do the calculation at 200 bit precision for improved accuracy. Rmpfr_set_default_prec(200); my $ret = int($arg0 / $arg1); $ret *= $arg1; $ret = $arg0 - $ret; # Convert the 200-bit precision $ret to # a perl scalar (double), and return it my $nv = Rmpfr_get_d($ret, MPFR_RNDN); # Restore default precision back to the # original value of 53 before returning Rmpfr_set_default_prec(53); return $nv; } __END__ Outputs: 859064762.875 859064762.882