Skip to content

Commit

Permalink
fix last rdieee() warning (#640)
Browse files Browse the repository at this point in the history
* added rdieeec() which reads from char array

* use new rdieeec() function to fix warning

* debugging _d problem

* debugging _d problem

* debugging _d problem

* improved documentation

* improved documentation
  • Loading branch information
edwardhartnett authored Mar 13, 2024
1 parent ed773eb commit b9e638b
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 44 deletions.
27 changes: 25 additions & 2 deletions src/g2bytes.F90
Original file line number Diff line number Diff line change
Expand Up @@ -457,11 +457,33 @@ subroutine g2_sbytesc8(out, in, iskip, nbits, nskip, n)
enddo
end subroutine g2_sbytesc8

!> Copy array of 32-bit IEEE floating point values stored in char
!> array to local floating point representation.
!>
!> @param[in] cieee Input char array containing floating point values
!> in 32-bit IEEE format.
!> @param[out] a Output array of real values.
!> @param[in] num Number of floating point values to convert.
!>
!> @author Edward Hartnett @date Mar 12, 2024
subroutine rdieeec(cieee, a, num)
implicit none

character(len = 1), intent(in) :: cieee(*)
real, intent(out) :: a(num)
integer, intent(in) :: num
real (kind = 4) :: rieee(num)

rieee(1:num) = transfer(cieee(1:num * 4), rieee, num)
call rdieee(rieee, a, num)
end subroutine rdieeec

!> Copy array of 32-bit IEEE floating point values to local
!> floating point representation.
!>
!> @param[in] rieee Input array of floating point values in 32-bit
!> IEEE format.
!> IEEE format. Note that this array is always 32-bit floats, even
!> when compiled with -d.
!> @param[out] a Output array of real values.
!> @param[in] num Number of floating point values to convert.
!>
Expand Down Expand Up @@ -509,7 +531,8 @@ end subroutine rdieee
!>
!> @param[in] a Input array of floating point values.
!> @param[out] rieee Output array of floating point values in 32-bit
!> IEEE format.
!> IEEE format. Note that this array is always 32-bit floats, even
!> when compiled with -d.
!> @param[in] num Number of floating point values to convert.
!>
!> @author Stephen Gilbert @date 2000-05-09
Expand Down
84 changes: 42 additions & 42 deletions src/g2spec.F90
Original file line number Diff line number Diff line change
Expand Up @@ -120,66 +120,66 @@ end subroutine specpack
!> @param[out] fld Contains the unpacked data values.
!>
!> @author Stephen Gilbert @date 2002-12-19
subroutine specunpack(cpack,len,idrstmpl,ndpts,JJ,KK,MM,fld)
subroutine specunpack(cpack, len, idrstmpl, ndpts, JJ, KK, MM, fld)

character(len=1),intent(in) :: cpack(len)
integer,intent(in) :: ndpts,len,JJ,KK,MM
integer,intent(in) :: idrstmpl(*)
real,intent(out) :: fld(ndpts)
character(len = 1), intent(in) :: cpack(len)
integer, intent(in) :: ndpts, len, JJ, KK, MM
integer, intent(in) :: idrstmpl(*)
real, intent(out) :: fld(ndpts)

integer :: ifld(ndpts),Ts
integer :: ifld(ndpts), Ts
integer(4) :: ieee
real :: ref,bscale,dscale,unpk(ndpts)
real,allocatable :: pscale(:)
real :: ref, bscale, dscale, unpk(ndpts)
real, allocatable :: pscale(:)

ieee = idrstmpl(1)
call rdieee(ieee,ref,1)
call rdieee(ieee, ref, 1)
bscale = 2.0**real(idrstmpl(2))
dscale = 10.0**real(-idrstmpl(3))
nbits = idrstmpl(4)
Js=idrstmpl(6)
Ks=idrstmpl(7)
Ms=idrstmpl(8)
Ts=idrstmpl(9)
Js = idrstmpl(6)
Ks = idrstmpl(7)
Ms = idrstmpl(8)
Ts = idrstmpl(9)

if (idrstmpl(10).eq.1) then ! unpacked floats are 32-bit IEEE
call rdieee(cpack,unpk,Ts) ! read IEEE unpacked floats
iofst=32*Ts
call g2_gbytesc(cpack,ifld,iofst,nbits,0,ndpts-Ts) ! unpack scaled data
if (idrstmpl(10) .eq. 1) then ! unpacked floats are 32-bit IEEE
call rdieeec(cpack, unpk, Ts) ! read IEEE unpacked floats
iofst = 32 * Ts
call g2_gbytesc(cpack, ifld, iofst, nbits, 0, ndpts - Ts) ! unpack scaled data

! Calculate Laplacian scaling factors for each possible wave number.
allocate(pscale(JJ+MM))
tscale=real(idrstmpl(5))*1E-6
do n=Js,JJ+MM
pscale(n)=real(n*(n+1))**(-tscale)
allocate(pscale(JJ + MM))
tscale = real(idrstmpl(5)) * 1E-6
do n = Js, JJ + MM
pscale(n) = real(n * (n + 1))**(-tscale)
enddo

! Assemble spectral coeffs back to original order.
inc=1
incu=1
incp=1
do m=0,MM
Nm=JJ ! triangular or trapezoidal
if (KK .eq. JJ+MM) Nm=JJ+m ! rhombodial
Ns=Js ! triangular or trapezoidal
if (Ks .eq. Js+Ms) Ns=Js+m ! rhombodial
do n=m,Nm
if (n.le.Ns .AND. m.le.Ms) then ! grab unpacked value
fld(inc)=unpk(incu) ! real part
fld(inc+1)=unpk(incu+1) ! imaginary part
inc=inc+2
incu=incu+2
else ! Calc coeff from packed value
fld(inc)=((real(ifld(incp))*bscale)+ref)*dscale*pscale(n) ! real part
fld(inc+1)=((real(ifld(incp+1))*bscale)+ref)*dscale*pscale(n) ! imaginary part
inc=inc+2
incp=incp+2
inc = 1
incu = 1
incp = 1
do m = 0, MM
Nm = JJ ! triangular or trapezoidal
if (KK .eq. JJ + MM) Nm = JJ + m ! rhombodial
Ns = Js ! triangular or trapezoidal
if (Ks .eq. Js + Ms) Ns = Js + m ! rhombodial
do n = m, Nm
if (n .le. Ns .AND. m .le. Ms) then ! grab unpacked value
fld(inc) = unpk(incu) ! real part
fld(inc + 1) = unpk(incu + 1) ! imaginary part
inc = inc + 2
incu = incu + 2
else ! Calc coeff from packed value
fld(inc) = ((real(ifld(incp))*bscale) + ref)*dscale*pscale(n) ! real part
fld(inc + 1) = ((real(ifld(incp + 1)) * bscale) + ref) * dscale * pscale(n) ! imaginary part
inc = inc + 2
incp = incp + 2
endif
enddo
enddo
deallocate(pscale)
else
print *,'specunpack: Cannot handle 64 or 128-bit floats.'
fld=0.0
print *, 'specunpack: Cannot handle 64 or 128-bit floats.'
fld = 0.0
endif
end subroutine specunpack
27 changes: 27 additions & 0 deletions tests/test_gbytec2.F90
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ program test_gbytec2
integer (kind = 4) :: i1
integer :: i
real (kind = 4) :: r1(1), r2(2)
real :: r1_2(1), r2_2(2)

! Initialize some test data.
do i = 1, 4
Expand Down Expand Up @@ -129,6 +130,32 @@ program test_gbytec2
end do
print *, 'OK!'

print *, 'testing rdieeec() with a float...'
! Reset array to IEEE float value 1.0.
c4(4) = char(63)
c4(3) = char(128)
c4(2) = char(0)
c4(1) = char(0)
r1_2(1) = 0
call rdieee(c4, r1_2, 1)
if (r1_2(1) .ne. 1.0) stop 300
print *, 'OK!'

print *, 'testing rdieeec() with a two floats...'
! Reset array to IEEE float value 1.0, twice.
do i = 0, 1
c8(4 + i * 4) = char(63)
c8(3 + i * 4) = char(128)
c8(2 + i * 4) = char(0)
c8(1 + i * 4) = char(0)
end do
r2_2(1) = 0
r2_2(2) = 0
call rdieeec(c8, r2_2, 2)
if (r2_2(1) .ne. 1.0 .or. r2_2(2) .ne. 1.0) stop 310
print *, 'OK!'

print *, 'SUCCESS!'

end program test_gbytec2

0 comments on commit b9e638b

Please sign in to comment.