MCPcopy
hub / github.com/pandas-dev/pandas / _parse_float_vec

Function _parse_float_vec

pandas/io/sas/sas_xport.py:179–233  ·  view source on GitHub ↗

Parse a vector of float values representing IBM 8 byte floats into native 8 byte floats.

(vec)

Source from the content-addressed store, hash-verified

177
178
179def _parse_float_vec(vec):
180 """
181 Parse a vector of float values representing IBM 8 byte floats into
182 native 8 byte floats.
183 """
184 dtype = np.dtype(">u4,>u4")
185 vec1 = vec.view(dtype=dtype)
186 xport1 = vec1["f0"]
187 xport2 = vec1["f1"]
188
189 # Start by setting first half of ieee number to first half of IBM
190 # number sans exponent
191 ieee1 = xport1 & 0x00FFFFFF
192
193 # The fraction bit to the left of the binary point in the ieee
194 # format was set and the number was shifted 0, 1, 2, or 3
195 # places. This will tell us how to adjust the ibm exponent to be a
196 # power of 2 ieee exponent and how to shift the fraction bits to
197 # restore the correct magnitude.
198 shift = np.zeros(len(vec), dtype=np.uint8)
199 shift[np.where(xport1 & 0x00200000)] = 1
200 shift[np.where(xport1 & 0x00400000)] = 2
201 shift[np.where(xport1 & 0x00800000)] = 3
202
203 # shift the ieee number down the correct number of places then
204 # set the second half of the ieee number to be the second half
205 # of the ibm number shifted appropriately, ored with the bits
206 # from the first half that would have been shifted in if we
207 # could shift a double. All we are worried about are the low
208 # order 3 bits of the first half since we're only shifting by
209 # 1, 2, or 3.
210 ieee1 >>= shift
211 ieee2 = (xport2 >> shift) | ((xport1 & 0x00000007) << (29 + (3 - shift)))
212
213 # clear the 1 bit to the left of the binary point
214 ieee1 &= 0xFFEFFFFF
215
216 # set the exponent of the ieee number to be the actual exponent
217 # plus the shift count + 1023. Or this into the first half of the
218 # ieee number. The ibm exponent is excess 64 but is adjusted by 65
219 # since during conversion to ibm format the exponent is
220 # incremented by 1 and the fraction bits left 4 positions to the
221 # right of the radix point. (had to add >> 24 because C treats &
222 # 0x7f as 0x7f000000 and Python doesn't)
223 ieee1 |= ((((((xport1 >> 24) & 0x7F) - 65) << 2) + shift + 1023) << 20) | (
224 xport1 & 0x80000000
225 )
226
227 ieee = np.empty((len(ieee1),), dtype=">u4,>u4")
228 ieee["f0"] = ieee1
229 ieee["f1"] = ieee2
230 ieee = ieee.view(dtype=">f8")
231 ieee = ieee.astype("f8")
232
233 return ieee
234
235
236class XportReader(SASReader):

Callers 1

readMethod · 0.85

Calls 5

dtypeMethod · 0.45
viewMethod · 0.45
whereMethod · 0.45
emptyMethod · 0.45
astypeMethod · 0.45

Tested by

no test coverage detected