Silverfrost Forums

Welcome to our forums

asin of angle

18 Dec 2024 10:37 #31748

Note: in Silverfrost Fortran, 64 bit with Win11, when calling the function ASIN(A) and A=1.D0, get 'invalid floating point operation'. The limits for A, per the mathematical functions for Silverfrost Fortran, are stated as -1.D0 ⇐ A ⇐ 1.D0. Should this not be an 'invalid floating point operation? As a minimum, I would think that Silverfrost Fortran should be checking this limit to make sure that it is not stated as invalid. Sid Kraft

19 Dec 2024 12:03 #31749

My test on Win 10

      use iso_fortran_env
      real*8 :: a
      write (*,*) compiler_version ()
      write (*,*) compiler_options ()
      a = asin (1.0d0)
      write (*,*) a
      end

  FTN95 v9.04.0
 64;ECHO_OPTIONS;ERROR_NUMBERS;IMPLICIT_NONE;INTL;LINK;LOGL;NO_BANNER;UNLIMITED_ERRORS;VS7;
           1.57079632679 

I would check SET PATH

19 Dec 2024 7:59 #31750

Sid

I have tested John's code under Windows 11 (both 23 H2 and 24 H2). I have also tested with /checkmate etc. I have not been able to reproduce your error report.

Please supply a sample program that demonstrates the fault together with details of the FTN95 version that you are using.

19 Dec 2024 10:25 #31751

Consider this simple example:

program p
implicit none
real*8 :: y
y = 1.d0
print*, y
print*, asin(y)
y = 1.d0 + epsilon(1.d0)   ! Y is now ever so slighty greater than 1 
                           ! (as may happen in a real calculation where
                           ! the expect value is exactly 1.d0)
print*, y                  ! Not obvious when you print the value.
print*, asin(y)          ! Invalid float error!
end program p

One way around this problem is to do the following:

program p
implicit none
real*8 :: y
y = 1.d0
print*, y
print*, asin(y)
y = 1.d0 + epsilon(1.d0)    ! Y is now ever so slighty greater than 1 
                            ! (as may happen in a real calculation where
                            ! the expect value is exactly 1.d0)
print*, y                   ! Not obvious when you print the value.
print*, limited_arg_asin(y) ! Call a function which truncates y to valid
                            ! valid range and then returns the arcsine

contains

function limited_arg_asin(x) result (x1)
real*8, intent(in) :: x
real*8 :: x1
  if(x .gt. 1.d0) then
    x1 = 1.d0
  else if (x .lt. -1.d0) then
    x1 = -1.d0
  else
    x1 = x
  end if
  x1 = asin(x1) 
end function limited_arg_asin

end program p
19 Dec 2024 11:11 #31752

Alternative function without block ifs:

program p
implicit none
real*8 :: y
y = 1.d0
print*, y
print*, asin(y)
y = 1.d0 + epsilon(1.d0)
print*, y 
print*, Dasin_t(y)

contains

  function Dasin_t (y) result (asiny)
  real*8 :: asiny
  real*8, intent(in) :: y
  real*8 :: x
    x = max(y,-1.d0)
    x = min(x, 1.d0)
    asiny = asin(x)
  end function Dasin_t

end program p
19 Dec 2024 11:39 #31753

FTN95 has now been fixed for the next release so that an argument that is out of bounds will give a meaningful runtime failure message (as already occurs for Win32).

Please login to reply.