Coverage for /var/srv/projects/api.amasfac.comuna18.com/tmp/venv/lib/python3.9/site-packages/numpy/core/getlimits.py: 56%

226 statements  

« prev     ^ index     » next       coverage.py v6.4.4, created at 2023-07-17 14:22 -0600

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

2 

3""" 

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

5 

6import warnings 

7 

8from ._machar import MachAr 

9from .overrides import set_module 

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: 18 ↛ 21line 18 didn't jump to line 21, because the condition on line 18 was never false

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: 26 ↛ 29line 26 didn't jump to line 29, because the condition on line 26 was never false

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# See: 

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

152_KNOWN_TYPES = {} 

153def _register_type(machar, bytepat): 

154 _KNOWN_TYPES[bytepat] = machar 

155_float_ma = {} 

156 

157 

158def _register_known_types(): 

159 # Known parameters for float16 

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

161 f16 = ntypes.float16 

162 float16_ma = MachArLike(f16, 

163 machep=-10, 

164 negep=-11, 

165 minexp=-14, 

166 maxexp=16, 

167 it=10, 

168 iexp=5, 

169 ibeta=2, 

170 irnd=5, 

171 ngrd=0, 

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

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

174 huge=f16(65504), 

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

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

177 _float_ma[16] = float16_ma 

178 

179 # Known parameters for float32 

180 f32 = ntypes.float32 

181 float32_ma = MachArLike(f32, 

182 machep=-23, 

183 negep=-24, 

184 minexp=-126, 

185 maxexp=128, 

186 it=23, 

187 iexp=8, 

188 ibeta=2, 

189 irnd=5, 

190 ngrd=0, 

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

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

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

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

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

196 _float_ma[32] = float32_ma 

197 

198 # Known parameters for float64 

199 f64 = ntypes.float64 

200 epsneg_f64 = 2.0 ** -53.0 

201 tiny_f64 = 2.0 ** -1022.0 

202 float64_ma = MachArLike(f64, 

203 machep=-52, 

204 negep=-53, 

205 minexp=-1022, 

206 maxexp=1024, 

207 it=52, 

208 iexp=11, 

209 ibeta=2, 

210 irnd=5, 

211 ngrd=0, 

212 eps=2.0 ** -52.0, 

213 epsneg=epsneg_f64, 

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

215 tiny=tiny_f64) 

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

217 _float_ma[64] = float64_ma 

218 

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

220 ld = ntypes.longdouble 

221 epsneg_f128 = exp2(ld(-113)) 

222 tiny_f128 = exp2(ld(-16382)) 

223 # Ignore runtime error when this is not f128 

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

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

226 float128_ma = MachArLike(ld, 

227 machep=-112, 

228 negep=-113, 

229 minexp=-16382, 

230 maxexp=16384, 

231 it=112, 

232 iexp=15, 

233 ibeta=2, 

234 irnd=5, 

235 ngrd=0, 

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

237 epsneg=epsneg_f128, 

238 huge=huge_f128, 

239 tiny=tiny_f128) 

240 # IEEE 754 128-bit binary float 

241 _register_type(float128_ma, 

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

243 _register_type(float128_ma, 

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

245 _float_ma[128] = float128_ma 

246 

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

248 epsneg_f80 = exp2(ld(-64)) 

249 tiny_f80 = exp2(ld(-16382)) 

250 # Ignore runtime error when this is not f80 

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

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

253 float80_ma = MachArLike(ld, 

254 machep=-63, 

255 negep=-64, 

256 minexp=-16382, 

257 maxexp=16384, 

258 it=63, 

259 iexp=15, 

260 ibeta=2, 

261 irnd=5, 

262 ngrd=0, 

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

264 epsneg=epsneg_f80, 

265 huge=huge_f80, 

266 tiny=tiny_f80) 

267 # float80, first 10 bytes containing actual storage 

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

269 _float_ma[80] = float80_ma 

270 

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

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

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

274 # digits in the significand. 

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

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

277 # it to NaN. 

278 smallest_normal_dd = NaN 

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

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

281 float_dd_ma = MachArLike(ld, 

282 machep=-105, 

283 negep=-106, 

284 minexp=-1022, 

285 maxexp=1024, 

286 it=105, 

287 iexp=11, 

288 ibeta=2, 

289 irnd=5, 

290 ngrd=0, 

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

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

293 huge=huge_dd, 

294 tiny=smallest_normal_dd, 

295 smallest_subnormal=smallest_subnormal_dd) 

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

297 _register_type(float_dd_ma, 

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

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

300 _register_type(float_dd_ma, 

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

302 _float_ma['dd'] = float_dd_ma 

303 

304 

305def _get_machar(ftype): 

306 """ Get MachAr instance or MachAr-like instance 

307 

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

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

310 identify parameters by analysis. 

311 

312 Parameters 

313 ---------- 

314 ftype : class 

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

316 

317 Returns 

318 ------- 

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

320 Object giving floating point parameters for `ftype`. 

321 

322 Warns 

323 ----- 

324 UserWarning 

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

326 known float types. 

327 """ 

328 params = _MACHAR_PARAMS.get(ftype) 

329 if params is None: 

330 raise ValueError(repr(ftype)) 

331 # Detect known / suspected types 

332 key = ftype('-0.1').newbyteorder('<').tobytes() 

333 ma_like = None 

334 if ftype == ntypes.longdouble: 

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

336 # be random garbage. 

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

338 # random garbage. 

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

340 if ma_like is None: 

341 ma_like = _KNOWN_TYPES.get(key) 

342 if ma_like is not None: 

343 return ma_like 

344 # Fall back to parameter discovery 

345 warnings.warn( 

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

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

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

349 UserWarning, stacklevel=2) 

350 return _discovered_machar(ftype) 

351 

352 

353def _discovered_machar(ftype): 

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

355 """ 

356 params = _MACHAR_PARAMS[ftype] 

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

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

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

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

361 params['title']) 

362 

363 

364@set_module('numpy') 

365class finfo: 

366 """ 

367 finfo(dtype) 

368 

369 Machine limits for floating point types. 

370 

371 Attributes 

372 ---------- 

373 bits : int 

374 The number of bits occupied by the type. 

375 eps : float 

376 The difference between 1.0 and the next smallest representable float 

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

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

379 epsneg : float 

380 The difference between 1.0 and the next smallest representable float 

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

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

383 iexp : int 

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

385 representation. 

386 machar : MachAr 

387 The object which calculated these parameters and holds more 

388 detailed information. 

389 

390 .. deprecated:: 1.22 

391 machep : int 

392 The exponent that yields `eps`. 

393 max : floating point number of the appropriate type 

394 The largest representable number. 

395 maxexp : int 

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

397 min : floating point number of the appropriate type 

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

399 minexp : int 

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

401 being no leading 0's in the mantissa. 

402 negep : int 

403 The exponent that yields `epsneg`. 

404 nexp : int 

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

406 nmant : int 

407 The number of bits in the mantissa. 

408 precision : int 

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

410 float is precise. 

411 resolution : floating point number of the appropriate type 

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

413 ``10**-precision``. 

414 tiny : float 

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

416 smallest_normal : float 

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

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

419 smallest_subnormal : float 

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

421 the mantissa following IEEE-754. 

422 

423 Parameters 

424 ---------- 

425 dtype : float, dtype, or instance 

426 Kind of floating point data-type about which to get information. 

427 

428 See Also 

429 -------- 

430 MachAr : The implementation of the tests that produce this information. 

431 iinfo : The equivalent for integer data types. 

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

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

434 

435 Notes 

436 ----- 

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

438 The initial calculation of these parameters is expensive and negatively 

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

440 repeatedly inside your functions is not a problem. 

441 

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

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

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

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

446 may have significantly reduced precision [2]_. 

447 

448 References 

449 ---------- 

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

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

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

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

454 """ 

455 

456 _finfo_cache = {} 

457 

458 def __new__(cls, dtype): 

459 try: 

460 dtype = numeric.dtype(dtype) 

461 except TypeError: 

462 # In case a float instance was given 

463 dtype = numeric.dtype(type(dtype)) 

464 

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

466 if obj is not None: 

467 return obj 

468 dtypes = [dtype] 

469 newdtype = numeric.obj2sctype(dtype) 

470 if newdtype is not dtype: 

471 dtypes.append(newdtype) 

472 dtype = newdtype 

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

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

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

476 if obj is not None: 

477 return obj 

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

479 newdtype = _convert_to_float[dtype] 

480 if newdtype is not dtype: 

481 dtypes.append(newdtype) 

482 dtype = newdtype 

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

484 if obj is not None: 

485 return obj 

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

487 for dt in dtypes: 

488 cls._finfo_cache[dt] = obj 

489 return obj 

490 

491 def _init(self, dtype): 

492 self.dtype = numeric.dtype(dtype) 

493 machar = _get_machar(dtype) 

494 

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

496 'maxexp', 'minexp', 'negep', 

497 'machep']: 

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

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

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

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

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

503 self.min = -self.max 

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

505 self.nexp = machar.iexp 

506 self.nmant = machar.it 

507 self._machar = machar 

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

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

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

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

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

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

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

515 return self 

516 

517 def __str__(self): 

518 fmt = ( 

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

520 '---------------------------------------------------------------\n' 

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

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

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

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

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

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

527 'smallest_normal = %(_str_smallest_normal)s ' 

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

529 '---------------------------------------------------------------\n' 

530 ) 

531 return fmt % self.__dict__ 

532 

533 def __repr__(self): 

534 c = self.__class__.__name__ 

535 d = self.__dict__.copy() 

536 d['klass'] = c 

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

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

539 

540 @property 

541 def smallest_normal(self): 

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

543 

544 Returns 

545 ------- 

546 smallest_normal : float 

547 Value for the smallest normal. 

548 

549 Warns 

550 ----- 

551 UserWarning 

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

553 double-double. 

554 """ 

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

556 # platform dependent for longdouble types. 

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

558 warnings.warn( 

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

560 UserWarning, stacklevel=2) 

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

562 

563 @property 

564 def tiny(self): 

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

566 

567 Returns 

568 ------- 

569 tiny : float 

570 Value for the smallest normal, alias of smallest_normal. 

571 

572 Warns 

573 ----- 

574 UserWarning 

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

576 double-double. 

577 """ 

578 return self.smallest_normal 

579 

580 @property 

581 def machar(self): 

582 """The object which calculated these parameters and holds more 

583 detailed information. 

584 

585 .. deprecated:: 1.22 

586 """ 

587 # Deprecated 2021-10-27, NumPy 1.22 

588 warnings.warn( 

589 "`finfo.machar` is deprecated (NumPy 1.22)", 

590 DeprecationWarning, stacklevel=2, 

591 ) 

592 return self._machar 

593 

594 

595@set_module('numpy') 

596class iinfo: 

597 """ 

598 iinfo(type) 

599 

600 Machine limits for integer types. 

601 

602 Attributes 

603 ---------- 

604 bits : int 

605 The number of bits occupied by the type. 

606 min : int 

607 The smallest integer expressible by the type. 

608 max : int 

609 The largest integer expressible by the type. 

610 

611 Parameters 

612 ---------- 

613 int_type : integer type, dtype, or instance 

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

615 

616 See Also 

617 -------- 

618 finfo : The equivalent for floating point data types. 

619 

620 Examples 

621 -------- 

622 With types: 

623 

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

625 >>> ii16.min 

626 -32768 

627 >>> ii16.max 

628 32767 

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

630 >>> ii32.min 

631 -2147483648 

632 >>> ii32.max 

633 2147483647 

634 

635 With instances: 

636 

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

638 >>> ii32.min 

639 -2147483648 

640 >>> ii32.max 

641 2147483647 

642 

643 """ 

644 

645 _min_vals = {} 

646 _max_vals = {} 

647 

648 def __init__(self, int_type): 

649 try: 

650 self.dtype = numeric.dtype(int_type) 

651 except TypeError: 

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

653 self.kind = self.dtype.kind 

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

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

656 if self.kind not in 'iu': 656 ↛ 657line 656 didn't jump to line 657, because the condition on line 656 was never true

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

658 

659 @property 

660 def min(self): 

661 """Minimum value of given dtype.""" 

662 if self.kind == 'u': 662 ↛ 663line 662 didn't jump to line 663, because the condition on line 662 was never true

663 return 0 

664 else: 

665 try: 

666 val = iinfo._min_vals[self.key] 

667 except KeyError: 

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

669 iinfo._min_vals[self.key] = val 

670 return val 

671 

672 @property 

673 def max(self): 

674 """Maximum value of given dtype.""" 

675 try: 

676 val = iinfo._max_vals[self.key] 

677 except KeyError: 

678 if self.kind == 'u': 

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

680 else: 

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

682 iinfo._max_vals[self.key] = val 

683 return val 

684 

685 def __str__(self): 

686 """String representation.""" 

687 fmt = ( 

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

689 '---------------------------------------------------------------\n' 

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

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

692 '---------------------------------------------------------------\n' 

693 ) 

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

695 

696 def __repr__(self): 

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

698 self.min, self.max, self.dtype)