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

228 statements  

« prev     ^ index     » next       coverage.py v7.0.5, created at 2023-01-17 06:27 +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.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 TODO: MachAr should be retired completely ideally. We currently only 

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

358 """ 

359 params = _MACHAR_PARAMS[ftype] 

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

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

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

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

364 params['title']) 

365 

366 

367@set_module('numpy') 

368class finfo: 

369 """ 

370 finfo(dtype) 

371 

372 Machine limits for floating point types. 

373 

374 Attributes 

375 ---------- 

376 bits : int 

377 The number of bits occupied by the type. 

378 dtype : dtype 

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

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

381 real and complex components. 

382 eps : float 

383 The difference between 1.0 and the next smallest representable float 

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

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

386 epsneg : float 

387 The difference between 1.0 and the next smallest representable float 

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

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

390 iexp : int 

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

392 representation. 

393 machep : int 

394 The exponent that yields `eps`. 

395 max : floating point number of the appropriate type 

396 The largest representable number. 

397 maxexp : int 

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

399 min : floating point number of the appropriate type 

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

401 minexp : int 

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

403 being no leading 0's in the mantissa. 

404 negep : int 

405 The exponent that yields `epsneg`. 

406 nexp : int 

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

408 nmant : int 

409 The number of bits in the mantissa. 

410 precision : int 

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

412 float is precise. 

413 resolution : floating point number of the appropriate type 

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

415 ``10**-precision``. 

416 tiny : float 

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

418 smallest_normal : float 

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

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

421 smallest_subnormal : float 

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

423 the mantissa following IEEE-754. 

424 

425 Parameters 

426 ---------- 

427 dtype : float, dtype, or instance 

428 Kind of floating point or complex floating point 

429 data-type about which to get information. 

430 

431 See Also 

432 -------- 

433 iinfo : The equivalent for integer data types. 

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

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

436 

437 Notes 

438 ----- 

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

440 The initial calculation of these parameters is expensive and negatively 

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

442 repeatedly inside your functions is not a problem. 

443 

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

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

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

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

448 may have significantly reduced precision [2]_. 

449 

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

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

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

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

454 

455 References 

456 ---------- 

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

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

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

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

461 

462 Examples 

463 -------- 

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

465 dtype('float64') 

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

467 dtype('float32') 

468 

469 """ 

470 

471 _finfo_cache = {} 

472 

473 def __new__(cls, dtype): 

474 try: 

475 dtype = numeric.dtype(dtype) 

476 except TypeError: 

477 # In case a float instance was given 

478 dtype = numeric.dtype(type(dtype)) 

479 

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

481 if obj is not None: 

482 return obj 

483 dtypes = [dtype] 

484 newdtype = numeric.obj2sctype(dtype) 

485 if newdtype is not dtype: 

486 dtypes.append(newdtype) 

487 dtype = newdtype 

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

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

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

491 if obj is not None: 

492 return obj 

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

494 newdtype = _convert_to_float[dtype] 

495 if newdtype is not dtype: 

496 dtypes.append(newdtype) 

497 dtype = newdtype 

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

499 if obj is not None: 

500 return obj 

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

502 for dt in dtypes: 

503 cls._finfo_cache[dt] = obj 

504 return obj 

505 

506 def _init(self, dtype): 

507 self.dtype = numeric.dtype(dtype) 

508 machar = _get_machar(dtype) 

509 

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

511 'maxexp', 'minexp', 'negep', 

512 'machep']: 

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

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

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

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

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

518 self.min = -self.max 

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

520 self.nexp = machar.iexp 

521 self.nmant = machar.it 

522 self._machar = machar 

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

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

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

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

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

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

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

530 return self 

531 

532 def __str__(self): 

533 fmt = ( 

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

535 '---------------------------------------------------------------\n' 

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

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

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

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

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

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

542 'smallest_normal = %(_str_smallest_normal)s ' 

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

544 '---------------------------------------------------------------\n' 

545 ) 

546 return fmt % self.__dict__ 

547 

548 def __repr__(self): 

549 c = self.__class__.__name__ 

550 d = self.__dict__.copy() 

551 d['klass'] = c 

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

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

554 

555 @property 

556 def smallest_normal(self): 

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

558 

559 Returns 

560 ------- 

561 smallest_normal : float 

562 Value for the smallest normal. 

563 

564 Warns 

565 ----- 

566 UserWarning 

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

568 double-double. 

569 """ 

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

571 # platform dependent for longdouble types. 

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

573 warnings.warn( 

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

575 UserWarning, stacklevel=2) 

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

577 

578 @property 

579 def tiny(self): 

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

581 

582 Returns 

583 ------- 

584 tiny : float 

585 Value for the smallest normal, alias of smallest_normal. 

586 

587 Warns 

588 ----- 

589 UserWarning 

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

591 double-double. 

592 """ 

593 return self.smallest_normal 

594 

595 

596@set_module('numpy') 

597class iinfo: 

598 """ 

599 iinfo(type) 

600 

601 Machine limits for integer types. 

602 

603 Attributes 

604 ---------- 

605 bits : int 

606 The number of bits occupied by the type. 

607 dtype : dtype 

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

609 min : int 

610 The smallest integer expressible by the type. 

611 max : int 

612 The largest integer expressible by the type. 

613 

614 Parameters 

615 ---------- 

616 int_type : integer type, dtype, or instance 

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

618 

619 See Also 

620 -------- 

621 finfo : The equivalent for floating point data types. 

622 

623 Examples 

624 -------- 

625 With types: 

626 

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

628 >>> ii16.min 

629 -32768 

630 >>> ii16.max 

631 32767 

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

633 >>> ii32.min 

634 -2147483648 

635 >>> ii32.max 

636 2147483647 

637 

638 With instances: 

639 

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

641 >>> ii32.min 

642 -2147483648 

643 >>> ii32.max 

644 2147483647 

645 

646 """ 

647 

648 _min_vals = {} 

649 _max_vals = {} 

650 

651 def __init__(self, int_type): 

652 try: 

653 self.dtype = numeric.dtype(int_type) 

654 except TypeError: 

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

656 self.kind = self.dtype.kind 

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

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

659 if self.kind not in 'iu': 

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

661 

662 @property 

663 def min(self): 

664 """Minimum value of given dtype.""" 

665 if self.kind == 'u': 

666 return 0 

667 else: 

668 try: 

669 val = iinfo._min_vals[self.key] 

670 except KeyError: 

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

672 iinfo._min_vals[self.key] = val 

673 return val 

674 

675 @property 

676 def max(self): 

677 """Maximum value of given dtype.""" 

678 try: 

679 val = iinfo._max_vals[self.key] 

680 except KeyError: 

681 if self.kind == 'u': 

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

683 else: 

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

685 iinfo._max_vals[self.key] = val 

686 return val 

687 

688 def __str__(self): 

689 """String representation.""" 

690 fmt = ( 

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

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

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

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

695 '---------------------------------------------------------------\n' 

696 ) 

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

698 

699 def __repr__(self): 

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

701 self.min, self.max, self.dtype)