-
Notifications
You must be signed in to change notification settings - Fork 17
/
Copy pathintmath.F90
268 lines (256 loc) · 7.51 KB
/
intmath.F90
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
!> @file
!> @brief Define math functions used by compack(),
!> simpack(), and misspack().
!> @author Stephen Gilbert @date 2000-06-21
!> @brief Define math functions used by compack(),
!> simpack(), and misspack().
!>
!> This module includes the following functions:
!> - ilog2 Calculate log(x)/log(2).
!> - ilog2_8 for 8 bit integer numbers.
!> - ilog2_4 for 4 bit integer numbers.
!> - ilog2_2 for 2 bit integer numbers.
!> - ilog2_1 for 1 bit integer numbers.
!> - i1log2 Calculate log(x+1)/log(2) unless x=maxint, in which case log(x)/log(2).
!> - i1log2_8 for 8 bit integer numbers.
!> - i1log2_4 for 4 bit integer numbers.
!> - i1log2_2 for 2 bit integer numbers.
!> - i1log2_1 for 1 bit integer numbers.
!>
!> @author Stephen Gilbert @date 2000-06-21
module intmath
implicit none
interface ilog2
! log(x)/log(2)
module procedure ilog2_8
module procedure ilog2_4
module procedure ilog2_2
module procedure ilog2_1
end interface ilog2
interface i1log2
! log(x+1)/log(2) unless x=maxint, in which case log(x)/log(2)
module procedure i1log2_8
module procedure i1log2_4
module procedure i1log2_2
module procedure i1log2_1
end interface i1log2
contains
!> This function returns log(x+1)/log(2) unless x=maxint, in
!> which case log(x)/log(2) for 8 bit integer numbers.
!> @param[in] ival 8 bit integer numbers.
!> @return value for log(x+1)/log(2)
!> @author Stephen Gilbert @date 2000-06-21
function i1log2_8(ival)
implicit none
integer(kind=8), value :: ival
integer(kind=8)::i1log2_8
integer(kind=8), parameter :: one=1
if(ival+one<ival) then
i1log2_8=ilog2_8(ival)
else
i1log2_8=ilog2_8(ival+one)
endif
end function i1log2_8
!> This function returns log(x+1)/log(2) unless x=maxint, in
!> which case log(x)/log(2) for 4 bit integer numbers.
!> @param[in] ival 4 bit integer numbers.
!> @return value for log(x+1)/log(2)
!> @author Stephen Gilbert @date 2000-06-21
function i1log2_4(ival)
implicit none
integer(kind=4), value :: ival
integer(kind=4)::i1log2_4
integer(kind=4), parameter :: one=1
if(ival+one<ival) then
i1log2_4=ilog2_4(ival)
else
i1log2_4=ilog2_4(ival+one)
endif
end function i1log2_4
!> This function returns log(x+1)/log(2) unless x=maxint, in
!> which case log(x)/log(2) for 2 bit integer numbers.
!> @param[in] ival 2 bit integer numbers.
!> @return value for log(x+1)/log(2)
!> @author Stephen Gilbert @date 2000-06-21
function i1log2_2(ival)
implicit none
integer(kind=2), value :: ival
integer(kind=2)::i1log2_2
integer(kind=2), parameter :: one = 1_2
if(ival+one<ival) then
i1log2_2=ilog2_2(ival)
else
i1log2_2=ilog2_2(ival+one)
endif
end function i1log2_2
!> This function returns log(x+1)/log(2) unless x=maxint, in
!> which case log(x)/log(2) for 1 bit integer numbers.
!> @param[in] ival 1 bit integer numbers.
!> @return value for log(x+1)/log(2)
!> @author Stephen Gilbert @date 2000-06-21
function i1log2_1(ival)
implicit none
integer(kind=1), value :: ival
integer(kind=1)::i1log2_1
integer(kind=1), parameter :: one = 1_1
if(ival+one<ival) then
i1log2_1=ilog2_1(ival)
else
i1log2_1=ilog2_1(ival+one)
endif
end function i1log2_1
!> This function returns log(x)/log(2) for 8 bit integer numbers.
!> @param[in] i_in 8 bit integer numbers.
!> @return value for log(x)/log(2)
!> @author Stephen Gilbert @date 2000-06-21
function ilog2_8(i_in)
implicit none
integer(kind=8), value :: i_in
integer(kind=8)::ilog2_8,i
ilog2_8=0
i=i_in
if(i<=0) return
if(iand(i,i-1)/=0) then
!write(0,*) 'iand i-1'
ilog2_8=1
endif
if(iand(i,Z'FFFFFFFF00000000')/=0) then
ilog2_8=ilog2_8+32
i=ishft(i,-32)
!write(0,*) 'iand ffffffff',i,ilog2_8
endif
if(iand(i,Z'00000000FFFF0000')/=0) then
ilog2_8=ilog2_8+16
i=ishft(i,-16)
!write(0,*) 'iand ffff' ,i,ilog2_8
endif
if(iand(i,Z'000000000000FF00')/=0) then
ilog2_8=ilog2_8+8
i=ishft(i,-8)
!write(0,*) 'iand ff',i,ilog2_8
endif
if(iand(i,Z'00000000000000F0')/=0) then
ilog2_8=ilog2_8+4
i=ishft(i,-4)
!write(0,*) 'iand f',i,ilog2_8
endif
if(iand(i,Z'000000000000000C')/=0) then
ilog2_8=ilog2_8+2
i=ishft(i,-2)
!write(0,*) 'iand c',i,ilog2_8
endif
if(iand(i,Z'0000000000000002')/=0) then
ilog2_8=ilog2_8+1
i=ishft(i,-1)
!write(0,*) 'iand 2',i,ilog2_8
endif
end function ilog2_8
!> This function returns log(x)/log(2) for 4 bit integer numbers.
!> @param[in] i_in 4 bit integer numbers.
!> @return value for log(x)/log(2)
!> @author Stephen Gilbert @date 2000-06-21
function ilog2_4(i_in)
implicit none
integer(kind=4), value :: i_in
integer(kind=4)::ilog2_4,i
ilog2_4=0
i=i_in
if(i<=0) return
if(iand(i,i-1)/=0) then
!write(0,*) 'iand i-1'
ilog2_4=1
endif
if(iand(i,Z'FFFF0000')/=0) then
ilog2_4=ilog2_4+16
i=ishft(i,-16)
!write(0,*) 'iand ffff' ,i,ilog2_4
endif
if(iand(i,Z'0000FF00')/=0) then
ilog2_4=ilog2_4+8
i=ishft(i,-8)
!write(0,*) 'iand ff',i,ilog2_4
endif
if(iand(i,Z'000000F0')/=0) then
ilog2_4=ilog2_4+4
i=ishft(i,-4)
!write(0,*) 'iand f',i,ilog2_4
endif
if(iand(i,Z'0000000C')/=0) then
ilog2_4=ilog2_4+2
i=ishft(i,-2)
!write(0,*) 'iand c',i,ilog2_4
endif
if(iand(i,Z'00000002')/=0) then
ilog2_4=ilog2_4+1
i=ishft(i,-1)
!write(0,*) 'iand 2',i,ilog2_4
endif
end function ilog2_4
!> This function returns log(x)/log(2) for 2 bit integer numbers.
!> @param[in] i_in 2 bit integer numbers.
!> @return value for log(x)/log(2)
!> @author Stephen Gilbert @date 2000-06-21
function ilog2_2(i_in)
implicit none
integer(kind=2), value :: i_in
integer(kind=2)::ilog2_2,i
ilog2_2 = 0_2
i=i_in
if(i<=0) return
if(iand(i,int(i-1,kind=2))/=0) then
!write(0,*) 'iand i-1'
ilog2_2 = 1_2
endif
if(iand(i,Z'FF00')/=0) then
ilog2_2 = ilog2_2 + 8_2
i=ishft(i,-8)
!write(0,*) 'iand ff',i,ilog2_2
endif
if(iand(i,Z'00F0')/=0) then
ilog2_2 = ilog2_2 + 4_2
i=ishft(i,-4)
!write(0,*) 'iand f',i,ilog2_2
endif
if(iand(i,Z'000C')/=0) then
ilog2_2 = ilog2_2 + 2_2
i=ishft(i,-2)
!write(0,*) 'iand c',i,ilog2_2
endif
if(iand(i,Z'0002')/=0) then
ilog2_2 = ilog2_2 + 1_2
i=ishft(i,-1)
!write(0,*) 'iand 2',i,ilog2_2
endif
end function ilog2_2
!> This function returns log(x)/log(2) for 1 bit integer numbers.
!> @param[in] i_in 1 bit integer numbers.
!> @return value for log(x)/log(2)
!> @author Stephen Gilbert @date 2000-06-21
function ilog2_1(i_in)
implicit none
integer(kind=1), value :: i_in
integer(kind=1)::ilog2_1,i
ilog2_1 = 0_1
i=i_in
if(i<=0) return
if(iand(i,int(i-1,kind=1))/=0) then
!write(0,*) 'iand i-1'
ilog2_1 = 1_1
endif
if(iand(i,Z'F0')/=0) then
ilog2_1 = ilog2_1 + 4_1
i=ishft(i,-4)
!write(0,*) 'iand f',i,ilog2_1
endif
if(iand(i,Z'0C')/=0) then
ilog2_1 = ilog2_1 + 2_1
i=ishft(i,-2)
!write(0,*) 'iand c',i,ilog2_1
endif
if(iand(i,Z'02')/=0) then
ilog2_1 = ilog2_1 + 1_1
i=ishft(i,-1)
!write(0,*) 'iand 2',i,ilog2_1
endif
end function ilog2_1
end module intmath