I am overriding the concatenation operator to allow real values to be concatenated with strings.
function concatenateRealSigFigsWithString( floatIn, str ) result(cat)
! Arguments
character( len=* ), intent(in) :: str
real(8), intent(in) :: floatIn(2)
! Returns
character( len=: ), allocatable :: cat
! Variables
logical :: remove_decimal = .False.
real(8) :: float
character( len=16 ) :: float_as_str, fmt
integer :: sigfig, i
float = floatIn(1)
sigfig = int(floatIn(2))
do i = sigfig, 1, -1
if (float < 10.0_8**i .and. float > 10.0_8**(i-1) ) then
fmt = '(F' // sigfig + 1 // '.' // sigfig - i // ')'
if (i == sigfig) remove_decimal = .True.
end if
end do
if ( float < 1 ) then
fmt = '(F' // sigfig + 2 // '.' // sigfig // ')'
end if
if (float < 0.1 ) then
fmt = '(ES' // sigfig + 5 // '.' // sigfig - 1 // ')'
end if
if ( float > 10.0_8**sigfig ) then
fmt = '(ES' // sigfig+6 // '.' // sigfig-1 // ')'
end if
write(float_as_str,fmt) float
if (remove_decimal) float_as_str = float_as_str(1:len_trim(float_as_str)-1)
cat = trim(float_as_str) // str
! cat = fmt
end function concatenateRealSigFigsWithString
The real value is a actually a list. The first element is the number and the second is the significant figures. Values between 0 and 10^(sigfig) are given in decimal form. Otherwise, the value is given in scientific form. The concatenation works for all values except those greater than 10^(sigfig). So the focus of the issue here is in the line fmt = '(ES' // sigfig+6 // '.' // sigfig-1 // ')'
. For example, a value of 300,000 that should be written to 3 significant figures is formatted as 3.00E+0
.
I can't figure out why the exponent is only showing one digit instead of 2, since it should be 3.00E+05
.
I have tried specifying the width of exponent like fmt = '(ES' // sigfig+6 // '.' // sigfig-1 // 'E2)'
but that just gives me 3.00E+00
. I also tried expanding the width in case I did my math wrong and the exponent was getting cut off, but all that did was increase leading white space.
Any idea why the exponent is not showing the true value. Here is the code I used to test it.
program test
interface operator(//)
procedure :: concatenateRealSigFigsWithString, concatenateStringWithInteger
end interface
real(8) :: sigfig = 3
print *, [2.337e-7_8, sigfig] // " slugs"
print *, [2.337e-6_8, sigfig] // " slugs"
print *, [2.337e-5_8, sigfig] // " slugs"
print *, [2.337e-4_8, sigfig] // " slugs"
print *, [2.337e-3_8, sigfig] // " slugs"
print *, [2.337e-2_8, sigfig] // " slugs"
print *, [2.337e-1_8, sigfig] // " slugs"
print *, [2.337e0_8, sigfig] // " slugs"
print *, [2.337e01_8, sigfig] // " slugs"
print *, [2.337e02_8, sigfig] // " slugs"
print *, [2.337e03_8, sigfig] // " slugs"
print *, [2.337e4_8, sigfig] // " slugs"
print *, [2.337e5_8, sigfig] // " slugs"
print *, [2.337e6_8, sigfig] // " slugs"
print *, [2.337e7_8, sigfig] // " slugs"
print *, [2.337e8_8, sigfig] // " slugs"
print *, [2.337e9_8, sigfig] // " slugs"
print *, [2.337e10_8, sigfig] // " slugs"
contains
function concatenateStringWithInteger(str,int) result(cat)
! Arguments
character( len=* ), intent(in) :: str
integer, intent(in) :: int
! Returns
character( len=: ), allocatable :: cat
! Variables
character( len=9 ) :: int_as_str
write(int_as_str,'(I0)') int
cat = str // trim(int_as_str)
end function concatenateStringWithInteger
function concatenateRealSigFigsWithString( floatIn, str ) result(cat)
! Arguments
character( len=* ), intent(in) :: str
real(8), intent(in) :: floatIn(2)
! Returns
character( len=: ), allocatable :: cat
! Variables
logical :: remove_decimal = .False.
real(8) :: float
character( len=16 ) :: float_as_str, fmt
integer :: sigfig, i
float = floatIn(1)
sigfig = int(floatIn(2))
do i = sigfig, 1, -1
if (float < 10.0_8**i .and. float > 10.0_8**(i-1) ) then
fmt = '(F' // sigfig + 1 // '.' // sigfig - i // ')'
if (i == sigfig) remove_decimal = .True.
end if
end do
if ( float < 1 ) then
fmt = '(F' // sigfig + 2 // '.' // sigfig // ')'
end if
if (float < 0.1 ) then
fmt = '(ES' // sigfig + 5 // '.' // sigfig - 1 // ')'
end if
if ( float > 10.0_8**sigfig ) then
fmt = '(ES' // sigfig+6 // '.' // sigfig-1 // ')'
end if
write(float_as_str,fmt) float
if (remove_decimal) float_as_str = float_as_str(1:len_trim(float_as_str)-1)
cat = trim(float_as_str) // str
! cat = fmt
end function concatenateRealSigFigsWithString
end program test