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

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

244 statements  

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

2 

3""" 

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

5 

6import types 

7import warnings 

8 

9from .._utils import set_module 

10from ._machar import MachAr 

11from . import numeric 

12from . import numerictypes as ntypes 

13from .numeric import array, inf, nan 

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

15 

16 

17def _fr0(a): 

18 """fix rank-0 --> rank-1""" 

19 if a.ndim == 0: 

20 a = a.copy() 

21 a.shape = (1,) 

22 return a 

23 

24 

25def _fr1(a): 

26 """fix rank > 0 --> rank-0""" 

27 if a.size == 1: 

28 a = a.copy() 

29 a.shape = () 

30 return a 

31 

32 

33class MachArLike: 

34 """ Object to simulate MachAr instance """ 

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

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

37 self.params = _MACHAR_PARAMS[ftype] 

38 self.ftype = ftype 

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

40 # Parameter types same as for discovered MachAr object. 

41 if not smallest_subnormal: 

42 self._smallest_subnormal = nextafter( 

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

44 else: 

45 self._smallest_subnormal = smallest_subnormal 

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

47 self.epsneg = self._float_to_float(epsneg) 

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

49 self.xmin = self._float_to_float(tiny) 

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

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

52 self.__dict__.update(kwargs) 

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

54 self.resolution = self._float_to_float( 

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

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

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

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

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

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

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

62 

63 @property 

64 def smallest_subnormal(self): 

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

66 

67 Returns 

68 ------- 

69 smallest_subnormal : float 

70 value for the smallest subnormal. 

71 

72 Warns 

73 ----- 

74 UserWarning 

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

76 """ 

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

78 # warning. 

79 value = self._smallest_subnormal 

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

81 warnings.warn( 

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

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

84 

85 return self._float_to_float(value) 

86 

87 @property 

88 def _str_smallest_subnormal(self): 

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

90 return self._float_to_str(self.smallest_subnormal) 

91 

92 def _float_to_float(self, value): 

93 """Converts float to float. 

94 

95 Parameters 

96 ---------- 

97 value : float 

98 value to be converted. 

99 """ 

100 return _fr1(self._float_conv(value)) 

101 

102 def _float_conv(self, value): 

103 """Converts float to conv. 

104 

105 Parameters 

106 ---------- 

107 value : float 

108 value to be converted. 

109 """ 

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

111 

112 def _float_to_str(self, value): 

113 """Converts float to str. 

114 

115 Parameters 

116 ---------- 

117 value : float 

118 value to be converted. 

119 """ 

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

121 

122 

123_convert_to_float = { 

124 ntypes.csingle: ntypes.single, 

125 ntypes.complex128: ntypes.float64, 

126 ntypes.clongdouble: ntypes.longdouble 

127 } 

128 

129# Parameters for creating MachAr / MachAr-like objects 

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

131_MACHAR_PARAMS = { 

132 ntypes.double: dict( 

133 itype = ntypes.int64, 

134 fmt = '%24.16e', 

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

136 ntypes.single: dict( 

137 itype = ntypes.int32, 

138 fmt = '%15.7e', 

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

140 ntypes.longdouble: dict( 

141 itype = ntypes.longlong, 

142 fmt = '%s', 

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

144 ntypes.half: dict( 

145 itype = ntypes.int16, 

146 fmt = '%12.5e', 

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

148 

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

150# 

151# ftype = np.longdouble # or float64, float32, etc. 

152# v = (ftype(-1.0) / ftype(10.0)) 

153# v.view(v.dtype.newbyteorder('<')).tobytes() 

154# 

155# Uses division to work around deficiencies in strtold on some platforms. 

156# See: 

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

158 

159_KNOWN_TYPES = {} 

160def _register_type(machar, bytepat): 

161 _KNOWN_TYPES[bytepat] = machar 

162 

163 

164_float_ma = {} 

165 

166 

167def _register_known_types(): 

168 # Known parameters for float16 

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

170 f16 = ntypes.float16 

171 float16_ma = MachArLike(f16, 

172 machep=-10, 

173 negep=-11, 

174 minexp=-14, 

175 maxexp=16, 

176 it=10, 

177 iexp=5, 

178 ibeta=2, 

179 irnd=5, 

180 ngrd=0, 

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

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

183 huge=f16(65504), 

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

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

186 _float_ma[16] = float16_ma 

187 

188 # Known parameters for float32 

189 f32 = ntypes.float32 

190 float32_ma = MachArLike(f32, 

191 machep=-23, 

192 negep=-24, 

193 minexp=-126, 

194 maxexp=128, 

195 it=23, 

196 iexp=8, 

197 ibeta=2, 

198 irnd=5, 

199 ngrd=0, 

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

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

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

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

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

205 _float_ma[32] = float32_ma 

206 

207 # Known parameters for float64 

208 f64 = ntypes.float64 

209 epsneg_f64 = 2.0 ** -53.0 

210 tiny_f64 = 2.0 ** -1022.0 

211 float64_ma = MachArLike(f64, 

212 machep=-52, 

213 negep=-53, 

214 minexp=-1022, 

215 maxexp=1024, 

216 it=52, 

217 iexp=11, 

218 ibeta=2, 

219 irnd=5, 

220 ngrd=0, 

221 eps=2.0 ** -52.0, 

222 epsneg=epsneg_f64, 

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

224 tiny=tiny_f64) 

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

226 _float_ma[64] = float64_ma 

227 

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

229 ld = ntypes.longdouble 

230 epsneg_f128 = exp2(ld(-113)) 

231 tiny_f128 = exp2(ld(-16382)) 

232 # Ignore runtime error when this is not f128 

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

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

235 float128_ma = MachArLike(ld, 

236 machep=-112, 

237 negep=-113, 

238 minexp=-16382, 

239 maxexp=16384, 

240 it=112, 

241 iexp=15, 

242 ibeta=2, 

243 irnd=5, 

244 ngrd=0, 

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

246 epsneg=epsneg_f128, 

247 huge=huge_f128, 

248 tiny=tiny_f128) 

249 # IEEE 754 128-bit binary float 

250 _register_type(float128_ma, 

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

252 _float_ma[128] = float128_ma 

253 

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

255 epsneg_f80 = exp2(ld(-64)) 

256 tiny_f80 = exp2(ld(-16382)) 

257 # Ignore runtime error when this is not f80 

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

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

260 float80_ma = MachArLike(ld, 

261 machep=-63, 

262 negep=-64, 

263 minexp=-16382, 

264 maxexp=16384, 

265 it=63, 

266 iexp=15, 

267 ibeta=2, 

268 irnd=5, 

269 ngrd=0, 

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

271 epsneg=epsneg_f80, 

272 huge=huge_f80, 

273 tiny=tiny_f80) 

274 # float80, first 10 bytes containing actual storage 

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

276 _float_ma[80] = float80_ma 

277 

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

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

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

281 # number of digits in the significand. 

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

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

284 # it to NaN. 

285 smallest_normal_dd = nan 

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

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

288 float_dd_ma = MachArLike(ld, 

289 machep=-105, 

290 negep=-106, 

291 minexp=-1022, 

292 maxexp=1024, 

293 it=105, 

294 iexp=11, 

295 ibeta=2, 

296 irnd=5, 

297 ngrd=0, 

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

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

300 huge=huge_dd, 

301 tiny=smallest_normal_dd, 

302 smallest_subnormal=smallest_subnormal_dd) 

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

304 _register_type(float_dd_ma, 

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

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

307 _register_type(float_dd_ma, 

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

309 _float_ma['dd'] = float_dd_ma 

310 

311 

312def _get_machar(ftype): 

313 """ Get MachAr instance or MachAr-like instance 

314 

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

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

317 identify parameters by analysis. 

318 

319 Parameters 

320 ---------- 

321 ftype : class 

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

323 

324 Returns 

325 ------- 

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

327 Object giving floating point parameters for `ftype`. 

328 

329 Warns 

330 ----- 

331 UserWarning 

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

333 known float types. 

334 """ 

335 params = _MACHAR_PARAMS.get(ftype) 

336 if params is None: 

337 raise ValueError(repr(ftype)) 

338 # Detect known / suspected types 

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

340 # may be deficient 

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

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

343 ma_like = None 

344 if ftype == ntypes.longdouble: 

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

346 # be random garbage. 

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

348 # random garbage. 

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

350 if ma_like is None: 

351 # see if the full key is known. 

352 ma_like = _KNOWN_TYPES.get(key) 

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

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

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

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

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

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

359 if ma_like is not None: 

360 return ma_like 

361 # Fall back to parameter discovery 

362 warnings.warn( 

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

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

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

366 UserWarning, stacklevel=2) 

367 return _discovered_machar(ftype) 

368 

369 

370def _discovered_machar(ftype): 

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

372 

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

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

375 """ 

376 params = _MACHAR_PARAMS[ftype] 

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

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

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

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

381 params['title']) 

382 

383 

384@set_module('numpy') 

385class finfo: 

386 """ 

387 finfo(dtype) 

388 

389 Machine limits for floating point types. 

390 

391 Attributes 

392 ---------- 

393 bits : int 

394 The number of bits occupied by the type. 

395 dtype : dtype 

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

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

398 real and complex components. 

399 eps : float 

400 The difference between 1.0 and the next smallest representable float 

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

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

403 epsneg : float 

404 The difference between 1.0 and the next smallest representable float 

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

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

407 iexp : int 

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

409 representation. 

410 machep : int 

411 The exponent that yields `eps`. 

412 max : floating point number of the appropriate type 

413 The largest representable number. 

414 maxexp : int 

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

416 min : floating point number of the appropriate type 

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

418 minexp : int 

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

420 being no leading 0's in the mantissa. 

421 negep : int 

422 The exponent that yields `epsneg`. 

423 nexp : int 

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

425 nmant : int 

426 The number of bits in the mantissa. 

427 precision : int 

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

429 float is precise. 

430 resolution : floating point number of the appropriate type 

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

432 ``10**-precision``. 

433 tiny : float 

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

435 smallest_normal : float 

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

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

438 smallest_subnormal : float 

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

440 the mantissa following IEEE-754. 

441 

442 Parameters 

443 ---------- 

444 dtype : float, dtype, or instance 

445 Kind of floating point or complex floating point 

446 data-type about which to get information. 

447 

448 See Also 

449 -------- 

450 iinfo : The equivalent for integer data types. 

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

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

453 

454 Notes 

455 ----- 

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

457 The initial calculation of these parameters is expensive and negatively 

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

459 repeatedly inside your functions is not a problem. 

460 

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

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

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

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

465 may have significantly reduced precision [2]_. 

466 

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

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

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

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

471 

472 References 

473 ---------- 

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

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

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

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

478 

479 Examples 

480 -------- 

481 >>> import numpy as np 

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

483 dtype('float64') 

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

485 dtype('float32') 

486 

487 """ 

488 

489 _finfo_cache = {} 

490 

491 __class_getitem__ = classmethod(types.GenericAlias) 

492 

493 def __new__(cls, dtype): 

494 try: 

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

496 if obj is not None: 

497 return obj 

498 except TypeError: 

499 pass 

500 

501 if dtype is None: 

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

503 warnings.warn( 

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

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

506 DeprecationWarning, 

507 stacklevel=2 

508 ) 

509 

510 try: 

511 dtype = numeric.dtype(dtype) 

512 except TypeError: 

513 # In case a float instance was given 

514 dtype = numeric.dtype(type(dtype)) 

515 

516 obj = cls._finfo_cache.get(dtype) 

517 if obj is not None: 

518 return obj 

519 dtypes = [dtype] 

520 newdtype = ntypes.obj2sctype(dtype) 

521 if newdtype is not dtype: 

522 dtypes.append(newdtype) 

523 dtype = newdtype 

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

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

526 obj = cls._finfo_cache.get(dtype) 

527 if obj is not None: 

528 return obj 

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

530 newdtype = _convert_to_float[dtype] 

531 if newdtype is not dtype: 

532 # dtype changed, for example from complex128 to float64 

533 dtypes.append(newdtype) 

534 dtype = newdtype 

535 

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

537 if obj is not None: 

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

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

540 # the cache and return the result 

541 for dt in dtypes: 

542 cls._finfo_cache[dt] = obj 

543 return obj 

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

545 for dt in dtypes: 

546 cls._finfo_cache[dt] = obj 

547 return obj 

548 

549 def _init(self, dtype): 

550 self.dtype = numeric.dtype(dtype) 

551 machar = _get_machar(dtype) 

552 

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

554 'maxexp', 'minexp', 'negep', 

555 'machep']: 

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

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

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

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

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

561 self.min = -self.max 

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

563 self.nexp = machar.iexp 

564 self.nmant = machar.it 

565 self._machar = machar 

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

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

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

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

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

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

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

573 return self 

574 

575 def __str__(self): 

576 fmt = ( 

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

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

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

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

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

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

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

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

585 'smallest_normal = %(_str_smallest_normal)s ' 

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

587 '---------------------------------------------------------------\n' 

588 ) 

589 return fmt % self.__dict__ 

590 

591 def __repr__(self): 

592 c = self.__class__.__name__ 

593 d = self.__dict__.copy() 

594 d['klass'] = c 

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

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

597 

598 @property 

599 def smallest_normal(self): 

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

601 

602 Returns 

603 ------- 

604 smallest_normal : float 

605 Value for the smallest normal. 

606 

607 Warns 

608 ----- 

609 UserWarning 

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

611 double-double. 

612 """ 

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

614 # platform dependent for longdouble types. 

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

616 warnings.warn( 

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

618 UserWarning, stacklevel=2) 

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

620 

621 @property 

622 def tiny(self): 

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

624 

625 Returns 

626 ------- 

627 tiny : float 

628 Value for the smallest normal, alias of smallest_normal. 

629 

630 Warns 

631 ----- 

632 UserWarning 

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

634 double-double. 

635 """ 

636 return self.smallest_normal 

637 

638 

639@set_module('numpy') 

640class iinfo: 

641 """ 

642 iinfo(type) 

643 

644 Machine limits for integer types. 

645 

646 Attributes 

647 ---------- 

648 bits : int 

649 The number of bits occupied by the type. 

650 dtype : dtype 

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

652 min : int 

653 The smallest integer expressible by the type. 

654 max : int 

655 The largest integer expressible by the type. 

656 

657 Parameters 

658 ---------- 

659 int_type : integer type, dtype, or instance 

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

661 

662 See Also 

663 -------- 

664 finfo : The equivalent for floating point data types. 

665 

666 Examples 

667 -------- 

668 With types: 

669 

670 >>> import numpy as np 

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

672 >>> ii16.min 

673 -32768 

674 >>> ii16.max 

675 32767 

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

677 >>> ii32.min 

678 -2147483648 

679 >>> ii32.max 

680 2147483647 

681 

682 With instances: 

683 

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

685 >>> ii32.min 

686 -2147483648 

687 >>> ii32.max 

688 2147483647 

689 

690 """ 

691 

692 _min_vals = {} 

693 _max_vals = {} 

694 

695 __class_getitem__ = classmethod(types.GenericAlias) 

696 

697 def __init__(self, int_type): 

698 try: 

699 self.dtype = numeric.dtype(int_type) 

700 except TypeError: 

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

702 self.kind = self.dtype.kind 

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

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

705 if self.kind not in 'iu': 

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

707 

708 @property 

709 def min(self): 

710 """Minimum value of given dtype.""" 

711 if self.kind == 'u': 

712 return 0 

713 else: 

714 try: 

715 val = iinfo._min_vals[self.key] 

716 except KeyError: 

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

718 iinfo._min_vals[self.key] = val 

719 return val 

720 

721 @property 

722 def max(self): 

723 """Maximum value of given dtype.""" 

724 try: 

725 val = iinfo._max_vals[self.key] 

726 except KeyError: 

727 if self.kind == 'u': 

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

729 else: 

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

731 iinfo._max_vals[self.key] = val 

732 return val 

733 

734 def __str__(self): 

735 """String representation.""" 

736 fmt = ( 

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

738 '---------------------------------------------------------------\n' 

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

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

741 '---------------------------------------------------------------\n' 

742 ) 

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

744 

745 def __repr__(self): 

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

747 self.min, self.max, self.dtype)