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

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

240 statements  

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.complex_: ntypes.float_, 

125 ntypes.clongfloat: ntypes.longfloat 

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_float_ma = {} 

160 

161 

162def _register_known_types(): 

163 # Known parameters for float16 

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

165 f16 = ntypes.float16 

166 float16_ma = MachArLike(f16, 

167 machep=-10, 

168 negep=-11, 

169 minexp=-14, 

170 maxexp=16, 

171 it=10, 

172 iexp=5, 

173 ibeta=2, 

174 irnd=5, 

175 ngrd=0, 

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

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

178 huge=f16(65504), 

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

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

181 _float_ma[16] = float16_ma 

182 

183 # Known parameters for float32 

184 f32 = ntypes.float32 

185 float32_ma = MachArLike(f32, 

186 machep=-23, 

187 negep=-24, 

188 minexp=-126, 

189 maxexp=128, 

190 it=23, 

191 iexp=8, 

192 ibeta=2, 

193 irnd=5, 

194 ngrd=0, 

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

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

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

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

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

200 _float_ma[32] = float32_ma 

201 

202 # Known parameters for float64 

203 f64 = ntypes.float64 

204 epsneg_f64 = 2.0 ** -53.0 

205 tiny_f64 = 2.0 ** -1022.0 

206 float64_ma = MachArLike(f64, 

207 machep=-52, 

208 negep=-53, 

209 minexp=-1022, 

210 maxexp=1024, 

211 it=52, 

212 iexp=11, 

213 ibeta=2, 

214 irnd=5, 

215 ngrd=0, 

216 eps=2.0 ** -52.0, 

217 epsneg=epsneg_f64, 

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

219 tiny=tiny_f64) 

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

221 _float_ma[64] = float64_ma 

222 

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

224 ld = ntypes.longdouble 

225 epsneg_f128 = exp2(ld(-113)) 

226 tiny_f128 = exp2(ld(-16382)) 

227 # Ignore runtime error when this is not f128 

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

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

230 float128_ma = MachArLike(ld, 

231 machep=-112, 

232 negep=-113, 

233 minexp=-16382, 

234 maxexp=16384, 

235 it=112, 

236 iexp=15, 

237 ibeta=2, 

238 irnd=5, 

239 ngrd=0, 

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

241 epsneg=epsneg_f128, 

242 huge=huge_f128, 

243 tiny=tiny_f128) 

244 # IEEE 754 128-bit binary float 

245 _register_type(float128_ma, 

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

247 _float_ma[128] = float128_ma 

248 

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

250 epsneg_f80 = exp2(ld(-64)) 

251 tiny_f80 = exp2(ld(-16382)) 

252 # Ignore runtime error when this is not f80 

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

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

255 float80_ma = MachArLike(ld, 

256 machep=-63, 

257 negep=-64, 

258 minexp=-16382, 

259 maxexp=16384, 

260 it=63, 

261 iexp=15, 

262 ibeta=2, 

263 irnd=5, 

264 ngrd=0, 

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

266 epsneg=epsneg_f80, 

267 huge=huge_f80, 

268 tiny=tiny_f80) 

269 # float80, first 10 bytes containing actual storage 

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

271 _float_ma[80] = float80_ma 

272 

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

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

275 # These numbers have the same exponent range as float64, but extended number of 

276 # digits in the significand. 

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

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

279 # it to NaN. 

280 smallest_normal_dd = NaN 

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

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

283 float_dd_ma = MachArLike(ld, 

284 machep=-105, 

285 negep=-106, 

286 minexp=-1022, 

287 maxexp=1024, 

288 it=105, 

289 iexp=11, 

290 ibeta=2, 

291 irnd=5, 

292 ngrd=0, 

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

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

295 huge=huge_dd, 

296 tiny=smallest_normal_dd, 

297 smallest_subnormal=smallest_subnormal_dd) 

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

299 _register_type(float_dd_ma, 

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

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

302 _register_type(float_dd_ma, 

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

304 _float_ma['dd'] = float_dd_ma 

305 

306 

307def _get_machar(ftype): 

308 """ Get MachAr instance or MachAr-like instance 

309 

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

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

312 identify parameters by analysis. 

313 

314 Parameters 

315 ---------- 

316 ftype : class 

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

318 

319 Returns 

320 ------- 

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

322 Object giving floating point parameters for `ftype`. 

323 

324 Warns 

325 ----- 

326 UserWarning 

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

328 known float types. 

329 """ 

330 params = _MACHAR_PARAMS.get(ftype) 

331 if params is None: 

332 raise ValueError(repr(ftype)) 

333 # Detect known / suspected types 

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

335 # may be deficient 

336 key = (ftype(-1.0) / ftype(10.)).newbyteorder('<').tobytes() 

337 ma_like = None 

338 if ftype == ntypes.longdouble: 

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

340 # be random garbage. 

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

342 # random garbage. 

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

344 if ma_like is None: 

345 # see if the full key is known. 

346 ma_like = _KNOWN_TYPES.get(key) 

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

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

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

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

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

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

353 if ma_like is not None: 

354 return ma_like 

355 # Fall back to parameter discovery 

356 warnings.warn( 

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

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

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

360 UserWarning, stacklevel=2) 

361 return _discovered_machar(ftype) 

362 

363 

364def _discovered_machar(ftype): 

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

366 

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

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

369 """ 

370 params = _MACHAR_PARAMS[ftype] 

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

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

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

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

375 params['title']) 

376 

377 

378@set_module('numpy') 

379class finfo: 

380 """ 

381 finfo(dtype) 

382 

383 Machine limits for floating point types. 

384 

385 Attributes 

386 ---------- 

387 bits : int 

388 The number of bits occupied by the type. 

389 dtype : dtype 

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

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

392 real and complex components. 

393 eps : float 

394 The difference between 1.0 and the next smallest representable float 

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

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

397 epsneg : float 

398 The difference between 1.0 and the next smallest representable float 

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

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

401 iexp : int 

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

403 representation. 

404 machep : int 

405 The exponent that yields `eps`. 

406 max : floating point number of the appropriate type 

407 The largest representable number. 

408 maxexp : int 

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

410 min : floating point number of the appropriate type 

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

412 minexp : int 

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

414 being no leading 0's in the mantissa. 

415 negep : int 

416 The exponent that yields `epsneg`. 

417 nexp : int 

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

419 nmant : int 

420 The number of bits in the mantissa. 

421 precision : int 

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

423 float is precise. 

424 resolution : floating point number of the appropriate type 

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

426 ``10**-precision``. 

427 tiny : float 

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

429 smallest_normal : float 

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

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

432 smallest_subnormal : float 

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

434 the mantissa following IEEE-754. 

435 

436 Parameters 

437 ---------- 

438 dtype : float, dtype, or instance 

439 Kind of floating point or complex floating point 

440 data-type about which to get information. 

441 

442 See Also 

443 -------- 

444 iinfo : The equivalent for integer data types. 

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

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

447 

448 Notes 

449 ----- 

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

451 The initial calculation of these parameters is expensive and negatively 

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

453 repeatedly inside your functions is not a problem. 

454 

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

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

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

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

459 may have significantly reduced precision [2]_. 

460 

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

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

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

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

465 

466 References 

467 ---------- 

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

469 pp.1-70, 2008, http://www.doi.org/10.1109/IEEESTD.2008.4610935 

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

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

472 

473 Examples 

474 -------- 

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

476 dtype('float64') 

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

478 dtype('float32') 

479 

480 """ 

481 

482 _finfo_cache = {} 

483 

484 def __new__(cls, dtype): 

485 try: 

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

487 if obj is not None: 

488 return obj 

489 except TypeError: 

490 pass 

491 

492 if dtype is None: 

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

494 warnings.warn( 

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

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

497 DeprecationWarning, 

498 stacklevel=2 

499 ) 

500 

501 try: 

502 dtype = numeric.dtype(dtype) 

503 except TypeError: 

504 # In case a float instance was given 

505 dtype = numeric.dtype(type(dtype)) 

506 

507 obj = cls._finfo_cache.get(dtype) 

508 if obj is not None: 

509 return obj 

510 dtypes = [dtype] 

511 newdtype = numeric.obj2sctype(dtype) 

512 if newdtype is not dtype: 

513 dtypes.append(newdtype) 

514 dtype = newdtype 

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

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

517 obj = cls._finfo_cache.get(dtype) 

518 if obj is not None: 

519 return obj 

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

521 newdtype = _convert_to_float[dtype] 

522 if newdtype is not dtype: 

523 # dtype changed, for example from complex128 to float64 

524 dtypes.append(newdtype) 

525 dtype = newdtype 

526 

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

528 if obj is not None: 

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

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

531 # the cache and return the result 

532 for dt in dtypes: 

533 cls._finfo_cache[dt] = obj 

534 return obj 

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

536 for dt in dtypes: 

537 cls._finfo_cache[dt] = obj 

538 return obj 

539 

540 def _init(self, dtype): 

541 self.dtype = numeric.dtype(dtype) 

542 machar = _get_machar(dtype) 

543 

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

545 'maxexp', 'minexp', 'negep', 

546 'machep']: 

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

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

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

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

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

552 self.min = -self.max 

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

554 self.nexp = machar.iexp 

555 self.nmant = machar.it 

556 self._machar = machar 

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

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

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

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

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

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

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

564 return self 

565 

566 def __str__(self): 

567 fmt = ( 

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

569 '---------------------------------------------------------------\n' 

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

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

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

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

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

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

576 'smallest_normal = %(_str_smallest_normal)s ' 

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

578 '---------------------------------------------------------------\n' 

579 ) 

580 return fmt % self.__dict__ 

581 

582 def __repr__(self): 

583 c = self.__class__.__name__ 

584 d = self.__dict__.copy() 

585 d['klass'] = c 

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

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

588 

589 @property 

590 def smallest_normal(self): 

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

592 

593 Returns 

594 ------- 

595 smallest_normal : float 

596 Value for the smallest normal. 

597 

598 Warns 

599 ----- 

600 UserWarning 

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

602 double-double. 

603 """ 

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

605 # platform dependent for longdouble types. 

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

607 warnings.warn( 

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

609 UserWarning, stacklevel=2) 

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

611 

612 @property 

613 def tiny(self): 

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

615 

616 Returns 

617 ------- 

618 tiny : float 

619 Value for the smallest normal, alias of smallest_normal. 

620 

621 Warns 

622 ----- 

623 UserWarning 

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

625 double-double. 

626 """ 

627 return self.smallest_normal 

628 

629 

630@set_module('numpy') 

631class iinfo: 

632 """ 

633 iinfo(type) 

634 

635 Machine limits for integer types. 

636 

637 Attributes 

638 ---------- 

639 bits : int 

640 The number of bits occupied by the type. 

641 dtype : dtype 

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

643 min : int 

644 The smallest integer expressible by the type. 

645 max : int 

646 The largest integer expressible by the type. 

647 

648 Parameters 

649 ---------- 

650 int_type : integer type, dtype, or instance 

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

652 

653 See Also 

654 -------- 

655 finfo : The equivalent for floating point data types. 

656 

657 Examples 

658 -------- 

659 With types: 

660 

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

662 >>> ii16.min 

663 -32768 

664 >>> ii16.max 

665 32767 

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

667 >>> ii32.min 

668 -2147483648 

669 >>> ii32.max 

670 2147483647 

671 

672 With instances: 

673 

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

675 >>> ii32.min 

676 -2147483648 

677 >>> ii32.max 

678 2147483647 

679 

680 """ 

681 

682 _min_vals = {} 

683 _max_vals = {} 

684 

685 def __init__(self, int_type): 

686 try: 

687 self.dtype = numeric.dtype(int_type) 

688 except TypeError: 

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

690 self.kind = self.dtype.kind 

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

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

693 if self.kind not in 'iu': 

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

695 

696 @property 

697 def min(self): 

698 """Minimum value of given dtype.""" 

699 if self.kind == 'u': 

700 return 0 

701 else: 

702 try: 

703 val = iinfo._min_vals[self.key] 

704 except KeyError: 

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

706 iinfo._min_vals[self.key] = val 

707 return val 

708 

709 @property 

710 def max(self): 

711 """Maximum value of given dtype.""" 

712 try: 

713 val = iinfo._max_vals[self.key] 

714 except KeyError: 

715 if self.kind == 'u': 

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

717 else: 

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

719 iinfo._max_vals[self.key] = val 

720 return val 

721 

722 def __str__(self): 

723 """String representation.""" 

724 fmt = ( 

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

726 '---------------------------------------------------------------\n' 

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

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

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

730 ) 

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

732 

733 def __repr__(self): 

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

735 self.min, self.max, self.dtype)