program base60 ! first step: Base60 encode. ! reference: http://faruk.akgul.org/blog/tantek-celiks-newbase60-in-python-and-java/ ! 5000 should be 1PL implicit none integer,dimension(14) :: tests = (/ 5000, 0, 100000, 1, 2, 60, & 61, 59, 5, 100000000, 256, 65536, 215000, 16777216 /) integer :: i ! index for the for loop integer :: n ! the current test to run ! I have to declare the return type of the function in the main program, too. character(len=1000) :: numtosxg integer :: sxgtonum ! test the functions. do i=1,size(tests) n = tests(i) write(*,*) n, trim(numtosxg(n)), sxgtonum(trim(numtosxg(n))) end do end program base60 character(len=1000) function numtosxg( number ) implicit none !!! preparation ! input: ensure that this is purely used as input. ! intent is only useful for function arguments. integer, intent(in) :: number ! constants: marked as parameter: not function parameters, but ! algorithm parameters! character(len=61), parameter :: base60chars = "0123456789"& //"ABCDEFGHJKLMNPQRSTUVWXYZ_abcdefghijkmnopqrstuvwxyz" ! work variables integer :: n integer :: remainder ! result character(len=1000) :: res ! do not initialize variables when ! declaring them: That only initializes ! at compile time not at every function ! call and thus invites nasty errors ! which are hard to find. actual ! algorithm if (number == 0) then numtosxg = "0" return end if ! calculate the base60 string res = "" ! I have to explicitely set res to "", otherwise it ! accumulates the prior results! n = number ! the input argument: that should be safe to use. ! catch number = 0 do while(n > 0) ! in the first loop, remainder is initialized here. remainder = mod(n, 60) n = n/60 ! note that fortran indizes start at 1, not at 0. res = base60chars(remainder+1:remainder+1)//trim(res) ! write(*,*) number, remainder, n end do numtosxg = res end function numtosxg integer function sxgtonum( base60string ) implicit none ! Turn a base60 string into the equivalent integer (number) character(len=*), intent(in) :: base60string character(len=61), parameter :: base60chars = "0123456789"& //"ABCDEFGHJKLMNPQRSTUVWXYZ_abcdefghijkmnopqrstuvwxyz" integer :: i ! running index integer :: idx ! found index of char in string integer :: number ! integer,dimension(len_trim(base60string)) :: numbers ! for later openmp number = 0 do i=1, len_trim(base60string) number = number * 60 idx = index(base60chars, base60string(i:i), .FALSE.) ! not backwards number = number + (idx-1) end do sxgtonum = number end function sxgtonum