Manual Reference Pages  - abs (3fortran)

NAME

ABS(3) - [NUMERIC] Absolute value

SYNOPSIS

result = abs(a)

         elemental TYPE(kind=KIND) function abs(a)

TYPE(kind=KIND),intent(in) :: a

CHARACTERISTICS

o A may be any real, integer, or complex value.
o If A is complex the returned value will be a real with the same kind as A.

Otherwise the returned type and kind is the same as for A.

DESCRIPTION

ABS(3) computes the absolute value of numeric argument A.

In mathematics, the absolute value or modulus of a real number X, denoted |X|, is the magnitude of X without regard to its sign.

The absolute value of a number may be thought of as its distance from zero. So for a complex value the absolute value is a real number with magnitude SQRT(X%RE**2,X%IM**2), as if the real component is the x value and the imaginary value is the y value for the point <x,y>.

OPTIONS

o A : The value to compute the absolute value of.

RESULT

If A is of type integer or real, the value of the result is the absolute value |A| and of the same type and kind as the input argument.

If A is complex with value (X, Y), the result is a real equal to a processor-dependent approximation to

            sqrt(x**2 + y**2)

computed without undue overflow or underflow (that means the computation of the result can overflow the allowed magnitude of the real value returned, and that very small values can produce underflows if they are squared while calculating the returned value, for example).

That is, if you think of non-complex values as being complex values on the x-axis and complex values as being x-y points <x%re,x%im> the result of ABS(3) is the (positive) magnitude of the distance of the value from the origin.

EXAMPLES

Sample program:

    program demo_abs
       implicit none
       integer,parameter :: dp=kind(0.0d0)

! some values to use with ABS(3) integer :: i = -1 real :: x = -1.0 complex :: z = (-3.0,-4.0) doubleprecision :: rr = -45.78_dp

! some formats for pretty-printing some information character(len=*),parameter :: & frmt = ’(1x,a15,1x," In: ",g0, T51," Out: ",g0)’, & frmtc = ’(1x,a15,1x," In: (",g0,",",g0,")",T51," Out: ",g0)’, & gen = ’(*(g0,1x))’

! the basics print gen, ’basic usage:’ ! any integer, real, or complex type write(*, frmt) ’integer ’, i, abs(i) write(*, frmt) ’real ’, x, abs(x) write(*, frmt) ’doubleprecision ’, rr, abs(rr) write(*, frmtc) ’complex ’, z, abs(z)

! elemental print gen, ’abs is elemental:’, abs([20, 0, -1, -3, 100])

! the returned value for complex input can be thought of as the ! distance from the origin <0,0> print gen, ’distance of (’, z, ’) from zero is’, abs( z )

call DUSTY_CORNERS_1("beware of abs(-huge(0)-1)") call DUSTY_CORNERS_2("beware of losing precision using CMPLX(3)") call DUSTY_CORNERS_3("beware of overflow of complex values") call DUSTY_CORNERS_4("custom meaning for absolute value of COMPLEX")

contains

subroutine DUSTY_CORNERS_1(message) character(len=*),intent(in) :: message

! A dusty corner is that abs(-huge(0)-1) of an integer would be ! a representable negative value on most machines but result in a ! positive value out of range.

print gen, message ! By definition: ! You can take the absolute value of any value whose POSITIVE value ! is representable with the same type and kind.

print gen, ’abs range test : ’, abs(huge(0)), abs(-huge(0)) print gen, ’abs range test : ’, abs(huge(0.0)), abs(-huge(0.0)) print gen, ’abs range test : ’, abs(tiny(0.0)), abs(-tiny(0.0))

end subroutine DUSTY_CORNERS_1

subroutine DUSTY_CORNERS_2(message) character(len=*),intent(in) :: message

! dusty corner: "kind=dp" is required or the value returned by ! CMPLX() is a default real instead of double precision.

! Working with complex values you often encounter the CMPLX(3) ! function. CMPLX(3) defaults to returning a default REAL regardless ! of input type. Not really a direct problem with ABS(2f) per-se, ! but a common error when working with doubleprecision complex values

print gen, message print gen, ’real result versus doubleprecision result’, & & abs(cmplx(30.0_dp,40.0_dp)), & & abs(cmplx(30.0_dp,40.0_dp,kind=dp))

end subroutine DUSTY_CORNERS_2

subroutine DUSTY_CORNERS_3(message) character(len=*),intent(in) :: message print gen, message

! this will probably cause an overflow error, or !print gen, abs(cmplx( huge(0.0), huge(0.0) ))

print gen, ’because the biggest default real is’,huge(0.0) print gen, ’because returning magnitude of sqrt(x%re**2,x%im**2)’

end subroutine DUSTY_CORNERS_3

subroutine DUSTY_CORNERS_4(message) character(len=*),intent(in) :: message print gen, message

! if you do not want the distance for a complex value you ! might want something like returning a complex value with ! both the imaginary and real parts. One way to do that is

print gen, cmplx(abs(z%re),abs(z%im),kind=kind(z))

end subroutine DUSTY_CORNERS_4

end program demo_abs

Results:

     >  integer          In: -1                        Out: 1
     >  real             In: -1.00000000               Out: 1.00000000
     >  doubleprecision  In: -45.780000000000001       Out: 45.780000000000001
     >  complex          In: (-3.00000000,-4.00000000) Out: 5.00000000
     > abs is elemental: 20 0 1 3 100
     > distance of ( -3.00000000 -4.00000000 ) from zero is 5.00000000
     > beware of abs(-huge(0)-1)
     > abs range test :  2147483647 2147483647
     > abs range test :  0.340282347E+39 0.340282347E+39
     > abs range test :  0.117549435E-37 0.117549435E-37
     > beware of losing precision using CMPLX(3)
     > real result versus doubleprecision result 50.0000000 50.000000000000000
     > beware of overflow of complex values
     > because the biggest default real is 0.340282347E+39
     > because returning magnitude of sqrt(x%re**2,x%im**2)
     > making your own meaning for ABS(COMPLEX_VALUE)
     > 3.00000000 4.00000000

STANDARD

FORTRAN 77

SEE ALSO

SIGN(3)

Fortran intrinsic descriptions (license: MIT) @urbanjost


Nemo Release 3.1 abs (3fortran) November 02, 2024
Generated by manServer 1.08 from 95c200d6-bfdc-43ab-a153-da180045fbac using man macros.