Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.9/dist-packages/numpy/_core/getlimits.py: 52%

241 statements  

« prev     ^ index     » next       coverage.py v7.4.4, created at 2024-04-09 06:12 +0000

1"""Machine limits for Float32 and Float64 and (long double) if available... 

2 

3""" 

4__all__ = ['finfo', 'iinfo'] 

5 

6import warnings 

7 

8from .._utils import set_module 

9from ._machar import MachAr 

10from . import numeric 

11from . import numerictypes as ntypes 

12from .numeric import array, inf, nan 

13from .umath import log10, exp2, nextafter, isnan 

14 

15 

16def _fr0(a): 

17 """fix rank-0 --> rank-1""" 

18 if a.ndim == 0: 

19 a = a.copy() 

20 a.shape = (1,) 

21 return a 

22 

23 

24def _fr1(a): 

25 """fix rank > 0 --> rank-0""" 

26 if a.size == 1: 

27 a = a.copy() 

28 a.shape = () 

29 return a 

30 

31 

32class MachArLike: 

33 """ Object to simulate MachAr instance """ 

34 def __init__(self, ftype, *, eps, epsneg, huge, tiny, 

35 ibeta, smallest_subnormal=None, **kwargs): 

36 self.params = _MACHAR_PARAMS[ftype] 

37 self.ftype = ftype 

38 self.title = self.params['title'] 

39 # Parameter types same as for discovered MachAr object. 

40 if not smallest_subnormal: 

41 self._smallest_subnormal = nextafter( 

42 self.ftype(0), self.ftype(1), dtype=self.ftype) 

43 else: 

44 self._smallest_subnormal = smallest_subnormal 

45 self.epsilon = self.eps = self._float_to_float(eps) 

46 self.epsneg = self._float_to_float(epsneg) 

47 self.xmax = self.huge = self._float_to_float(huge) 

48 self.xmin = self._float_to_float(tiny) 

49 self.smallest_normal = self.tiny = self._float_to_float(tiny) 

50 self.ibeta = self.params['itype'](ibeta) 

51 self.__dict__.update(kwargs) 

52 self.precision = int(-log10(self.eps)) 

53 self.resolution = self._float_to_float( 

54 self._float_conv(10) ** (-self.precision)) 

55 self._str_eps = self._float_to_str(self.eps) 

56 self._str_epsneg = self._float_to_str(self.epsneg) 

57 self._str_xmin = self._float_to_str(self.xmin) 

58 self._str_xmax = self._float_to_str(self.xmax) 

59 self._str_resolution = self._float_to_str(self.resolution) 

60 self._str_smallest_normal = self._float_to_str(self.xmin) 

61 

62 @property 

63 def smallest_subnormal(self): 

64 """Return the value for the smallest subnormal. 

65 

66 Returns 

67 ------- 

68 smallest_subnormal : float 

69 value for the smallest subnormal. 

70 

71 Warns 

72 ----- 

73 UserWarning 

74 If the calculated value for the smallest subnormal is zero. 

75 """ 

76 # Check that the calculated value is not zero, in case it raises a 

77 # warning. 

78 value = self._smallest_subnormal 

79 if self.ftype(0) == value: 

80 warnings.warn( 

81 'The value of the smallest subnormal for {} type ' 

82 'is zero.'.format(self.ftype), UserWarning, stacklevel=2) 

83 

84 return self._float_to_float(value) 

85 

86 @property 

87 def _str_smallest_subnormal(self): 

88 """Return the string representation of the smallest subnormal.""" 

89 return self._float_to_str(self.smallest_subnormal) 

90 

91 def _float_to_float(self, value): 

92 """Converts float to float. 

93 

94 Parameters 

95 ---------- 

96 value : float 

97 value to be converted. 

98 """ 

99 return _fr1(self._float_conv(value)) 

100 

101 def _float_conv(self, value): 

102 """Converts float to conv. 

103 

104 Parameters 

105 ---------- 

106 value : float 

107 value to be converted. 

108 """ 

109 return array([value], self.ftype) 

110 

111 def _float_to_str(self, value): 

112 """Converts float to str. 

113 

114 Parameters 

115 ---------- 

116 value : float 

117 value to be converted. 

118 """ 

119 return self.params['fmt'] % array(_fr0(value)[0], self.ftype) 

120 

121 

122_convert_to_float = { 

123 ntypes.csingle: ntypes.single, 

124 ntypes.complex128: ntypes.float64, 

125 ntypes.clongdouble: ntypes.longdouble 

126 } 

127 

128# Parameters for creating MachAr / MachAr-like objects 

129_title_fmt = 'numpy {} precision floating point number' 

130_MACHAR_PARAMS = { 

131 ntypes.double: dict( 

132 itype = ntypes.int64, 

133 fmt = '%24.16e', 

134 title = _title_fmt.format('double')), 

135 ntypes.single: dict( 

136 itype = ntypes.int32, 

137 fmt = '%15.7e', 

138 title = _title_fmt.format('single')), 

139 ntypes.longdouble: dict( 

140 itype = ntypes.longlong, 

141 fmt = '%s', 

142 title = _title_fmt.format('long double')), 

143 ntypes.half: dict( 

144 itype = ntypes.int16, 

145 fmt = '%12.5e', 

146 title = _title_fmt.format('half'))} 

147 

148# Key to identify the floating point type. Key is result of 

149# ftype('-0.1').newbyteorder('<').tobytes() 

150# 

151# 20230201 - use (ftype(-1.0) / ftype(10.0)).newbyteorder('<').tobytes() 

152# instead because stold may have deficiencies on some platforms. 

153# See: 

154# https://perl5.git.perl.org/perl.git/blob/3118d7d684b56cbeb702af874f4326683c45f045:/Configure 

155 

156_KNOWN_TYPES = {} 

157def _register_type(machar, bytepat): 

158 _KNOWN_TYPES[bytepat] = machar 

159 

160 

161_float_ma = {} 

162 

163 

164def _register_known_types(): 

165 # Known parameters for float16 

166 # See docstring of MachAr class for description of parameters. 

167 f16 = ntypes.float16 

168 float16_ma = MachArLike(f16, 

169 machep=-10, 

170 negep=-11, 

171 minexp=-14, 

172 maxexp=16, 

173 it=10, 

174 iexp=5, 

175 ibeta=2, 

176 irnd=5, 

177 ngrd=0, 

178 eps=exp2(f16(-10)), 

179 epsneg=exp2(f16(-11)), 

180 huge=f16(65504), 

181 tiny=f16(2 ** -14)) 

182 _register_type(float16_ma, b'f\xae') 

183 _float_ma[16] = float16_ma 

184 

185 # Known parameters for float32 

186 f32 = ntypes.float32 

187 float32_ma = MachArLike(f32, 

188 machep=-23, 

189 negep=-24, 

190 minexp=-126, 

191 maxexp=128, 

192 it=23, 

193 iexp=8, 

194 ibeta=2, 

195 irnd=5, 

196 ngrd=0, 

197 eps=exp2(f32(-23)), 

198 epsneg=exp2(f32(-24)), 

199 huge=f32((1 - 2 ** -24) * 2**128), 

200 tiny=exp2(f32(-126))) 

201 _register_type(float32_ma, b'\xcd\xcc\xcc\xbd') 

202 _float_ma[32] = float32_ma 

203 

204 # Known parameters for float64 

205 f64 = ntypes.float64 

206 epsneg_f64 = 2.0 ** -53.0 

207 tiny_f64 = 2.0 ** -1022.0 

208 float64_ma = MachArLike(f64, 

209 machep=-52, 

210 negep=-53, 

211 minexp=-1022, 

212 maxexp=1024, 

213 it=52, 

214 iexp=11, 

215 ibeta=2, 

216 irnd=5, 

217 ngrd=0, 

218 eps=2.0 ** -52.0, 

219 epsneg=epsneg_f64, 

220 huge=(1.0 - epsneg_f64) / tiny_f64 * f64(4), 

221 tiny=tiny_f64) 

222 _register_type(float64_ma, b'\x9a\x99\x99\x99\x99\x99\xb9\xbf') 

223 _float_ma[64] = float64_ma 

224 

225 # Known parameters for IEEE 754 128-bit binary float 

226 ld = ntypes.longdouble 

227 epsneg_f128 = exp2(ld(-113)) 

228 tiny_f128 = exp2(ld(-16382)) 

229 # Ignore runtime error when this is not f128 

230 with numeric.errstate(all='ignore'): 

231 huge_f128 = (ld(1) - epsneg_f128) / tiny_f128 * ld(4) 

232 float128_ma = MachArLike(ld, 

233 machep=-112, 

234 negep=-113, 

235 minexp=-16382, 

236 maxexp=16384, 

237 it=112, 

238 iexp=15, 

239 ibeta=2, 

240 irnd=5, 

241 ngrd=0, 

242 eps=exp2(ld(-112)), 

243 epsneg=epsneg_f128, 

244 huge=huge_f128, 

245 tiny=tiny_f128) 

246 # IEEE 754 128-bit binary float 

247 _register_type(float128_ma, 

248 b'\x9a\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\x99\xfb\xbf') 

249 _float_ma[128] = float128_ma 

250 

251 # Known parameters for float80 (Intel 80-bit extended precision) 

252 epsneg_f80 = exp2(ld(-64)) 

253 tiny_f80 = exp2(ld(-16382)) 

254 # Ignore runtime error when this is not f80 

255 with numeric.errstate(all='ignore'): 

256 huge_f80 = (ld(1) - epsneg_f80) / tiny_f80 * ld(4) 

257 float80_ma = MachArLike(ld, 

258 machep=-63, 

259 negep=-64, 

260 minexp=-16382, 

261 maxexp=16384, 

262 it=63, 

263 iexp=15, 

264 ibeta=2, 

265 irnd=5, 

266 ngrd=0, 

267 eps=exp2(ld(-63)), 

268 epsneg=epsneg_f80, 

269 huge=huge_f80, 

270 tiny=tiny_f80) 

271 # float80, first 10 bytes containing actual storage 

272 _register_type(float80_ma, b'\xcd\xcc\xcc\xcc\xcc\xcc\xcc\xcc\xfb\xbf') 

273 _float_ma[80] = float80_ma 

274 

275 # Guessed / known parameters for double double; see: 

276 # https://en.wikipedia.org/wiki/Quadruple-precision_floating-point_format#Double-double_arithmetic 

277 # These numbers have the same exponent range as float64, but extended 

278 # number of digits in the significand. 

279 huge_dd = nextafter(ld(inf), ld(0), dtype=ld) 

280 # As the smallest_normal in double double is so hard to calculate we set 

281 # it to NaN. 

282 smallest_normal_dd = nan 

283 # Leave the same value for the smallest subnormal as double 

284 smallest_subnormal_dd = ld(nextafter(0., 1.)) 

285 float_dd_ma = MachArLike(ld, 

286 machep=-105, 

287 negep=-106, 

288 minexp=-1022, 

289 maxexp=1024, 

290 it=105, 

291 iexp=11, 

292 ibeta=2, 

293 irnd=5, 

294 ngrd=0, 

295 eps=exp2(ld(-105)), 

296 epsneg=exp2(ld(-106)), 

297 huge=huge_dd, 

298 tiny=smallest_normal_dd, 

299 smallest_subnormal=smallest_subnormal_dd) 

300 # double double; low, high order (e.g. PPC 64) 

301 _register_type(float_dd_ma, 

302 b'\x9a\x99\x99\x99\x99\x99Y<\x9a\x99\x99\x99\x99\x99\xb9\xbf') 

303 # double double; high, low order (e.g. PPC 64 le) 

304 _register_type(float_dd_ma, 

305 b'\x9a\x99\x99\x99\x99\x99\xb9\xbf\x9a\x99\x99\x99\x99\x99Y<') 

306 _float_ma['dd'] = float_dd_ma 

307 

308 

309def _get_machar(ftype): 

310 """ Get MachAr instance or MachAr-like instance 

311 

312 Get parameters for floating point type, by first trying signatures of 

313 various known floating point types, then, if none match, attempting to 

314 identify parameters by analysis. 

315 

316 Parameters 

317 ---------- 

318 ftype : class 

319 Numpy floating point type class (e.g. ``np.float64``) 

320 

321 Returns 

322 ------- 

323 ma_like : instance of :class:`MachAr` or :class:`MachArLike` 

324 Object giving floating point parameters for `ftype`. 

325 

326 Warns 

327 ----- 

328 UserWarning 

329 If the binary signature of the float type is not in the dictionary of 

330 known float types. 

331 """ 

332 params = _MACHAR_PARAMS.get(ftype) 

333 if params is None: 

334 raise ValueError(repr(ftype)) 

335 # Detect known / suspected types 

336 # ftype(-1.0) / ftype(10.0) is better than ftype('-0.1') because stold 

337 # may be deficient 

338 key = (ftype(-1.0) / ftype(10.)) 

339 key = key.view(key.dtype.newbyteorder("<")).tobytes() 

340 ma_like = None 

341 if ftype == ntypes.longdouble: 

342 # Could be 80 bit == 10 byte extended precision, where last bytes can 

343 # be random garbage. 

344 # Comparing first 10 bytes to pattern first to avoid branching on the 

345 # random garbage. 

346 ma_like = _KNOWN_TYPES.get(key[:10]) 

347 if ma_like is None: 

348 # see if the full key is known. 

349 ma_like = _KNOWN_TYPES.get(key) 

350 if ma_like is None and len(key) == 16: 

351 # machine limits could be f80 masquerading as np.float128, 

352 # find all keys with length 16 and make new dict, but make the keys 

353 # only 10 bytes long, the last bytes can be random garbage 

354 _kt = {k[:10]: v for k, v in _KNOWN_TYPES.items() if len(k) == 16} 

355 ma_like = _kt.get(key[:10]) 

356 if ma_like is not None: 

357 return ma_like 

358 # Fall back to parameter discovery 

359 warnings.warn( 

360 f'Signature {key} for {ftype} does not match any known type: ' 

361 'falling back to type probe function.\n' 

362 'This warnings indicates broken support for the dtype!', 

363 UserWarning, stacklevel=2) 

364 return _discovered_machar(ftype) 

365 

366 

367def _discovered_machar(ftype): 

368 """ Create MachAr instance with found information on float types 

369 

370 TODO: MachAr should be retired completely ideally. We currently only 

371 ever use it system with broken longdouble (valgrind, WSL). 

372 """ 

373 params = _MACHAR_PARAMS[ftype] 

374 return MachAr(lambda v: array([v], ftype), 

375 lambda v: _fr0(v.astype(params['itype']))[0], 

376 lambda v: array(_fr0(v)[0], ftype), 

377 lambda v: params['fmt'] % array(_fr0(v)[0], ftype), 

378 params['title']) 

379 

380 

381@set_module('numpy') 

382class finfo: 

383 """ 

384 finfo(dtype) 

385 

386 Machine limits for floating point types. 

387 

388 Attributes 

389 ---------- 

390 bits : int 

391 The number of bits occupied by the type. 

392 dtype : dtype 

393 Returns the dtype for which `finfo` returns information. For complex 

394 input, the returned dtype is the associated ``float*`` dtype for its 

395 real and complex components. 

396 eps : float 

397 The difference between 1.0 and the next smallest representable float 

398 larger than 1.0. For example, for 64-bit binary floats in the IEEE-754 

399 standard, ``eps = 2**-52``, approximately 2.22e-16. 

400 epsneg : float 

401 The difference between 1.0 and the next smallest representable float 

402 less than 1.0. For example, for 64-bit binary floats in the IEEE-754 

403 standard, ``epsneg = 2**-53``, approximately 1.11e-16. 

404 iexp : int 

405 The number of bits in the exponent portion of the floating point 

406 representation. 

407 machep : int 

408 The exponent that yields `eps`. 

409 max : floating point number of the appropriate type 

410 The largest representable number. 

411 maxexp : int 

412 The smallest positive power of the base (2) that causes overflow. 

413 min : floating point number of the appropriate type 

414 The smallest representable number, typically ``-max``. 

415 minexp : int 

416 The most negative power of the base (2) consistent with there 

417 being no leading 0's in the mantissa. 

418 negep : int 

419 The exponent that yields `epsneg`. 

420 nexp : int 

421 The number of bits in the exponent including its sign and bias. 

422 nmant : int 

423 The number of bits in the mantissa. 

424 precision : int 

425 The approximate number of decimal digits to which this kind of 

426 float is precise. 

427 resolution : floating point number of the appropriate type 

428 The approximate decimal resolution of this type, i.e., 

429 ``10**-precision``. 

430 tiny : float 

431 An alias for `smallest_normal`, kept for backwards compatibility. 

432 smallest_normal : float 

433 The smallest positive floating point number with 1 as leading bit in 

434 the mantissa following IEEE-754 (see Notes). 

435 smallest_subnormal : float 

436 The smallest positive floating point number with 0 as leading bit in 

437 the mantissa following IEEE-754. 

438 

439 Parameters 

440 ---------- 

441 dtype : float, dtype, or instance 

442 Kind of floating point or complex floating point 

443 data-type about which to get information. 

444 

445 See Also 

446 -------- 

447 iinfo : The equivalent for integer data types. 

448 spacing : The distance between a value and the nearest adjacent number 

449 nextafter : The next floating point value after x1 towards x2 

450 

451 Notes 

452 ----- 

453 For developers of NumPy: do not instantiate this at the module level. 

454 The initial calculation of these parameters is expensive and negatively 

455 impacts import times. These objects are cached, so calling ``finfo()`` 

456 repeatedly inside your functions is not a problem. 

457 

458 Note that ``smallest_normal`` is not actually the smallest positive 

459 representable value in a NumPy floating point type. As in the IEEE-754 

460 standard [1]_, NumPy floating point types make use of subnormal numbers to 

461 fill the gap between 0 and ``smallest_normal``. However, subnormal numbers 

462 may have significantly reduced precision [2]_. 

463 

464 This function can also be used for complex data types as well. If used, 

465 the output will be the same as the corresponding real float type 

466 (e.g. numpy.finfo(numpy.csingle) is the same as numpy.finfo(numpy.single)). 

467 However, the output is true for the real and imaginary components. 

468 

469 References 

470 ---------- 

471 .. [1] IEEE Standard for Floating-Point Arithmetic, IEEE Std 754-2008, 

472 pp.1-70, 2008, https://doi.org/10.1109/IEEESTD.2008.4610935 

473 .. [2] Wikipedia, "Denormal Numbers", 

474 https://en.wikipedia.org/wiki/Denormal_number 

475 

476 Examples 

477 -------- 

478 >>> np.finfo(np.float64).dtype 

479 dtype('float64') 

480 >>> np.finfo(np.complex64).dtype 

481 dtype('float32') 

482 

483 """ 

484 

485 _finfo_cache = {} 

486 

487 def __new__(cls, dtype): 

488 try: 

489 obj = cls._finfo_cache.get(dtype) # most common path 

490 if obj is not None: 

491 return obj 

492 except TypeError: 

493 pass 

494 

495 if dtype is None: 

496 # Deprecated in NumPy 1.25, 2023-01-16 

497 warnings.warn( 

498 "finfo() dtype cannot be None. This behavior will " 

499 "raise an error in the future. (Deprecated in NumPy 1.25)", 

500 DeprecationWarning, 

501 stacklevel=2 

502 ) 

503 

504 try: 

505 dtype = numeric.dtype(dtype) 

506 except TypeError: 

507 # In case a float instance was given 

508 dtype = numeric.dtype(type(dtype)) 

509 

510 obj = cls._finfo_cache.get(dtype) 

511 if obj is not None: 

512 return obj 

513 dtypes = [dtype] 

514 newdtype = ntypes.obj2sctype(dtype) 

515 if newdtype is not dtype: 

516 dtypes.append(newdtype) 

517 dtype = newdtype 

518 if not issubclass(dtype, numeric.inexact): 

519 raise ValueError("data type %r not inexact" % (dtype)) 

520 obj = cls._finfo_cache.get(dtype) 

521 if obj is not None: 

522 return obj 

523 if not issubclass(dtype, numeric.floating): 

524 newdtype = _convert_to_float[dtype] 

525 if newdtype is not dtype: 

526 # dtype changed, for example from complex128 to float64 

527 dtypes.append(newdtype) 

528 dtype = newdtype 

529 

530 obj = cls._finfo_cache.get(dtype, None) 

531 if obj is not None: 

532 # the original dtype was not in the cache, but the new 

533 # dtype is in the cache. we add the original dtypes to 

534 # the cache and return the result 

535 for dt in dtypes: 

536 cls._finfo_cache[dt] = obj 

537 return obj 

538 obj = object.__new__(cls)._init(dtype) 

539 for dt in dtypes: 

540 cls._finfo_cache[dt] = obj 

541 return obj 

542 

543 def _init(self, dtype): 

544 self.dtype = numeric.dtype(dtype) 

545 machar = _get_machar(dtype) 

546 

547 for word in ['precision', 'iexp', 

548 'maxexp', 'minexp', 'negep', 

549 'machep']: 

550 setattr(self, word, getattr(machar, word)) 

551 for word in ['resolution', 'epsneg', 'smallest_subnormal']: 

552 setattr(self, word, getattr(machar, word).flat[0]) 

553 self.bits = self.dtype.itemsize * 8 

554 self.max = machar.huge.flat[0] 

555 self.min = -self.max 

556 self.eps = machar.eps.flat[0] 

557 self.nexp = machar.iexp 

558 self.nmant = machar.it 

559 self._machar = machar 

560 self._str_tiny = machar._str_xmin.strip() 

561 self._str_max = machar._str_xmax.strip() 

562 self._str_epsneg = machar._str_epsneg.strip() 

563 self._str_eps = machar._str_eps.strip() 

564 self._str_resolution = machar._str_resolution.strip() 

565 self._str_smallest_normal = machar._str_smallest_normal.strip() 

566 self._str_smallest_subnormal = machar._str_smallest_subnormal.strip() 

567 return self 

568 

569 def __str__(self): 

570 fmt = ( 

571 'Machine parameters for %(dtype)s\n' 

572 '---------------------------------------------------------------\n' 

573 'precision = %(precision)3s resolution = %(_str_resolution)s\n' 

574 'machep = %(machep)6s eps = %(_str_eps)s\n' 

575 'negep = %(negep)6s epsneg = %(_str_epsneg)s\n' 

576 'minexp = %(minexp)6s tiny = %(_str_tiny)s\n' 

577 'maxexp = %(maxexp)6s max = %(_str_max)s\n' 

578 'nexp = %(nexp)6s min = -max\n' 

579 'smallest_normal = %(_str_smallest_normal)s ' 

580 'smallest_subnormal = %(_str_smallest_subnormal)s\n' 

581 '---------------------------------------------------------------\n' 

582 ) 

583 return fmt % self.__dict__ 

584 

585 def __repr__(self): 

586 c = self.__class__.__name__ 

587 d = self.__dict__.copy() 

588 d['klass'] = c 

589 return (("%(klass)s(resolution=%(resolution)s, min=-%(_str_max)s," 

590 " max=%(_str_max)s, dtype=%(dtype)s)") % d) 

591 

592 @property 

593 def smallest_normal(self): 

594 """Return the value for the smallest normal. 

595 

596 Returns 

597 ------- 

598 smallest_normal : float 

599 Value for the smallest normal. 

600 

601 Warns 

602 ----- 

603 UserWarning 

604 If the calculated value for the smallest normal is requested for 

605 double-double. 

606 """ 

607 # This check is necessary because the value for smallest_normal is 

608 # platform dependent for longdouble types. 

609 if isnan(self._machar.smallest_normal.flat[0]): 

610 warnings.warn( 

611 'The value of smallest normal is undefined for double double', 

612 UserWarning, stacklevel=2) 

613 return self._machar.smallest_normal.flat[0] 

614 

615 @property 

616 def tiny(self): 

617 """Return the value for tiny, alias of smallest_normal. 

618 

619 Returns 

620 ------- 

621 tiny : float 

622 Value for the smallest normal, alias of smallest_normal. 

623 

624 Warns 

625 ----- 

626 UserWarning 

627 If the calculated value for the smallest normal is requested for 

628 double-double. 

629 """ 

630 return self.smallest_normal 

631 

632 

633@set_module('numpy') 

634class iinfo: 

635 """ 

636 iinfo(type) 

637 

638 Machine limits for integer types. 

639 

640 Attributes 

641 ---------- 

642 bits : int 

643 The number of bits occupied by the type. 

644 dtype : dtype 

645 Returns the dtype for which `iinfo` returns information. 

646 min : int 

647 The smallest integer expressible by the type. 

648 max : int 

649 The largest integer expressible by the type. 

650 

651 Parameters 

652 ---------- 

653 int_type : integer type, dtype, or instance 

654 The kind of integer data type to get information about. 

655 

656 See Also 

657 -------- 

658 finfo : The equivalent for floating point data types. 

659 

660 Examples 

661 -------- 

662 With types: 

663 

664 >>> ii16 = np.iinfo(np.int16) 

665 >>> ii16.min 

666 -32768 

667 >>> ii16.max 

668 32767 

669 >>> ii32 = np.iinfo(np.int32) 

670 >>> ii32.min 

671 -2147483648 

672 >>> ii32.max 

673 2147483647 

674 

675 With instances: 

676 

677 >>> ii32 = np.iinfo(np.int32(10)) 

678 >>> ii32.min 

679 -2147483648 

680 >>> ii32.max 

681 2147483647 

682 

683 """ 

684 

685 _min_vals = {} 

686 _max_vals = {} 

687 

688 def __init__(self, int_type): 

689 try: 

690 self.dtype = numeric.dtype(int_type) 

691 except TypeError: 

692 self.dtype = numeric.dtype(type(int_type)) 

693 self.kind = self.dtype.kind 

694 self.bits = self.dtype.itemsize * 8 

695 self.key = "%s%d" % (self.kind, self.bits) 

696 if self.kind not in 'iu': 

697 raise ValueError("Invalid integer data type %r." % (self.kind,)) 

698 

699 @property 

700 def min(self): 

701 """Minimum value of given dtype.""" 

702 if self.kind == 'u': 

703 return 0 

704 else: 

705 try: 

706 val = iinfo._min_vals[self.key] 

707 except KeyError: 

708 val = int(-(1 << (self.bits-1))) 

709 iinfo._min_vals[self.key] = val 

710 return val 

711 

712 @property 

713 def max(self): 

714 """Maximum value of given dtype.""" 

715 try: 

716 val = iinfo._max_vals[self.key] 

717 except KeyError: 

718 if self.kind == 'u': 

719 val = int((1 << self.bits) - 1) 

720 else: 

721 val = int((1 << (self.bits-1)) - 1) 

722 iinfo._max_vals[self.key] = val 

723 return val 

724 

725 def __str__(self): 

726 """String representation.""" 

727 fmt = ( 

728 'Machine parameters for %(dtype)s\n' 

729 '---------------------------------------------------------------\n' 

730 'min = %(min)s\n' 

731 'max = %(max)s\n' 

732 '---------------------------------------------------------------\n' 

733 ) 

734 return fmt % {'dtype': self.dtype, 'min': self.min, 'max': self.max} 

735 

736 def __repr__(self): 

737 return "%s(min=%s, max=%s, dtype=%s)" % (self.__class__.__name__, 

738 self.min, self.max, self.dtype)