diff --git a/src/g2_gbytesc.F90 b/src/g2_gbytesc.F90 index de841bd0..de9f69bc 100644 --- a/src/g2_gbytesc.F90 +++ b/src/g2_gbytesc.F90 @@ -3,9 +3,8 @@ !> string and unpacked array. !> @author Stephen Gilbert @date 2004-04-27 -!> Extract arbitrary size values from a packed bit string, right -!> justifying each value in the unpacked array without skip and -!> interations. +!> Extract one arbitrary size value (up to 32 bits) from a packed bit +!> string, right justifying each value in the unpacked array. !> !> This should be used when input array IN has only one element. If in !> has more elements, use g2_sbytesc(). @@ -13,7 +12,8 @@ !> @param[in] in Array input. !> @param[inout] iout Unpacked array output. !> @param[in] iskip Initial number of bits to skip. -!> @param[in] nbits Number of bits of each integer in IN to take. +!> @param[in] nbits Number of bits of each integer in IN to take. Must +!> be 32 or less. !> !> @author Stephen Gilbert @date 2004-04-27 subroutine g2_gbytec(in, iout, iskip, nbits) @@ -25,51 +25,110 @@ subroutine g2_gbytec(in, iout, iskip, nbits) call g2_gbytesc(in, iout, iskip, nbits, 0, 1) end subroutine g2_gbytec -!> Put arbitrary size values into a packed bit string, taking the low -!> order bits from each value in the unpacked array without skip and -!> interation. +!> Extract arbitrary size values (up to 32 bits each) from a packed +!> bit string, right justifying each value in the unpacked array. !> -!> This should be used when input array IN has only one element. If IN -!> has more elements, use G2_SBYTESC(). -!> -!> @param[inout] out packed array output -!> @param[in] in unpacked array input +!> @param[in] in array input +!> @param[out] iout unpacked array output !> @param[in] iskip initial number of bits to skip -!> @param[in] nbits Number of bits of each integer in OUT to fill. +!> @param[in] nbits Number of bits of each integer in IN to take. Must +!> be 32 or less. +!> @param[in] nskip Additional number of bits to skip on each iteration. +!> @param[in] n Number of integers to extract. !> !> @author Stephen Gilbert @date 2004-04-27 -subroutine g2_sbytec(out, in, iskip, nbits) +subroutine g2_gbytesc(in, iout, iskip, nbits, nskip, n) implicit none - character*1, intent(inout) :: out(*) - integer, intent(in) :: in(*) + character*1, intent(in) :: in(*) + integer, intent(out) :: iout(*) + integer, intent(in) :: iskip, nbits, nskip, n + integer :: tbit, bitcnt + integer, parameter :: ones(8) = (/ 1, 3, 7, 15, 31, 63, 127, 255 /) + + integer :: nbit, i, index, ibit, itmp + integer, external :: mova2i + + ! nbit is the start position of the field in bits + nbit = iskip + do i = 1, n + bitcnt = nbits + index = nbit / 8 + 1 + ibit = mod(nbit, 8) + nbit = nbit + nbits + nskip + + ! first byte + tbit = min(bitcnt, 8 - ibit) + itmp = iand(mova2i(in(index)), ones(8 - ibit)) + if (tbit .ne. 8 - ibit) itmp = ishft(itmp, tbit - 8 + ibit) + index = index + 1 + bitcnt = bitcnt - tbit + + ! now transfer whole bytes + do while (bitcnt .ge. 8) + itmp = ior(ishft(itmp,8), mova2i(in(index))) + bitcnt = bitcnt - 8 + index = index + 1 + enddo + + ! get data from last byte + if (bitcnt .gt. 0) then + itmp = ior(ishft(itmp, bitcnt), iand(ishft(mova2i(in(index)), & + - (8 - bitcnt)), ones(bitcnt))) + endif + + iout(i) = itmp + enddo + +end subroutine g2_gbytesc + +!> Extract one arbitrary sized (up to 64-bits) values from a packed bit +!> string, right justifying each value in the unpacked array. +!> +!> This should be used when input array in has only one element. If in +!> has more elements, use g2_sbytesc(). +!> +!> @param[in] in Array input. +!> @param[inout] iout Unpacked array output. +!> @param[in] iskip Initial number of bits to skip. +!> @param[in] nbits Number of bits of each integer in IN to take. Must +!> be 64 or less. +!> +!> @author Stephen Gilbert @date 2004-04-27 +subroutine g2_gbytec8(in, iout, iskip, nbits) + implicit none + + character*1, intent(in) :: in(*) + integer (kind = 8), intent(inout) :: iout(*) integer, intent(in) :: iskip, nbits - call g2_sbytesc(out, in, iskip, nbits, 0, 1) -end subroutine g2_sbytec + call g2_gbytesc8(in, iout, iskip, nbits, 0, 1) +end subroutine g2_gbytec8 -!> Extract arbitrary size values from a packed bit string, right -!> justifying each value in the unpacked array with skip and -!> interation options. +!> Extract arbitrary sized (up to 64-bits) values from a packed bit +!> string, right justifying each value in the unpacked array. !> !> @param[in] in array input !> @param[out] iout unpacked array output !> @param[in] iskip initial number of bits to skip -!> @param[in] nbits Number of bits of each integer in IN to take. +!> @param[in] nbits Number of bits of each integer in IN to take. Must +!> be 64 or less. !> @param[in] nskip Additional number of bits to skip on each iteration. !> @param[in] n Number of integers to extract. !> !> @author Stephen Gilbert @date 2004-04-27 -subroutine g2_gbytesc(in, iout, iskip, nbits, nskip, n) +subroutine g2_gbytesc8(in, iout, iskip, nbits, nskip, n) implicit none character*1, intent(in) :: in(*) - integer, intent(out) :: iout(*) + integer (kind = 8), intent(out) :: iout(*) integer, intent(in) :: iskip, nbits, nskip, n integer :: tbit, bitcnt integer, parameter :: ones(8) = (/ 1, 3, 7, 15, 31, 63, 127, 255 /) integer :: nbit, i, index, ibit, itmp + integer (kind = 8) :: itmp8, itmp8_2, itmp8_3 integer, external :: mova2i + integer (kind = 8), external :: mova2i8 ! nbit is the start position of the field in bits nbit = iskip @@ -81,37 +140,65 @@ subroutine g2_gbytesc(in, iout, iskip, nbits, nskip, n) ! first byte tbit = min(bitcnt, 8 - ibit) + itmp8 = iand(mova2i8(in(index)), int(ones(8 - ibit), kind = 8)) itmp = iand(mova2i(in(index)), ones(8 - ibit)) if (tbit .ne. 8 - ibit) itmp = ishft(itmp, tbit - 8 + ibit) + if (tbit .ne. 8 - ibit) itmp8 = ishft(itmp8, tbit - 8 + ibit) index = index + 1 bitcnt = bitcnt - tbit ! now transfer whole bytes do while (bitcnt .ge. 8) itmp = ior(ishft(itmp,8), mova2i(in(index))) + itmp8 = ior(ishft(itmp8,8), mova2i8(in(index))) bitcnt = bitcnt - 8 index = index + 1 enddo ! get data from last byte if (bitcnt .gt. 0) then - itmp = ior(ishft(itmp, bitcnt), iand(ishft(mova2i(in(index)), & - - (8 - bitcnt)), ones(bitcnt))) + itmp = ior(ishft(itmp, bitcnt), iand(ishft(mova2i(in(index)), - (8 - bitcnt)), ones(bitcnt))) + itmp8_2 = ishft(mova2i8(in(index)), int(-(8 - bitcnt), kind(8))) + itmp8_3 = int(ones(bitcnt), kind(8)) + itmp8 = ior(ishft(itmp8, bitcnt), iand(itmp8_2, itmp8_3)) endif - iout(i) = itmp + iout(i) = itmp8 enddo -end subroutine g2_gbytesc +end subroutine g2_gbytesc8 + +!> Put one arbitrary sized (up to 32 bits) values into a packed bit +!> string, taking the low order bits from the value in the unpacked +!> array. +!> +!> This should be used when input array IN has only one element. If IN +!> has more elements, use g2_sbytesc(). +!> +!> @param[inout] out packed array output +!> @param[in] in unpacked array input +!> @param[in] iskip initial number of bits to skip +!> @param[in] nbits Number of bits of each integer in OUT to fill. +!> +!> @author Stephen Gilbert @date 2004-04-27 +subroutine g2_sbytec(out, in, iskip, nbits) + implicit none + + character*1, intent(inout) :: out(*) + integer, intent(in) :: in(*) + integer, intent(in) :: iskip, nbits + call g2_sbytesc(out, in, iskip, nbits, 0, 1) +end subroutine g2_sbytec -!> Put arbitrary size values into a packed bit string, taking the low -!> order bits from each value in the unpacked array with skip and -!> interation options. +!> Put arbitrary size (up to 32 bits each) values into a packed bit +!> string, taking the low order bits from each value in the unpacked +!> array. !> !> @param[out] out Packed array output. !> @param[in] in Unpacked array input. !> @param[in] iskip Initial number of bits to skip. -!> @param[in] nbits Number of bits of each integer in OUT to fill. +!> @param[in] nbits Number of bits of each integer in OUT to +!> fill. Must be 32 or less. !> @param[in] nskip Additional number of bits to skip on each iteration. !> @param[in] n Number of iterations. !> @@ -131,13 +218,15 @@ subroutine g2_sbytesc(out, in, iskip, nbits, nskip, n) ! number bits from zero to ... ! nbit is the last bit of the field to be filled nbit = iskip + nbits - 1 + !print *, 'nbit', nbit, 'nbits ', nbits, 'nskip', nskip, 'n', n do i = 1, n itmp = in(i) bitcnt = nbits index = nbit / 8 + 1 ibit = mod(nbit, 8) nbit = nbit + nbits + nskip - + !print *, 'i', i, 'itmp', itmp, 'bitcnt', bitcnt, 'index', index, 'ibit', ibit, 'nbit', nbit + ! make byte aligned if (ibit .ne. 7) then tbit = min(bitcnt, ibit + 1) @@ -155,17 +244,114 @@ subroutine g2_sbytesc(out, in, iskip, nbits, nskip, n) ! do by bytes do while (bitcnt .ge. 8) out(index) = char(iand(itmp, 255)) + !print '(z2.2, x, z2.2, x, z2.2)', out(index), itmp, iand(itmp, 255) itmp = ishft(itmp, -8) bitcnt = bitcnt - 8 index = index - 1 enddo - ! do last byte + ! Do left over bits. if (bitcnt .gt. 0) then itmp2 = iand(itmp, ones(bitcnt)) + !print '(z2.2, x, z2.2)', ones(bitcnt), itmp2 itmp3 = iand(mova2i(out(index)), 255 - ones(bitcnt)) out(index) = char(ior(itmp2, itmp3)) endif enddo end subroutine g2_sbytesc + +!> Put one arbitrary sized (up to 64 bits) values into a packed bit +!> string, taking the low order bits from each value in the unpacked +!> array. +!> +!> This should be used when input array IN has only one element. If IN +!> has more elements, use g2_sbytesc(). +!> +!> @param[inout] out packed array output +!> @param[in] in unpacked array input +!> @param[in] iskip initial number of bits to skip +!> @param[in] nbits Number of bits of each integer in OUT to +!> fill. Must be 64 or less. +!> +!> @author Stephen Gilbert @date 2004-04-27 +subroutine g2_sbytec8(out, in, iskip, nbits) + implicit none + + character*1, intent(inout) :: out(*) + integer (kind = 8), intent(in) :: in(*) + integer, intent(in) :: iskip, nbits + call g2_sbytesc8(out, in, iskip, nbits, 0, 1) +end subroutine g2_sbytec8 + +!> Put arbitrary sized (up to 64 bits each) values into a packed bit +!> string, taking the low order bits from each value in the unpacked +!> array. +!> +!> @param[out] out Packed array output. +!> @param[in] in Unpacked array input. +!> @param[in] iskip Initial number of bits to skip. +!> @param[in] nbits Number of bits of each integer in OUT to +!> fill. Must be 64 or less. +!> @param[in] nskip Additional number of bits to skip on each iteration. +!> @param[in] n Number of iterations. +!> +!> @author Stephen Gilbert @date 2004-04-27 +subroutine g2_sbytesc8(out, in, iskip, nbits, nskip, n) + implicit none + + character*1, intent(out) :: out(*) + integer (kind = 8), intent(in) :: in(n) + integer, intent(in) :: iskip, nbits, nskip, n + + integer :: bitcnt, tbit + integer, parameter :: ones(8)=(/ 1, 3, 7, 15, 31, 63, 127, 255/) + integer :: nbit, i, index, ibit, imask, itmp1, itmp2, itmp3 + integer (kind = 8) :: itmp8, itmp8_2 + integer, external :: mova2i + + ! number bits from zero to ... + ! nbit is the last bit of the field to be filled + nbit = iskip + nbits - 1 + print *, 'nbit', nbit, 'nbits ', nbits, 'nskip', nskip, 'n', n + do i = 1, n + itmp8 = in(i) + bitcnt = nbits + index = nbit / 8 + 1 + ibit = mod(nbit, 8) + nbit = nbit + nbits + nskip + print *, 'i', i, 'itmp8', itmp8, 'bitcnt', bitcnt, 'index', index, 'ibit', ibit, 'nbit', nbit + + ! make byte aligned + if (ibit .ne. 7) then + tbit = min(bitcnt, ibit + 1) + imask = ishft(ones(tbit), 7 - ibit) + itmp1 = int(ishft(itmp8, int(7 - ibit, kind(8))), kind(4)) + itmp2 = iand(itmp1, imask) + itmp3 = iand(mova2i(out(index)), 255 - imask) + out(index) = char(ior(itmp2, itmp3)) + bitcnt = bitcnt - tbit + itmp8 = ishft(itmp8, -tbit) + index = index - 1 + endif + + ! now byte aligned + + ! Process a byte at a time. + do while (bitcnt .ge. 8) + !print *, bitcnt, iand(itmp8, 255_8) + out(index) = char(iand(itmp8, 255_8)) + itmp8 = ishft(itmp8, -8) + bitcnt = bitcnt - 8 + index = index - 1 + enddo + + ! Take care of left over bits. + if (bitcnt .gt. 0) then + itmp8_2 = int(ones(bitcnt), kind(8)) + itmp2 = int(iand(itmp8, itmp8_2), kind(4)) + itmp3 = iand(mova2i(out(index)), 255 - ones(bitcnt)) + out(index) = char(ior(itmp2, itmp3)) + endif + enddo +end subroutine g2_sbytesc8 diff --git a/src/mova2i.c b/src/mova2i.c index ee563843..4db7920a 100644 --- a/src/mova2i.c +++ b/src/mova2i.c @@ -1,19 +1,21 @@ /** * @file - * @brief mova2i Moves a bit string from a char*1 to int + * @brief Move bits from a char*1 to an int. * @author Stephen Gilbert @date 2002-08-15 */ /** - * This Function copies a bit string from a Character*1 variable - * to an integer variable. It is intended to replace the Fortran Intrinsic - * Function ICHAR, which only supports 0 <= ICHAR(a) <= 127 on the - * IBM SP. If "a" is greater than 127 in the collating sequence, - * ICHAR(a) does not return the expected bit value. - * This function can be used for all values 0 <= ICHAR(a) <= 255. + * Derefrence char pointer and cast result as 32-bit int. + * + * This function is intended to replace the Fortran Intrinsic Function + * ICHAR, which only supports 0 <= ICHAR(a) <= 127 on the IBM SP. If + * "a" is greater than 127 in the collating sequence, ICHAR(a) does + * not return the expected bit value. This function can be used for + * all values 0 <= ICHAR(a) <= 255. * - * @param[in] a - Character*1 variable that holds the bitstring to extract - * @return - > mova2i - Integer value of the bitstring in character a + * @param a Pointer to char. + * + * @return 32-bit integer containing the value of the bits. * * @author Stephen Gilbert @date 2002-08-15 * */ @@ -21,3 +23,19 @@ int mova2i_(unsigned char *a) { return (int)(*a); } + +/** + * Derefrence char pointer and cast result as 64-bit int. + * + * See mova2i_() for details. + * + * @param a Pointer to char. + * + * @return 64-bit integer containing value of the bits. + * + * @author Ed Hartnett @date Feb 7, 2024 + * */ +int mova2i8_(unsigned char *a) +{ + return (long long int)(*a); +} diff --git a/tests/test_gbytec.F90 b/tests/test_gbytec.F90 index 6064e2e2..57880236 100644 --- a/tests/test_gbytec.F90 +++ b/tests/test_gbytec.F90 @@ -29,24 +29,36 @@ program test_gbytec integer :: num integer(kind = 4) :: in44(4), in44_1(4) integer(kind = 8) :: in8(1), in8_1(1), in84(4), in84_1(4) + integer, external :: mova2i print *, 'Testing g2_gbytesc.F90 subroutines.' - print *, ' testing g2_sbytec()...' + print *, ' testing g2_sbytec(), packing one 32-bit int into 8 bits of a char array in big-endian...' in(1) = 3 out(1) = char(0) call g2_sbytec(out, in, iskip, nbits) - if (ichar(out(1)) .ne. in(1)) stop 10 - + if (mova2i(out(1)) .ne. in(1)) stop 10 + !print '(z2.2)', out(1) + + print *, ' packing one 32-bit int into 32 bits of a char array in big-endian...' + in(1) = 3 + do i = 1, 4 + out4(i) = char(0) + end do + call g2_sbytec(out4, in, 0, 32) + ! do i = 1, 4 + ! print '(z2.2)', out4(i) + ! end do + print *, ' testing g2_gbytec()...' call g2_gbytec(out, in, iskip, nbits) - if (ichar(out(1)) .ne. in(1)) stop 11 + if (mova2i(out(1)) .ne. in(1)) stop 11 print *, ' testing g2_sbytesc()...' in(1) = 3 out(1) = char(0) call g2_sbytesc(out, in, iskip, nbits, nskip, n) - if (ichar(out(1)) .ne. in(1)) stop 20 + if (mova2i(out(1)) .ne. in(1)) stop 20 ! This will pack the numbers 1 and 2 into the first two chars of the ! buffer. The rest of the output buffer will remain zeros. @@ -60,9 +72,9 @@ program test_gbytec call g2_sbytesc(out8, in2, iskip, nbits, nskip, n2) do i = 1, 8 if (i .le. 2) then - if (ichar(out8(i)) .ne. in2(i)) stop 30; + if (mova2i(out8(i)) .ne. in2(i)) stop 30; else - if (ichar(out8(i)) .ne. 0) stop 31; + if (mova2i(out8(i)) .ne. 0) stop 31; endif end do @@ -80,7 +92,7 @@ program test_gbytec end do call g2_sbytesc(out5, in5, iskip, nbits, nskip, n5) do i = 1, 5 - if (ichar(out5(i)) .ne. in5(i)) stop 40; + if (mova2i(out5(i)) .ne. in5(i)) stop 40; end do ! Now pack 5 values into the 10 character array out10. Skip every @@ -95,9 +107,9 @@ program test_gbytec do i = 1, 10 ! print '(z2.2)', out10(i) if (mod(i, 2) .gt. 0) then - if (ichar(out10(i)) .ne. in5(int(i/2) + 1)) stop 51; + if (mova2i(out10(i)) .ne. in5(int(i/2) + 1)) stop 51; else - if (ichar(out10(i)) .ne. 0) stop 52; + if (mova2i(out10(i)) .ne. 0) stop 52; endif end do @@ -105,7 +117,7 @@ program test_gbytec in(1) = 1 out(1) = char(0) call g2_sbytec(out, in, 1, 6) - if (ichar(out(1)) .ne. 2) stop 53 + if (mova2i(out(1)) .ne. 2) stop 53 print *, ' testing g2_sbytesc() with a size 4 output array...' iskip = 0 @@ -114,8 +126,8 @@ program test_gbytec num = 1 in(1) = 1 call g2_sbytesc(out4, in, iskip, nbits, nskip, num) - if (ichar(out4(1)) .ne. 0 .and. ichar(out4(2)) .ne. 0 .and. & - ichar(out4(3)) .ne. 0 .and. ichar(out4(4)) .ne. 1) stop 60 + if (mova2i(out4(1)) .ne. 0 .and. mova2i(out4(2)) .ne. 0 .and. & + mova2i(out4(3)) .ne. 0 .and. mova2i(out4(4)) .ne. 1) stop 60 print *, ' now unpack into 4 ints with g2_gbytesc()...' call g2_gbytesc(out4, in4, iskip, 8, 0, 4) @@ -135,17 +147,17 @@ program test_gbytec ! used, because I am passing in a real array instead of an int array ! for the in parameter. This is how g2_sbytesc() is called in ! addfield.F90. - print *, ' testing g2_sbytesc() with a real array (size 1) instead of an int array...' - iskip = 0 - nbits = 32 - nskip = 0 - num = 1 - r_in(1) = 1 - call g2_sbytesc(out4, r_in, iskip, nbits, nskip, num) - ! Note that the 32-bit IEEE representation of 1.0 is 3f800000. The - ! decimal for 3f is 63, the decimal for 80 is 128. - if (ichar(out4(1)) .ne. 63 .and. ichar(out4(2)) .ne. 128 .and. & - ichar(out4(3)) .ne. 0 .and. ichar(out4(4)) .ne. 0) stop 80 + ! print *, ' testing g2_sbytesc() with a real array (size 1) instead of an int array...' + ! iskip = 0 + ! nbits = 32 + ! nskip = 0 + ! num = 1 + ! r_in(1) = 1 + ! call g2_sbytesc(out4, r_in, iskip, nbits, nskip, num) + ! ! Note that the 32-bit IEEE representation of 1.0 is 3f800000. The + ! ! decimal for 3f is 63, the decimal for 80 is 128. + ! if (mova2i(out4(1)) .ne. 63 .and. mova2i(out4(2)) .ne. 128 .and. & + ! mova2i(out4(3)) .ne. 0 .and. mova2i(out4(4)) .ne. 0) stop 80 ! print '(z2.2)', out4(1) ! This test is the same as above, but does not require the @@ -160,27 +172,27 @@ program test_gbytec call g2_sbytesc(out4, in, iskip, nbits, nskip, num) ! Note that the 32-bit IEEE representation of 1.0 is 3f800000. The ! decimal for 3f is 63, the decimal for 80 is 128. - if (ichar(out4(1)) .ne. 63 .and. ichar(out4(2)) .ne. 128 .and. & - ichar(out4(3)) .ne. 0 .and. ichar(out4(4)) .ne. 0) stop 90 + if (mova2i(out4(1)) .ne. 63 .and. mova2i(out4(2)) .ne. 128 .and. & + mova2i(out4(3)) .ne. 0 .and. mova2i(out4(4)) .ne. 0) stop 90 ! For this test to pass the -fallow-argument-mismatch flag must be ! used, because I am passing in a real array instead of an int array ! for the in parameter. This is how g2_sbytesc() is called in ! addfield.F90. - print *, ' testing g2_sbytesc() with a real array instead of an int array...' - iskip = 0 - nbits = 32 - nskip = 0 - num = 2 - r_in2(1) = 1 - r_in2(2) = 1 - call g2_sbytesc(out8, r_in2, iskip, nbits, nskip, num) - ! Note that the 32-bit IEEE representation of 1.0 is 3f800000. The - ! decimal for 3f is 63, the decimal for 80 is 128. - if (ichar(out8(1)) .ne. 63 .and. ichar(out8(2)) .ne. 128 .and. & - ichar(out8(3)) .ne. 0 .and. ichar(out8(4)) .ne. 0) stop 100 - if (ichar(out8(5)) .ne. 63 .and. ichar(out8(6)) .ne. 128 .and. & - ichar(out8(7)) .ne. 0 .and. ichar(out8(8)) .ne. 0) stop 110 + ! print *, ' testing g2_sbytesc() with a real array instead of an int array...' + ! iskip = 0 + ! nbits = 32 + ! nskip = 0 + ! num = 2 + ! r_in2(1) = 1 + ! r_in2(2) = 1 + ! call g2_sbytesc(out8, r_in2, iskip, nbits, nskip, num) + ! ! Note that the 32-bit IEEE representation of 1.0 is 3f800000. The + ! ! decimal for 3f is 63, the decimal for 80 is 128. + ! if (mova2i(out8(1)) .ne. 63 .and. mova2i(out8(2)) .ne. 128 .and. & + ! mova2i(out8(3)) .ne. 0 .and. mova2i(out8(4)) .ne. 0) stop 100 + ! if (mova2i(out8(5)) .ne. 63 .and. mova2i(out8(6)) .ne. 128 .and. & + ! mova2i(out8(7)) .ne. 0 .and. mova2i(out8(8)) .ne. 0) stop 110 ! print '(z2.2)', out8(1) ! This test is the same as above, but does not require the -fallow-argument-mismatch flag. @@ -195,33 +207,33 @@ program test_gbytec call g2_sbytesc(out8, in2, iskip, nbits, nskip, num) ! Note that the 32-bit IEEE representation of 1.0 is 3f800000. The ! decimal for 3f is 63, the decimal for 80 is 128. - if (ichar(out4(1)) .ne. 63 .and. ichar(out4(2)) .ne. 128 .and. & - ichar(out4(3)) .ne. 0 .and. ichar(out4(4)) .ne. 0) stop 120 - if (ichar(out8(5)) .ne. 63 .and. ichar(out8(6)) .ne. 128 .and. & - ichar(out8(7)) .ne. 0 .and. ichar(out8(8)) .ne. 0) stop 130 - ! print '(z2.2)', out4(1) + if (mova2i(out4(1)) .ne. 63 .and. mova2i(out4(2)) .ne. 128 .and. & + mova2i(out4(3)) .ne. 0 .and. mova2i(out4(4)) .ne. 0) stop 120 + if (mova2i(out8(5)) .ne. 63 .and. mova2i(out8(6)) .ne. 128 .and. & + mova2i(out8(7)) .ne. 0 .and. mova2i(out8(8)) .ne. 0) stop 130 + !print '(z2.2)', out4(1) - print *, ' testing g2_sbytec() with 64-bit int...' + print *, ' testing g2_sbytec8() with 64-bit int...' in8(1) = 1 do i = 1, 8 out8(i) = char(0) end do - call g2_sbytec(out8, in8, iskip, 64) + call g2_sbytec8(out8, in8, iskip, 64) do i = 1, 8 !print '(z2.2)', out8(i) if (i .lt. 8) then - if (ichar(out8(i)) .ne. 0) stop 140 + if (mova2i(out8(i)) .ne. 0) stop 140 else - if (ichar(out8(i)) .ne. 1) stop 140 + if (mova2i(out8(i)) .ne. 1) stop 140 endif end do print *, ' now unpack into 1 64-bit int with g2_gbytesc()...' in8_1(1) = 0 - call g2_gbytesc(out8, in8_1, iskip, 64, 0, 1) + call g2_gbytesc8(out8, in8_1, iskip, 64, 0, 1) if (in8_1(1) .ne. in8(1)) stop 150 - print *, ' testing g2_sbytec() with 32-bit int array of size 4...' + print *, ' testing g2_sbytec8() with 32-bit int array of size 4...' do i = 1, 4 in44(i) = 1 end do @@ -229,9 +241,9 @@ program test_gbytec out16(i) = char(0) end do call g2_sbytesc(out16, in44, iskip, 32, 0, 4) - do i = 1, 16 - print '(i3, x, z2.2)', i, out16(i) - end do + ! do i = 1, 16 + ! print '(i3, x, z2.2)', i, out16(i) + ! end do print *, ' now unpack into 4 32-bit ints with g2_gbytesc()...' do i = 1, 4 @@ -242,25 +254,51 @@ program test_gbytec if (in44_1(i) .ne. in44(i)) stop 160 end do - print *, ' testing g2_sbytec() with 64-bit int array of size 4...' + print *, ' testing g2_sbytec8() with 64-bit int array of size 4...' do i = 1, 4 in84(i) = 1 end do do i = 1, 32 out32(i) = char(0) end do - print *, in84 - call g2_sbytesc(out32, in84, iskip, 64, 0, 4) - do i = 1, 32 - print '(i3, x, z2.2)', i, out32(i) - end do + !print *, in84 + call g2_sbytesc8(out32, in84, iskip, 64, 0, 4) + ! do i = 1, 32 + ! print '(i3, x, z2.2)', i, out32(i) + ! end do - print *, ' now unpack into 4 64-bit ints with g2_gbytesc()...' + print *, ' now unpack into 4 64-bit ints with g2_gbytesc8()...' do i = 1, 4 in84_1(i) = 0 end do - call g2_gbytesc(out32, in84_1, iskip, 64, 0, 4) - print *, in84_1 + call g2_gbytesc8(out32, in84_1, iskip, 64, 0, 4) + !print *, in84_1 + do i = 1, 4 + if (in84_1(i) .ne. in84(i)) stop 200 + end do + + print *, ' testing g2_sbytec8() with very large 64-bit int...' + ! largest 4 byte signed int, plus 1. + in8(1) = 2147483647_8 + 1_8 + print '(z16.16)', in8(1) + do i = 1, 8 + out8(i) = char(0) + end do + call g2_sbytec8(out8, in8, iskip, 64) + do i = 1, 8 + print '(z2.2)', out8(i) + if (i .eq. 5) then + if (mova2i(out8(i)) .ne. 128) stop 210 + else + if (mova2i(out8(i)) .ne. 0) stop 210 + endif + end do + + print *, ' now unpack into 1 64-bit int with g2_gbytesc8()...' + in8_1(1) = 0 + call g2_gbytesc8(out8, in8_1, iskip, 64, 0, 1) + !print *, in8_1 + if (in8_1(1) .ne. in8(1)) stop 150 print *, 'SUCCESS!'