NCEPLIBS-w3emc  2.11.0
w3ai00.f
Go to the documentation of this file.
1 C> @file
2 C> @brief Real array to 16 bit packed format.
3 C> @author Ralph Jones @date 1985-07-31
4 
5 C> Converts IEEE floating point numbers to 16 bit
6 C> packed office note 84 format. The floating point number are
7 C> converted to 16 bit signed scaled integers.
8 C>
9 C> Program history log:
10 C> - Ralph Jones 1989-10-20 Convert cyber 205 version of w3ai00 to cray.
11 C> - Ralph Jones 1990-03-18 Change to use cray integer*2 packer.
12 C> - Ralph Jones 1990-10-11 Special version to pack grids larger than
13 C> 32743 words. Will do old and new version.
14 C> - Ralph Jones 1991-02-16 Changes so equivalence of pack and real8
15 C> arrays will work.
16 C> - Ralph Jones 1993-06-10 Changes for array size (512,512) 262144 words.
17 C> - Boi Vuong 1998-03-10 Remove the cdir$ integer=64 directive.
18 C> - Stephen Gilbert 1998-11-18 Changed to pack IEEE values for the IBM SP
19 C>
20 C> @param[in] REAL8 Array of cray floating point numbers.
21 C> @param[in] LABEL Six 8-byte integer words. Must have first 8 of 12 32 bit
22 C> word office note 84 label. word 6 must have in bits 31-00 the number of
23 C> real words in array real8 if j is greater than 32743.
24 C> j in bits 15-0 of the 4th id word is set zero.
25 C> @param[out] PACK Packed output array of integer words of size 6 + (j+3)/4 ,
26 C> j = no. points in label (from word 4 bits 15-00). Label will be copied to pack words 1-4.
27 C> - Pack will contain the following in words 5-6:
28 C> - word 5 bits 63-48 Number of bytes in whole record. will not be correct if j > 32743.
29 C> - word 5 bits 47-32 Exclusive-or checksum by 16 bit words of whole array pack excluding checksum itself.
30 C> - word 5 bits 31-00 Center value a = mean of max and min values. converted to ibm 32 floating point number.
31 C> - word 6 bits 63-48 Zero.
32 C> - word 6 bits 47-32 16 bit shift value n. the least integer such that abs(x-a)/2**n lt 1 for all x in real8. limited to +-127.
33 C> - word 6 bits 31-00 Number of words in real8 if > 32743, right adjusted if <= 32743 set zero.
34 C>
35 C> @note Pack and label may be equivalenced. n, the number of points
36 C> in a grid is now in 32 bit id word 12.
37 C>
38 C> @author Ralph Jones @date 1985-07-31
39  SUBROUTINE w3ai00(REAL8,PACK,LABEL)
40 C
41  REAL REAL8(*)
42  REAL XX(262144)
43 C
44  INTEGER(8) KK(262144)
45  INTEGER(8) LABEL(6)
46  INTEGER(8) PACK(*)
47  INTEGER(8) TPACK(6)
48  INTEGER(8) MASK16,MASK32,MASKN,IBYTES,IXOR
49  INTEGER(8) IB,N
50  REAL(8) B
51  REAL(4) X,A
52  real(4) rtemp(2)
53  integer(8) irtemp
54  equivalence(irtemp,rtemp(1))
55 C
56  SAVE
57 C
58  equivalence(b,ib)
59 C
60  DATA mask16/z'000000000000FFFF'/
61  DATA mask32/z'00000000FFFFFFFF'/
62  DATA maskn /z'0000FFFF00000000'/
63 C
64 C TRANSFER LABEL DATA TO WORDS 1-4. GET WORD COUNT, COMPUTE BYTES.
65 C
66  DO 10 i = 1,4
67  tpack(i) = label(i)
68  10 CONTINUE
69 C
70  tpack(5) = 0
71  tpack(6) = 0
72 C
73 C GET J, THE NUMBER OF WORDS IN A GRID, IF ZERO GET THE
74 C GET J FROM OFFICE NOTE 84 ID WORD 12.
75 C
76  j = iand(mask16,tpack(4))
77  IF (j.EQ.0) THEN
78  tpack(6) = label(6)
79  j = iand(mask32,tpack(6))
80  IF (j.EQ.0) THEN
81  print *,' W3AI00: ERROR, NO. OF WORDS IN GRID = 0'
82  RETURN
83  ENDIF
84  IF (j.GT.262144) THEN
85  print *,' W3AI00: ERROR, NO. OF WORDS IN GRID = ',j
86  print *,' THERE IS A LIMIT OF 262144 WORDS.'
87  RETURN
88  ENDIF
89  ENDIF
90  m = j + 24
91 C
92 C COMPUTE THE NUMBER OF 64 BIT INTEGER CRAY WORDS NEEDED FOR
93 C PACKED DATA.
94 C
95  IF (mod(m,4).NE.0) THEN
96  iword = (m + 3) / 4
97  ELSE
98  iword = m / 4
99  ENDIF
100 C
101  ibytes = m + m
102 C
103 C STORE NUMBER OF BYTES IN RECORD IN BITS 63-48 OF WORD 5.
104 C BITS ARE NUMBERED LEFT TO RIGHT 63 T0 00
105 C
106  tpack(5) = ishft(ibytes,48_8)
107 C
108 C FIND MAX, MIN OF DATA, COMPUTE A AND N.
109 C
110  rmax = real8(1)
111  rmin = rmax
112  DO 20 i = 2,j
113  rmax = amax1(rmax,real8(i))
114  rmin = amin1(rmin,real8(i))
115  20 CONTINUE
116 C
117  a = 0.5 * (rmax + rmin)
118  x = rmax - a
119  IF (rmax.NE.rmin) THEN
120 C CALL USDCTI(X,B,1,1,ISTAT)
121  CALL q9e3i6(x,b,1,istat)
122  IF (istat.NE.0) print *,' W3AI00-USDCTI OVERFLOW ERROR 1'
123  n = iand(ishft(ib,-56_8),127_8)
124  n = 4 * (n - 64)
125  IF (btest(ib,55_8)) GO TO 30
126  n = n - 1
127  IF (btest(ib,54_8)) GO TO 30
128  n = n - 1
129  IF (btest(ib,53_8)) GO TO 30
130  n = n - 1
131  30 CONTINUE
132  n = max(-127_8,min(127_8,n))
133  ELSE
134 C
135 C FIELD IS ZERO OR A CONSTANT
136 C
137  n = 0
138  ENDIF
139 C
140 C CONVERT AVERAGE VALUE FROM IEEE F.P. TO IBM370 32 BIT
141 C STORE IBM370 32 BIT F.P. AVG. VALUE IN BITS 31 - 00 OF WORD 5.
142 C
143 C CALL USSCTI(A,TPACK(5),5,1,ISTAT)
144  CALL q9ei32(a,rtemp(2),1,istat)
145  IF (istat.NE.0) print *,' W3AI00-USDCTI OVERFLOW ERROR 2'
146  tpack(5)=ior(tpack(5),irtemp)
147 C
148 C STORE SCALING VALUE N IN BITS 47 - 32 OF WORD 6.
149 C
150  tpack(6) = ior(iand(maskn,ishft(n,32_8)),tpack(6))
151 C
152 C NOW PACK UP THE DATA, AND SCALE IT TO FIT AN INTEGER*2 WORD
153 C
154  twon = 2.0 ** (15 - n)
155  DO 40 i = 1,j
156  xx(i) = (real8(i) - a) * twon
157  kk(i) = xx(i) + sign(0.5,xx(i))
158  IF (kk(i).GE.(-32767)) THEN
159  kk(i) = min(32767_8,kk(i))
160  ELSE
161  kk(i) = -32767
162  ENDIF
163  kk(i) = iand(kk(i),mask16)
164  40 CONTINUE
165 C
166 C SHIFT THE INTEGER*2 DATA TO FIT 4 IN A 64 BIT WORD
167 C
168  lim = (j / 4 ) * 4
169  irem = j - lim
170  DO 50 i = 1,lim,4
171  kk(i) = ishft(kk(i), 48_8)
172  kk(i+1) = ishft(kk(i+1),32_8)
173  kk(i+2) = ishft(kk(i+2),16_8)
174  50 CONTINUE
175 C
176 C SHIFT THE REMAINING 1, 2, OR 3 INTEGER*2 WORDS
177 C
178  IF (irem.EQ.1) THEN
179  kk(lim+1) = ishft(kk(lim+1),48_8)
180  ENDIF
181 C
182  IF (irem.EQ.2) THEN
183  kk(lim+1) = ishft(kk(lim+1),48_8)
184  kk(lim+2) = ishft(kk(lim+2),32_8)
185  ENDIF
186 C
187  IF (irem.EQ.3) THEN
188  kk(lim+1) = ishft(kk(lim+1),48_8)
189  kk(lim+2) = ishft(kk(lim+2),32_8)
190  kk(lim+3) = ishft(kk(lim+3),16_8)
191  ENDIF
192 C
193 C PACK THE DATA BY USE OF IOR FOUR TO A WORD
194 C
195  ii = 7
196  DO 60 i = 1,lim,4
197  pack(ii) = ior(ior(ior(kk(i),kk(i+1)),kk(i+2)),kk(i+3))
198  ii = ii + 1
199  60 CONTINUE
200 C
201 C PACK THE LAST 1, 2, OR 3 INTEGER*2 WORDS
202 C
203  IF (irem.EQ.1) THEN
204  pack(iword) = kk(lim+1)
205  ENDIF
206 C
207  IF (irem.EQ.2) THEN
208  pack(iword) = ior(kk(i),kk(i+1))
209  ENDIF
210 C
211  IF (irem.EQ.3) THEN
212  pack(iword) = ior(ior(kk(i),kk(i+1)),kk(i+2))
213  ENDIF
214 C
215 C MOVE LABEL FROM TEMPORARY ARRAY TO PACK
216 C
217  DO 70 i = 1,6
218  pack(i) = tpack(i)
219  70 CONTINUE
220 C
221 C COMPUTE CHECKSUM AND STORE
222 C
223  ixor = 0
224 C
225 C COMPUTES A 64 BIT CHECKSUM 1ST
226 C
227  DO 80 i = 1,iword
228  ixor = ieor(ixor,pack(i))
229  80 CONTINUE
230 C
231 C COMPUTES A 32 BIT CHECKSUM 2ND
232 C
233  ixor = ieor(ishft(ixor,-32_8),iand(ixor,mask32))
234 C
235 C COMPUTES A 16 BIT CHECKSUM 3RD
236 C
237  ixor = ieor(ishft(ixor,-16_8),iand(ixor,mask16))
238 C
239 C STORE 16 BIT CHECK SUM OF RECORD IN BITS 47-32 OF WORD 5.
240 C
241  pack(5) = ior(ishft(ixor,32_8),pack(5))
242 C
243  RETURN
244  END
245 
246 
247 C> Convert IEEE 32 bit task 754 floating point numbers
248 C> to IBM370 32 bit floating point numbers.
249 C>
250 C> Program history log:
251 C> - Ralph Jones 1990-06-04 Convert to sun fortran 1.3.
252 C> - Ralph Jones 1990-07-14 Change ishft to lshift or lrshft.
253 C> - Ralph Jones 1991-03-28 Change to silicongraphics 3.3 fortran 77.
254 C> - Ralph Jones 1992-07-20 Change to ibm aix xl fortran.
255 C> - Ralph Jones 1995-11-15 Add save statement.
256 C> - Stepen Gilbert 1998-11-18 Specified 4-byte Integer values.
257 C>
258 C> @param[in] A - Real*4 array of IEEE 32 bit floating point numbers.
259 C> @param[in] N - Number of words to convert to IBM370 32 bit F.P.
260 C> @param[out] B - Real*4 array of IBM370 32 bit floating point numbers.
261 C> @param[out] ISTAT:
262 C> - 0: All numbers converted.
263 C> - -1: N is less than one.
264 C> - +K: K infinity or nan numbers were found.
265 C>
266 C> @note See IEEE task 754 standard floating point arithmetic for
267 C> more information about IEEE F.P.
268 C>
269 C> @author Ralph Jones @date 1990-06-04
270  SUBROUTINE q9ei32(A,B,N,ISTAT)
271 C
272  INTEGER(4) A(*)
273  INTEGER(4) B(*)
274  INTEGER(4) SIGN,MASKFR,IBIT8,MASKSN,ITEMP,IBMEXP,IBX7
275  INTEGER(4) ISIGN
276 C
277  SAVE
278 C
279  DATA maskfr/z'00FFFFFF'/
280  DATA ibit8 /z'00800000'/
281  DATA masksn/z'7FFFFFFF'/
282  DATA sign /z'80000000'/
283 C
284  IF (n.LT.1) THEN
285  istat = -1
286  RETURN
287  ENDIF
288 C
289  istat = 0
290 C
291  DO 30 i = 1,n
292 C
293 C SIGN BIT OFF
294 C
295  isign = 0
296  itemp = a(i)
297 C
298 C TEST SIGN BIT
299 C
300  IF (itemp.EQ.0) GO TO 20
301 C
302  IF (itemp.LT.0) THEN
303 C
304 C SIGN BIT ON
305 C
306  isign = sign
307 C
308 C TURN SIGN BIT OFF
309 C
310  itemp = iand(itemp,masksn)
311 C
312  END IF
313 C
314  ibmexp = ishft(itemp,-23_4)
315 C
316 C TEST FOR INDIFINITE OR NAN NUMBER
317 C
318  IF (ibmexp.EQ.255) GO TO 10
319 C
320 C TEST FOR ZERO EXPONENT AND FRACTION (UNDERFLOW)
321 C
322  IF (ibmexp.EQ.0) GO TO 20
323  ibmexp = ibmexp + 133
324  ibx7 = iand(3_4,ibmexp)
325  ibmexp = ieor(ibmexp,ibx7)
326  ibx7 = ieor(3_4,ibx7)
327  itemp = ior(itemp,ibit8)
328  itemp = ior(ishft(ibmexp,22_4),ishft(iand(itemp,maskfr),
329  & -ibx7))
330  b(i) = ior(itemp,isign)
331  GO TO 30
332 C
333  10 CONTINUE
334 C
335 C ADD 1 TO ISTAT FOR INDEFINITE OR NAN NUMBER
336 C
337  istat = istat + 1
338 C
339  20 CONTINUE
340  b(i) = 0
341 C
342  30 CONTINUE
343 C
344  RETURN
345  END
346 
347 C> Convert ieee 32 bit task 754 floating point numbers
348 C> to ibm370 64 bit floating point numbers.
349 C>
350 C> Program history log:
351 C> - Ralph Jones 1992-08-02
352 C> - Ralph Jones 1995-11-15 Add save statement.
353 C>
354 C> @param[in] A Real*4 array of IEEE 32 bit floating point numbers.
355 C> @param[in] N Number of words to convert to IBM370 64 bit F.P.
356 C> @param[out] B Real*8 array of IBM370 64 bit floating point numbers.
357 C> @param[out] ISTAT
358 C> - 0 All numbers converted.
359 C> - -1 N is less than one.
360 C> - +K K infinity or nan numbers were found.
361 C>
362 C> @note See IEEE task 754 standard floating point arithmetic for
363 C> more information about IEEE F.P.
364 C>
365 C> @author Ralph Jones @date 1992-08-02
366  SUBROUTINE q9e3i6(A,B,N,ISTAT)
367 
368 C
369  INTEGER(4) A(N)
370  INTEGER(4) B(2,N)
371  INTEGER(4) SIGN,MASKFR,IBIT8,MASKSN,ITEMP,IEEEXP
372  INTEGER(4) IBMEXP,IBX7,JTEMP,ISIGN
373 C
374  SAVE
375 C
376  DATA maskfr/z'00FFFFFF'/
377  DATA ibit8 /z'00800000'/
378  DATA masksn/z'7FFFFFFF'/
379  DATA sign /z'80000000'/
380 C
381  IF (n.LT.1) THEN
382  istat = -1
383  RETURN
384  ENDIF
385 C
386  istat = 0
387 C
388  DO 30 i = 1,n
389  isign = 0
390  itemp = a(i)
391 C
392 C TEST SIGN BIT
393 C
394  IF (itemp.EQ.0) GO TO 20
395 C
396 C TEST FOR NEGATIVE NUMBERS
397 C
398  IF (itemp.LT.0) THEN
399 C
400 C SIGN BIT ON
401 C
402  isign = sign
403 C
404 C TURN SIGN BIT OFF
405 C
406  itemp = iand(itemp,masksn)
407 C
408  END IF
409 C
410 C GET IEEE EXPONENT
411 C
412  ieeexp = ishft(itemp,-23_4)
413 C
414 C TEST FOR INDIFINITE OR NAN NUMBER
415 C
416  IF (ieeexp.EQ.255) GO TO 10
417 C
418 C TEST FOR ZERO EXPONENT AND FRACTION (UNDERFLOW)
419 C CONVERT IEEE EXPONENT (BASE 2) TO IBM EXPONENT
420 C (BASE 16)
421 C
422  IF (ieeexp.EQ.0) GO TO 20
423  ibmexp = ieeexp + 133
424  ibx7 = iand(3_4,ibmexp)
425  ibmexp = ieor(ibmexp,ibx7)
426  ibx7 = ieor(3_4,ibx7)
427  itemp = ior(itemp,ibit8)
428  jtemp = ior(ishft(ibmexp,22_4),ishft(iand(itemp,maskfr),
429  & -ibx7))
430  b(1,i) = ior(jtemp,isign)
431  b(2,i) = 0
432  IF (ibx7.GT.0) b(2,i) = ishft(itemp,32_4-ibx7)
433  GO TO 30
434 C
435  10 CONTINUE
436 C ADD 1 TO ISTAT FOR INDEFINITE OR NAN NUMBER
437 C
438  istat = istat + 1
439 C
440  20 CONTINUE
441  b(1,i) = 0
442  b(2,i) = 0
443 C
444  30 CONTINUE
445 C
446  RETURN
447  END
subroutine w3ai00(REAL8, PACK, LABEL)
Converts IEEE floating point numbers to 16 bit packed office note 84 format.
Definition: w3ai00.f:40
subroutine q9e3i6(A, B, N, ISTAT)
Convert ieee 32 bit task 754 floating point numbers to ibm370 64 bit floating point numbers.
Definition: w3ai00.f:367
subroutine q9ei32(A, B, N, ISTAT)
Convert IEEE 32 bit task 754 floating point numbers to IBM370 32 bit floating point numbers.
Definition: w3ai00.f:271