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