      SUBROUTINE W3FI58(IFIELD,NPTS,NWORK,NPFLD,NBITS,LEN,KMIN)
C$$$  SUBPROGRAM DOCUMENTATION BLOCK  ***
C                .      .    .                                       .
C SUBPROGRAM:  W3FI58   - PACK POSITIVE DIFFERENCES IN LEAST BITS
C   PRGMMR:  ALLARD, R.       ORG:  NMC411        DATE:  JULY 1987
C
C ABSTRACT:  CONVERTS AN ARRAY OF INTEGER NUMBERS INTO AN ARRAY OF
C   POSITIVE DIFFERENCES (NUMBER(S) - MINIMUM VALUE) AND PACKS THE
C   MAGNITUDE OF EACH DIFFERENCE RIGHT-ADJUSTED INTO THE LEAST
C   NUMBER OF BITS THAT HOLDS THE LARGEST DIFFERENCE.
C
C PROGRAM HISTORY LOG:
C   87-09-02  ALLARD
C   88-10-02  R.E.JONES   CONVERTED TO CDC CYBER 205 FTN200 FORTRAN
C   90-05-17  R.E.JONES   CONVERTED TO CRAY CFT77 FORTRAN
C   90-05-18  R.E.JONES   CHANGE NAME VBIMPK TO W3LIB NAME W3FI58
C   96-05-14  IREDELL     GENERALIZED COMPUTATION OF NBITS
C   98-06-30  EBISUZAKI   LINUX PORT
C
C USAGE:  CALL W3FI58(IFIELD,NPTS,NWORK,NPFLD,NBITS,LEN,KMIN)
C
C   INPUT:
C
C     IFIELD - ARRAY OF INTEGER DATA FOR PROCESSING
C     NPTS   - NUMBER OF DATA VALUES TO PROCESS IN IFIELD (AND NWORK)
C              WHERE, NPTS > 0
C
C   OUTPUT:
C
C     NWORK  - WORK ARRAY WITH INTEGER DIFFERENCE
C     NPFLD  - ARRAY FOR PACKED DATA (character*1)
C              (USER IS RESPONSIBLE FOR AN ADEQUATE DIMENSION.)
C     NBITS  - NUMBER OF BITS USED TO PACK DATA WHERE, 0 < NBITS < 32
C              (THE MAXIMUM DIFFERENCE WITHOUT OVERFLOW IS 2**31 -1)
C     LEN    - NUMBER OF PACKED BYTES IN NPFLD (SET TO 0 IF NO PACKING)
C              WHERE, LEN = (NBITS * NPTS + 7) / 8 WITHOUT REMAINDER
C     KMIN   - MINIMUM VALUE (SUBTRACTED FROM EACH DATUM). IF THIS
C              PACKED DATA IS BEING USED FOR GRIB DATA, THE
C              PROGRAMER WILL HAVE TO CONVERT THE KMIN VALUE TO AN
C              IBM370 32 BIT FLOATING POINT NUMBER.
C
C   SUBPROGRAMS CALLED:
C
C     W3LIB:  SBYTES, SBYTE
C
C   EXIT STATES:  NONE
C
C     NOTE:  LEN = 0, NBITS = 0, AND NO PACKING PERFORMED IF
C
C     (1) KMAX = KMIN  (A CONSTANT FIELD)
C     (2) NPTS < 1  (SEE INPUT ARGUMENT)
C
C ATTRIBUTES:
C   LANGUAGE: CRAY CFT77 FORTRAN
C   MACHINE:  CRAY Y-MP8/832
C
C$$$
C
      PARAMETER(ALOG2=0.69314718056)
      INTEGER  IFIELD(*)
      CHARACTER*1  NPFLD(*)
      INTEGER  NWORK(*)
C
      DATA  KZERO / 0 /
C
C / / / / / /
C
      LEN   = 0
      NBITS = 0
      IF (NPTS.LE.0) GO TO 3000
C
C FIND THE MAX-MIN VALUES IN INTEGER FIELD (IFIELD).
C
      KMAX = IFIELD(1)
      KMIN = KMAX
      DO 1000 I = 2,NPTS
        KMAX = MAX(KMAX,IFIELD(I))
        KMIN = MIN(KMIN,IFIELD(I))
 1000 CONTINUE
C
C IF A CONSTANT FIELD, RETURN WITH NO PACKING AND 'LEN' AND 'NBITS' SET
C TO ZERO.
C
      IF (KMAX.EQ.KMIN) GO TO 3000
C
C DETERMINE LARGEST DIFFERENCE IN IFIELD AND FLOAT (BIGDIF).
C
      BIGDIF = KMAX - KMIN
C
C NBITS IS COMPUTED AS THE LEAST INTEGER SUCH THAT
C   BIGDIF < 2**NBITS
C
      NBITS=LOG(BIGDIF+0.5)/ALOG2+1
C
C FORM DIFFERENCES IN NWORK ARRAY.
C
      DO 2000 K = 1,NPTS
        NWORK(K) = IFIELD(K) - KMIN
 2000 CONTINUE
C
C PACK EACH MAGNITUDE IN NBITS (NBITS = THE LEAST POWER OF 2 OR 'N')
C
      LEN=(NBITS*NPTS-1)/8+1
      CALL SBYTESC(NPFLD,NWORK,0,NBITS,0,NPTS)
C
C ADD ZERO-BITS AT END OF PACKED DATA TO INSURE A BYTE BOUNDARY.
C
      NOFF = NBITS * NPTS
      NZERO=LEN*8-NOFF
      IF(NZERO.GT.0) CALL SBYTEC(NPFLD,KZERO,NOFF,NZERO)
C
 3000 CONTINUE
      RETURN
C
      END
