1 | #![cfg(any(feature = "std", feature = "libm"))] |
---|---|

2 | |

3 | use core::ops::Neg; |

4 | |

5 | use crate::{Float, Num, NumCast}; |

6 | |

7 | // NOTE: These doctests have the same issue as those in src/float.rs. |

8 | // They're testing the inherent methods directly, and not those of `Real`. |

9 | |

10 | /// A trait for real number types that do not necessarily have |

11 | /// floating-point-specific characteristics such as NaN and infinity. |

12 | /// |

13 | /// See [this Wikipedia article](https://en.wikipedia.org/wiki/Real_data_type) |

14 | /// for a list of data types that could meaningfully implement this trait. |

15 | /// |

16 | /// This trait is only available with the `std` feature, or with the `libm` feature otherwise. |

17 | pub trait Real: Num + Copy + NumCast + PartialOrd + Neg<Output = Self> { |

18 | /// Returns the smallest finite value that this type can represent. |

19 | /// |

20 | /// ``` |

21 | /// use num_traits::real::Real; |

22 | /// use std::f64; |

23 | /// |

24 | /// let x: f64 = Real::min_value(); |

25 | /// |

26 | /// assert_eq!(x, f64::MIN); |

27 | /// ``` |

28 | fn min_value() -> Self; |

29 | |

30 | /// Returns the smallest positive, normalized value that this type can represent. |

31 | /// |

32 | /// ``` |

33 | /// use num_traits::real::Real; |

34 | /// use std::f64; |

35 | /// |

36 | /// let x: f64 = Real::min_positive_value(); |

37 | /// |

38 | /// assert_eq!(x, f64::MIN_POSITIVE); |

39 | /// ``` |

40 | fn min_positive_value() -> Self; |

41 | |

42 | /// Returns epsilon, a small positive value. |

43 | /// |

44 | /// ``` |

45 | /// use num_traits::real::Real; |

46 | /// use std::f64; |

47 | /// |

48 | /// let x: f64 = Real::epsilon(); |

49 | /// |

50 | /// assert_eq!(x, f64::EPSILON); |

51 | /// ``` |

52 | /// |

53 | /// # Panics |

54 | /// |

55 | /// The default implementation will panic if `f32::EPSILON` cannot |

56 | /// be cast to `Self`. |

57 | fn epsilon() -> Self; |

58 | |

59 | /// Returns the largest finite value that this type can represent. |

60 | /// |

61 | /// ``` |

62 | /// use num_traits::real::Real; |

63 | /// use std::f64; |

64 | /// |

65 | /// let x: f64 = Real::max_value(); |

66 | /// assert_eq!(x, f64::MAX); |

67 | /// ``` |

68 | fn max_value() -> Self; |

69 | |

70 | /// Returns the largest integer less than or equal to a number. |

71 | /// |

72 | /// ``` |

73 | /// use num_traits::real::Real; |

74 | /// |

75 | /// let f = 3.99; |

76 | /// let g = 3.0; |

77 | /// |

78 | /// assert_eq!(f.floor(), 3.0); |

79 | /// assert_eq!(g.floor(), 3.0); |

80 | /// ``` |

81 | fn floor(self) -> Self; |

82 | |

83 | /// Returns the smallest integer greater than or equal to a number. |

84 | /// |

85 | /// ``` |

86 | /// use num_traits::real::Real; |

87 | /// |

88 | /// let f = 3.01; |

89 | /// let g = 4.0; |

90 | /// |

91 | /// assert_eq!(f.ceil(), 4.0); |

92 | /// assert_eq!(g.ceil(), 4.0); |

93 | /// ``` |

94 | fn ceil(self) -> Self; |

95 | |

96 | /// Returns the nearest integer to a number. Round half-way cases away from |

97 | /// `0.0`. |

98 | /// |

99 | /// ``` |

100 | /// use num_traits::real::Real; |

101 | /// |

102 | /// let f = 3.3; |

103 | /// let g = -3.3; |

104 | /// |

105 | /// assert_eq!(f.round(), 3.0); |

106 | /// assert_eq!(g.round(), -3.0); |

107 | /// ``` |

108 | fn round(self) -> Self; |

109 | |

110 | /// Return the integer part of a number. |

111 | /// |

112 | /// ``` |

113 | /// use num_traits::real::Real; |

114 | /// |

115 | /// let f = 3.3; |

116 | /// let g = -3.7; |

117 | /// |

118 | /// assert_eq!(f.trunc(), 3.0); |

119 | /// assert_eq!(g.trunc(), -3.0); |

120 | /// ``` |

121 | fn trunc(self) -> Self; |

122 | |

123 | /// Returns the fractional part of a number. |

124 | /// |

125 | /// ``` |

126 | /// use num_traits::real::Real; |

127 | /// |

128 | /// let x = 3.5; |

129 | /// let y = -3.5; |

130 | /// let abs_difference_x = (x.fract() - 0.5).abs(); |

131 | /// let abs_difference_y = (y.fract() - (-0.5)).abs(); |

132 | /// |

133 | /// assert!(abs_difference_x < 1e-10); |

134 | /// assert!(abs_difference_y < 1e-10); |

135 | /// ``` |

136 | fn fract(self) -> Self; |

137 | |

138 | /// Computes the absolute value of `self`. Returns `Float::nan()` if the |

139 | /// number is `Float::nan()`. |

140 | /// |

141 | /// ``` |

142 | /// use num_traits::real::Real; |

143 | /// use std::f64; |

144 | /// |

145 | /// let x = 3.5; |

146 | /// let y = -3.5; |

147 | /// |

148 | /// let abs_difference_x = (x.abs() - x).abs(); |

149 | /// let abs_difference_y = (y.abs() - (-y)).abs(); |

150 | /// |

151 | /// assert!(abs_difference_x < 1e-10); |

152 | /// assert!(abs_difference_y < 1e-10); |

153 | /// |

154 | /// assert!(::num_traits::Float::is_nan(f64::NAN.abs())); |

155 | /// ``` |

156 | fn abs(self) -> Self; |

157 | |

158 | /// Returns a number that represents the sign of `self`. |

159 | /// |

160 | /// - `1.0` if the number is positive, `+0.0` or `Float::infinity()` |

161 | /// - `-1.0` if the number is negative, `-0.0` or `Float::neg_infinity()` |

162 | /// - `Float::nan()` if the number is `Float::nan()` |

163 | /// |

164 | /// ``` |

165 | /// use num_traits::real::Real; |

166 | /// use std::f64; |

167 | /// |

168 | /// let f = 3.5; |

169 | /// |

170 | /// assert_eq!(f.signum(), 1.0); |

171 | /// assert_eq!(f64::NEG_INFINITY.signum(), -1.0); |

172 | /// |

173 | /// assert!(f64::NAN.signum().is_nan()); |

174 | /// ``` |

175 | fn signum(self) -> Self; |

176 | |

177 | /// Returns `true` if `self` is positive, including `+0.0`, |

178 | /// `Float::infinity()`, and with newer versions of Rust `f64::NAN`. |

179 | /// |

180 | /// ``` |

181 | /// use num_traits::real::Real; |

182 | /// use std::f64; |

183 | /// |

184 | /// let neg_nan: f64 = -f64::NAN; |

185 | /// |

186 | /// let f = 7.0; |

187 | /// let g = -7.0; |

188 | /// |

189 | /// assert!(f.is_sign_positive()); |

190 | /// assert!(!g.is_sign_positive()); |

191 | /// assert!(!neg_nan.is_sign_positive()); |

192 | /// ``` |

193 | fn is_sign_positive(self) -> bool; |

194 | |

195 | /// Returns `true` if `self` is negative, including `-0.0`, |

196 | /// `Float::neg_infinity()`, and with newer versions of Rust `-f64::NAN`. |

197 | /// |

198 | /// ``` |

199 | /// use num_traits::real::Real; |

200 | /// use std::f64; |

201 | /// |

202 | /// let nan: f64 = f64::NAN; |

203 | /// |

204 | /// let f = 7.0; |

205 | /// let g = -7.0; |

206 | /// |

207 | /// assert!(!f.is_sign_negative()); |

208 | /// assert!(g.is_sign_negative()); |

209 | /// assert!(!nan.is_sign_negative()); |

210 | /// ``` |

211 | fn is_sign_negative(self) -> bool; |

212 | |

213 | /// Fused multiply-add. Computes `(self * a) + b` with only one rounding |

214 | /// error, yielding a more accurate result than an unfused multiply-add. |

215 | /// |

216 | /// Using `mul_add` can be more performant than an unfused multiply-add if |

217 | /// the target architecture has a dedicated `fma` CPU instruction. |

218 | /// |

219 | /// ``` |

220 | /// use num_traits::real::Real; |

221 | /// |

222 | /// let m = 10.0; |

223 | /// let x = 4.0; |

224 | /// let b = 60.0; |

225 | /// |

226 | /// // 100.0 |

227 | /// let abs_difference = (m.mul_add(x, b) - (m*x + b)).abs(); |

228 | /// |

229 | /// assert!(abs_difference < 1e-10); |

230 | /// ``` |

231 | fn mul_add(self, a: Self, b: Self) -> Self; |

232 | |

233 | /// Take the reciprocal (inverse) of a number, `1/x`. |

234 | /// |

235 | /// ``` |

236 | /// use num_traits::real::Real; |

237 | /// |

238 | /// let x = 2.0; |

239 | /// let abs_difference = (x.recip() - (1.0/x)).abs(); |

240 | /// |

241 | /// assert!(abs_difference < 1e-10); |

242 | /// ``` |

243 | fn recip(self) -> Self; |

244 | |

245 | /// Raise a number to an integer power. |

246 | /// |

247 | /// Using this function is generally faster than using `powf` |

248 | /// |

249 | /// ``` |

250 | /// use num_traits::real::Real; |

251 | /// |

252 | /// let x = 2.0; |

253 | /// let abs_difference = (x.powi(2) - x*x).abs(); |

254 | /// |

255 | /// assert!(abs_difference < 1e-10); |

256 | /// ``` |

257 | fn powi(self, n: i32) -> Self; |

258 | |

259 | /// Raise a number to a real number power. |

260 | /// |

261 | /// ``` |

262 | /// use num_traits::real::Real; |

263 | /// |

264 | /// let x = 2.0; |

265 | /// let abs_difference = (x.powf(2.0) - x*x).abs(); |

266 | /// |

267 | /// assert!(abs_difference < 1e-10); |

268 | /// ``` |

269 | fn powf(self, n: Self) -> Self; |

270 | |

271 | /// Take the square root of a number. |

272 | /// |

273 | /// Returns NaN if `self` is a negative floating-point number. |

274 | /// |

275 | /// # Panics |

276 | /// |

277 | /// If the implementing type doesn't support NaN, this method should panic if `self < 0`. |

278 | /// |

279 | /// ``` |

280 | /// use num_traits::real::Real; |

281 | /// |

282 | /// let positive = 4.0; |

283 | /// let negative = -4.0; |

284 | /// |

285 | /// let abs_difference = (positive.sqrt() - 2.0).abs(); |

286 | /// |

287 | /// assert!(abs_difference < 1e-10); |

288 | /// assert!(::num_traits::Float::is_nan(negative.sqrt())); |

289 | /// ``` |

290 | fn sqrt(self) -> Self; |

291 | |

292 | /// Returns `e^(self)`, (the exponential function). |

293 | /// |

294 | /// ``` |

295 | /// use num_traits::real::Real; |

296 | /// |

297 | /// let one = 1.0; |

298 | /// // e^1 |

299 | /// let e = one.exp(); |

300 | /// |

301 | /// // ln(e) - 1 == 0 |

302 | /// let abs_difference = (e.ln() - 1.0).abs(); |

303 | /// |

304 | /// assert!(abs_difference < 1e-10); |

305 | /// ``` |

306 | fn exp(self) -> Self; |

307 | |

308 | /// Returns `2^(self)`. |

309 | /// |

310 | /// ``` |

311 | /// use num_traits::real::Real; |

312 | /// |

313 | /// let f = 2.0; |

314 | /// |

315 | /// // 2^2 - 4 == 0 |

316 | /// let abs_difference = (f.exp2() - 4.0).abs(); |

317 | /// |

318 | /// assert!(abs_difference < 1e-10); |

319 | /// ``` |

320 | fn exp2(self) -> Self; |

321 | |

322 | /// Returns the natural logarithm of the number. |

323 | /// |

324 | /// # Panics |

325 | /// |

326 | /// If `self <= 0` and this type does not support a NaN representation, this function should panic. |

327 | /// |

328 | /// ``` |

329 | /// use num_traits::real::Real; |

330 | /// |

331 | /// let one = 1.0; |

332 | /// // e^1 |

333 | /// let e = one.exp(); |

334 | /// |

335 | /// // ln(e) - 1 == 0 |

336 | /// let abs_difference = (e.ln() - 1.0).abs(); |

337 | /// |

338 | /// assert!(abs_difference < 1e-10); |

339 | /// ``` |

340 | fn ln(self) -> Self; |

341 | |

342 | /// Returns the logarithm of the number with respect to an arbitrary base. |

343 | /// |

344 | /// # Panics |

345 | /// |

346 | /// If `self <= 0` and this type does not support a NaN representation, this function should panic. |

347 | /// |

348 | /// ``` |

349 | /// use num_traits::real::Real; |

350 | /// |

351 | /// let ten = 10.0; |

352 | /// let two = 2.0; |

353 | /// |

354 | /// // log10(10) - 1 == 0 |

355 | /// let abs_difference_10 = (ten.log(10.0) - 1.0).abs(); |

356 | /// |

357 | /// // log2(2) - 1 == 0 |

358 | /// let abs_difference_2 = (two.log(2.0) - 1.0).abs(); |

359 | /// |

360 | /// assert!(abs_difference_10 < 1e-10); |

361 | /// assert!(abs_difference_2 < 1e-10); |

362 | /// ``` |

363 | fn log(self, base: Self) -> Self; |

364 | |

365 | /// Returns the base 2 logarithm of the number. |

366 | /// |

367 | /// # Panics |

368 | /// |

369 | /// If `self <= 0` and this type does not support a NaN representation, this function should panic. |

370 | /// |

371 | /// ``` |

372 | /// use num_traits::real::Real; |

373 | /// |

374 | /// let two = 2.0; |

375 | /// |

376 | /// // log2(2) - 1 == 0 |

377 | /// let abs_difference = (two.log2() - 1.0).abs(); |

378 | /// |

379 | /// assert!(abs_difference < 1e-10); |

380 | /// ``` |

381 | fn log2(self) -> Self; |

382 | |

383 | /// Returns the base 10 logarithm of the number. |

384 | /// |

385 | /// # Panics |

386 | /// |

387 | /// If `self <= 0` and this type does not support a NaN representation, this function should panic. |

388 | /// |

389 | /// |

390 | /// ``` |

391 | /// use num_traits::real::Real; |

392 | /// |

393 | /// let ten = 10.0; |

394 | /// |

395 | /// // log10(10) - 1 == 0 |

396 | /// let abs_difference = (ten.log10() - 1.0).abs(); |

397 | /// |

398 | /// assert!(abs_difference < 1e-10); |

399 | /// ``` |

400 | fn log10(self) -> Self; |

401 | |

402 | /// Converts radians to degrees. |

403 | /// |

404 | /// ``` |

405 | /// use std::f64::consts; |

406 | /// |

407 | /// let angle = consts::PI; |

408 | /// |

409 | /// let abs_difference = (angle.to_degrees() - 180.0).abs(); |

410 | /// |

411 | /// assert!(abs_difference < 1e-10); |

412 | /// ``` |

413 | fn to_degrees(self) -> Self; |

414 | |

415 | /// Converts degrees to radians. |

416 | /// |

417 | /// ``` |

418 | /// use std::f64::consts; |

419 | /// |

420 | /// let angle = 180.0_f64; |

421 | /// |

422 | /// let abs_difference = (angle.to_radians() - consts::PI).abs(); |

423 | /// |

424 | /// assert!(abs_difference < 1e-10); |

425 | /// ``` |

426 | fn to_radians(self) -> Self; |

427 | |

428 | /// Returns the maximum of the two numbers. |

429 | /// |

430 | /// ``` |

431 | /// use num_traits::real::Real; |

432 | /// |

433 | /// let x = 1.0; |

434 | /// let y = 2.0; |

435 | /// |

436 | /// assert_eq!(x.max(y), y); |

437 | /// ``` |

438 | fn max(self, other: Self) -> Self; |

439 | |

440 | /// Returns the minimum of the two numbers. |

441 | /// |

442 | /// ``` |

443 | /// use num_traits::real::Real; |

444 | /// |

445 | /// let x = 1.0; |

446 | /// let y = 2.0; |

447 | /// |

448 | /// assert_eq!(x.min(y), x); |

449 | /// ``` |

450 | fn min(self, other: Self) -> Self; |

451 | |

452 | /// The positive difference of two numbers. |

453 | /// |

454 | /// * If `self <= other`: `0:0` |

455 | /// * Else: `self - other` |

456 | /// |

457 | /// ``` |

458 | /// use num_traits::real::Real; |

459 | /// |

460 | /// let x = 3.0; |

461 | /// let y = -3.0; |

462 | /// |

463 | /// let abs_difference_x = (x.abs_sub(1.0) - 2.0).abs(); |

464 | /// let abs_difference_y = (y.abs_sub(1.0) - 0.0).abs(); |

465 | /// |

466 | /// assert!(abs_difference_x < 1e-10); |

467 | /// assert!(abs_difference_y < 1e-10); |

468 | /// ``` |

469 | fn abs_sub(self, other: Self) -> Self; |

470 | |

471 | /// Take the cubic root of a number. |

472 | /// |

473 | /// ``` |

474 | /// use num_traits::real::Real; |

475 | /// |

476 | /// let x = 8.0; |

477 | /// |

478 | /// // x^(1/3) - 2 == 0 |

479 | /// let abs_difference = (x.cbrt() - 2.0).abs(); |

480 | /// |

481 | /// assert!(abs_difference < 1e-10); |

482 | /// ``` |

483 | fn cbrt(self) -> Self; |

484 | |

485 | /// Calculate the length of the hypotenuse of a right-angle triangle given |

486 | /// legs of length `x` and `y`. |

487 | /// |

488 | /// ``` |

489 | /// use num_traits::real::Real; |

490 | /// |

491 | /// let x = 2.0; |

492 | /// let y = 3.0; |

493 | /// |

494 | /// // sqrt(x^2 + y^2) |

495 | /// let abs_difference = (x.hypot(y) - (x.powi(2) + y.powi(2)).sqrt()).abs(); |

496 | /// |

497 | /// assert!(abs_difference < 1e-10); |

498 | /// ``` |

499 | fn hypot(self, other: Self) -> Self; |

500 | |

501 | /// Computes the sine of a number (in radians). |

502 | /// |

503 | /// ``` |

504 | /// use num_traits::real::Real; |

505 | /// use std::f64; |

506 | /// |

507 | /// let x = f64::consts::PI/2.0; |

508 | /// |

509 | /// let abs_difference = (x.sin() - 1.0).abs(); |

510 | /// |

511 | /// assert!(abs_difference < 1e-10); |

512 | /// ``` |

513 | fn sin(self) -> Self; |

514 | |

515 | /// Computes the cosine of a number (in radians). |

516 | /// |

517 | /// ``` |

518 | /// use num_traits::real::Real; |

519 | /// use std::f64; |

520 | /// |

521 | /// let x = 2.0*f64::consts::PI; |

522 | /// |

523 | /// let abs_difference = (x.cos() - 1.0).abs(); |

524 | /// |

525 | /// assert!(abs_difference < 1e-10); |

526 | /// ``` |

527 | fn cos(self) -> Self; |

528 | |

529 | /// Computes the tangent of a number (in radians). |

530 | /// |

531 | /// ``` |

532 | /// use num_traits::real::Real; |

533 | /// use std::f64; |

534 | /// |

535 | /// let x = f64::consts::PI/4.0; |

536 | /// let abs_difference = (x.tan() - 1.0).abs(); |

537 | /// |

538 | /// assert!(abs_difference < 1e-14); |

539 | /// ``` |

540 | fn tan(self) -> Self; |

541 | |

542 | /// Computes the arcsine of a number. Return value is in radians in |

543 | /// the range [-pi/2, pi/2] or NaN if the number is outside the range |

544 | /// [-1, 1]. |

545 | /// |

546 | /// # Panics |

547 | /// |

548 | /// If this type does not support a NaN representation, this function should panic |

549 | /// if the number is outside the range [-1, 1]. |

550 | /// |

551 | /// ``` |

552 | /// use num_traits::real::Real; |

553 | /// use std::f64; |

554 | /// |

555 | /// let f = f64::consts::PI / 2.0; |

556 | /// |

557 | /// // asin(sin(pi/2)) |

558 | /// let abs_difference = (f.sin().asin() - f64::consts::PI / 2.0).abs(); |

559 | /// |

560 | /// assert!(abs_difference < 1e-10); |

561 | /// ``` |

562 | fn asin(self) -> Self; |

563 | |

564 | /// Computes the arccosine of a number. Return value is in radians in |

565 | /// the range [0, pi] or NaN if the number is outside the range |

566 | /// [-1, 1]. |

567 | /// |

568 | /// # Panics |

569 | /// |

570 | /// If this type does not support a NaN representation, this function should panic |

571 | /// if the number is outside the range [-1, 1]. |

572 | /// |

573 | /// ``` |

574 | /// use num_traits::real::Real; |

575 | /// use std::f64; |

576 | /// |

577 | /// let f = f64::consts::PI / 4.0; |

578 | /// |

579 | /// // acos(cos(pi/4)) |

580 | /// let abs_difference = (f.cos().acos() - f64::consts::PI / 4.0).abs(); |

581 | /// |

582 | /// assert!(abs_difference < 1e-10); |

583 | /// ``` |

584 | fn acos(self) -> Self; |

585 | |

586 | /// Computes the arctangent of a number. Return value is in radians in the |

587 | /// range [-pi/2, pi/2]; |

588 | /// |

589 | /// ``` |

590 | /// use num_traits::real::Real; |

591 | /// |

592 | /// let f = 1.0; |

593 | /// |

594 | /// // atan(tan(1)) |

595 | /// let abs_difference = (f.tan().atan() - 1.0).abs(); |

596 | /// |

597 | /// assert!(abs_difference < 1e-10); |

598 | /// ``` |

599 | fn atan(self) -> Self; |

600 | |

601 | /// Computes the four quadrant arctangent of `self` (`y`) and `other` (`x`). |

602 | /// |

603 | /// * `x = 0`, `y = 0`: `0` |

604 | /// * `x >= 0`: `arctan(y/x)` -> `[-pi/2, pi/2]` |

605 | /// * `y >= 0`: `arctan(y/x) + pi` -> `(pi/2, pi]` |

606 | /// * `y < 0`: `arctan(y/x) - pi` -> `(-pi, -pi/2)` |

607 | /// |

608 | /// ``` |

609 | /// use num_traits::real::Real; |

610 | /// use std::f64; |

611 | /// |

612 | /// let pi = f64::consts::PI; |

613 | /// // All angles from horizontal right (+x) |

614 | /// // 45 deg counter-clockwise |

615 | /// let x1 = 3.0; |

616 | /// let y1 = -3.0; |

617 | /// |

618 | /// // 135 deg clockwise |

619 | /// let x2 = -3.0; |

620 | /// let y2 = 3.0; |

621 | /// |

622 | /// let abs_difference_1 = (y1.atan2(x1) - (-pi/4.0)).abs(); |

623 | /// let abs_difference_2 = (y2.atan2(x2) - 3.0*pi/4.0).abs(); |

624 | /// |

625 | /// assert!(abs_difference_1 < 1e-10); |

626 | /// assert!(abs_difference_2 < 1e-10); |

627 | /// ``` |

628 | fn atan2(self, other: Self) -> Self; |

629 | |

630 | /// Simultaneously computes the sine and cosine of the number, `x`. Returns |

631 | /// `(sin(x), cos(x))`. |

632 | /// |

633 | /// ``` |

634 | /// use num_traits::real::Real; |

635 | /// use std::f64; |

636 | /// |

637 | /// let x = f64::consts::PI/4.0; |

638 | /// let f = x.sin_cos(); |

639 | /// |

640 | /// let abs_difference_0 = (f.0 - x.sin()).abs(); |

641 | /// let abs_difference_1 = (f.1 - x.cos()).abs(); |

642 | /// |

643 | /// assert!(abs_difference_0 < 1e-10); |

644 | /// assert!(abs_difference_0 < 1e-10); |

645 | /// ``` |

646 | fn sin_cos(self) -> (Self, Self); |

647 | |

648 | /// Returns `e^(self) - 1` in a way that is accurate even if the |

649 | /// number is close to zero. |

650 | /// |

651 | /// ``` |

652 | /// use num_traits::real::Real; |

653 | /// |

654 | /// let x = 7.0; |

655 | /// |

656 | /// // e^(ln(7)) - 1 |

657 | /// let abs_difference = (x.ln().exp_m1() - 6.0).abs(); |

658 | /// |

659 | /// assert!(abs_difference < 1e-10); |

660 | /// ``` |

661 | fn exp_m1(self) -> Self; |

662 | |

663 | /// Returns `ln(1+n)` (natural logarithm) more accurately than if |

664 | /// the operations were performed separately. |

665 | /// |

666 | /// # Panics |

667 | /// |

668 | /// If this type does not support a NaN representation, this function should panic |

669 | /// if `self-1 <= 0`. |

670 | /// |

671 | /// ``` |

672 | /// use num_traits::real::Real; |

673 | /// use std::f64; |

674 | /// |

675 | /// let x = f64::consts::E - 1.0; |

676 | /// |

677 | /// // ln(1 + (e - 1)) == ln(e) == 1 |

678 | /// let abs_difference = (x.ln_1p() - 1.0).abs(); |

679 | /// |

680 | /// assert!(abs_difference < 1e-10); |

681 | /// ``` |

682 | fn ln_1p(self) -> Self; |

683 | |

684 | /// Hyperbolic sine function. |

685 | /// |

686 | /// ``` |

687 | /// use num_traits::real::Real; |

688 | /// use std::f64; |

689 | /// |

690 | /// let e = f64::consts::E; |

691 | /// let x = 1.0; |

692 | /// |

693 | /// let f = x.sinh(); |

694 | /// // Solving sinh() at 1 gives `(e^2-1)/(2e)` |

695 | /// let g = (e*e - 1.0)/(2.0*e); |

696 | /// let abs_difference = (f - g).abs(); |

697 | /// |

698 | /// assert!(abs_difference < 1e-10); |

699 | /// ``` |

700 | fn sinh(self) -> Self; |

701 | |

702 | /// Hyperbolic cosine function. |

703 | /// |

704 | /// ``` |

705 | /// use num_traits::real::Real; |

706 | /// use std::f64; |

707 | /// |

708 | /// let e = f64::consts::E; |

709 | /// let x = 1.0; |

710 | /// let f = x.cosh(); |

711 | /// // Solving cosh() at 1 gives this result |

712 | /// let g = (e*e + 1.0)/(2.0*e); |

713 | /// let abs_difference = (f - g).abs(); |

714 | /// |

715 | /// // Same result |

716 | /// assert!(abs_difference < 1.0e-10); |

717 | /// ``` |

718 | fn cosh(self) -> Self; |

719 | |

720 | /// Hyperbolic tangent function. |

721 | /// |

722 | /// ``` |

723 | /// use num_traits::real::Real; |

724 | /// use std::f64; |

725 | /// |

726 | /// let e = f64::consts::E; |

727 | /// let x = 1.0; |

728 | /// |

729 | /// let f = x.tanh(); |

730 | /// // Solving tanh() at 1 gives `(1 - e^(-2))/(1 + e^(-2))` |

731 | /// let g = (1.0 - e.powi(-2))/(1.0 + e.powi(-2)); |

732 | /// let abs_difference = (f - g).abs(); |

733 | /// |

734 | /// assert!(abs_difference < 1.0e-10); |

735 | /// ``` |

736 | fn tanh(self) -> Self; |

737 | |

738 | /// Inverse hyperbolic sine function. |

739 | /// |

740 | /// ``` |

741 | /// use num_traits::real::Real; |

742 | /// |

743 | /// let x = 1.0; |

744 | /// let f = x.sinh().asinh(); |

745 | /// |

746 | /// let abs_difference = (f - x).abs(); |

747 | /// |

748 | /// assert!(abs_difference < 1.0e-10); |

749 | /// ``` |

750 | fn asinh(self) -> Self; |

751 | |

752 | /// Inverse hyperbolic cosine function. |

753 | /// |

754 | /// ``` |

755 | /// use num_traits::real::Real; |

756 | /// |

757 | /// let x = 1.0; |

758 | /// let f = x.cosh().acosh(); |

759 | /// |

760 | /// let abs_difference = (f - x).abs(); |

761 | /// |

762 | /// assert!(abs_difference < 1.0e-10); |

763 | /// ``` |

764 | fn acosh(self) -> Self; |

765 | |

766 | /// Inverse hyperbolic tangent function. |

767 | /// |

768 | /// ``` |

769 | /// use num_traits::real::Real; |

770 | /// use std::f64; |

771 | /// |

772 | /// let e = f64::consts::E; |

773 | /// let f = e.tanh().atanh(); |

774 | /// |

775 | /// let abs_difference = (f - e).abs(); |

776 | /// |

777 | /// assert!(abs_difference < 1.0e-10); |

778 | /// ``` |

779 | fn atanh(self) -> Self; |

780 | } |

781 | |

782 | impl<T: Float> Real for T { |

783 | forward! { |

784 | Float::min_value() -> Self; |

785 | Float::min_positive_value() -> Self; |

786 | Float::epsilon() -> Self; |

787 | Float::max_value() -> Self; |

788 | } |

789 | forward! { |

790 | Float::floor(self) -> Self; |

791 | Float::ceil(self) -> Self; |

792 | Float::round(self) -> Self; |

793 | Float::trunc(self) -> Self; |

794 | Float::fract(self) -> Self; |

795 | Float::abs(self) -> Self; |

796 | Float::signum(self) -> Self; |

797 | Float::is_sign_positive(self) -> bool; |

798 | Float::is_sign_negative(self) -> bool; |

799 | Float::mul_add(self, a: Self, b: Self) -> Self; |

800 | Float::recip(self) -> Self; |

801 | Float::powi(self, n: i32) -> Self; |

802 | Float::powf(self, n: Self) -> Self; |

803 | Float::sqrt(self) -> Self; |

804 | Float::exp(self) -> Self; |

805 | Float::exp2(self) -> Self; |

806 | Float::ln(self) -> Self; |

807 | Float::log(self, base: Self) -> Self; |

808 | Float::log2(self) -> Self; |

809 | Float::log10(self) -> Self; |

810 | Float::to_degrees(self) -> Self; |

811 | Float::to_radians(self) -> Self; |

812 | Float::max(self, other: Self) -> Self; |

813 | Float::min(self, other: Self) -> Self; |

814 | Float::abs_sub(self, other: Self) -> Self; |

815 | Float::cbrt(self) -> Self; |

816 | Float::hypot(self, other: Self) -> Self; |

817 | Float::sin(self) -> Self; |

818 | Float::cos(self) -> Self; |

819 | Float::tan(self) -> Self; |

820 | Float::asin(self) -> Self; |

821 | Float::acos(self) -> Self; |

822 | Float::atan(self) -> Self; |

823 | Float::atan2(self, other: Self) -> Self; |

824 | Float::sin_cos(self) -> (Self, Self); |

825 | Float::exp_m1(self) -> Self; |

826 | Float::ln_1p(self) -> Self; |

827 | Float::sinh(self) -> Self; |

828 | Float::cosh(self) -> Self; |

829 | Float::tanh(self) -> Self; |

830 | Float::asinh(self) -> Self; |

831 | Float::acosh(self) -> Self; |

832 | Float::atanh(self) -> Self; |

833 | } |

834 | } |

835 |