Dear all,
I am translating some Matlab version of matrix exponential solver to Fortran, one of it is the expmv from Higham,
Those solvers contain some large integer operations.
For a minimal example, for some matrix, in the solver it will calculate things like
ceiling(3.06921040378475e+21)
But the result is just wrong since its overflow. I don’t think brute force adding a kind parameter such as int32,64,128 in the ceiling function can really solve the problem, because overflow can still happen.
However, Matlab’s ceil function does not have problem. Its output is just 3.06921040378475e+21.
I know its ceil function seems like a double precision version, it returns the nearest integer in the format of double precision, so no overflow.
I wonder, is there a way to let the ceiling function in Fortran behaves like Matlab?
I mean the ceiling function do not really return a strict integer, it just need a correct value in double precision.
Many thanks in advance!
PS.
I can think of a stupid way, roughly, just define a double precision version of ceiling function to perhaps mimic Matlab’s ceil function, in it, it will check the input variable x. If x is very big, then ceiling function output x. Otherwise ceiling function output ceiling(x), and then convert it to double precision. But should there be better solutions?
module ceil_mod
implicit none
contains
elemental real function ceil(x)
implicit none
!integer, parameter :: i4=selected_int_kind(9)
integer, parameter :: i8=selected_int_kind(15)
integer, parameter :: r8=selected_real_kind(15,9)
real(r8), intent(in) :: x
integer(i8), parameter :: ceil_limit = 2.0**62
if (abs(x)<ceil_limit) then
ceil = ceiling(x,kind=i8)
else
ceil = x
endif
return
end function ceil
end module