1 | use core::num::FpCategory; |
---|---|

2 | use core::ops::{Add, Div, Neg}; |

3 | |

4 | use core::f32; |

5 | use core::f64; |

6 | |

7 | use crate::{Num, NumCast, ToPrimitive}; |

8 | |

9 | /// Generic trait for floating point numbers that works with `no_std`. |

10 | /// |

11 | /// This trait implements a subset of the `Float` trait. |

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

13 | /// Returns positive infinity. |

14 | /// |

15 | /// # Examples |

16 | /// |

17 | /// ``` |

18 | /// use num_traits::float::FloatCore; |

19 | /// use std::{f32, f64}; |

20 | /// |

21 | /// fn check<T: FloatCore>(x: T) { |

22 | /// assert!(T::infinity() == x); |

23 | /// } |

24 | /// |

25 | /// check(f32::INFINITY); |

26 | /// check(f64::INFINITY); |

27 | /// ``` |

28 | fn infinity() -> Self; |

29 | |

30 | /// Returns negative infinity. |

31 | /// |

32 | /// # Examples |

33 | /// |

34 | /// ``` |

35 | /// use num_traits::float::FloatCore; |

36 | /// use std::{f32, f64}; |

37 | /// |

38 | /// fn check<T: FloatCore>(x: T) { |

39 | /// assert!(T::neg_infinity() == x); |

40 | /// } |

41 | /// |

42 | /// check(f32::NEG_INFINITY); |

43 | /// check(f64::NEG_INFINITY); |

44 | /// ``` |

45 | fn neg_infinity() -> Self; |

46 | |

47 | /// Returns NaN. |

48 | /// |

49 | /// # Examples |

50 | /// |

51 | /// ``` |

52 | /// use num_traits::float::FloatCore; |

53 | /// |

54 | /// fn check<T: FloatCore>() { |

55 | /// let n = T::nan(); |

56 | /// assert!(n != n); |

57 | /// } |

58 | /// |

59 | /// check::<f32>(); |

60 | /// check::<f64>(); |

61 | /// ``` |

62 | fn nan() -> Self; |

63 | |

64 | /// Returns `-0.0`. |

65 | /// |

66 | /// # Examples |

67 | /// |

68 | /// ``` |

69 | /// use num_traits::float::FloatCore; |

70 | /// use std::{f32, f64}; |

71 | /// |

72 | /// fn check<T: FloatCore>(n: T) { |

73 | /// let z = T::neg_zero(); |

74 | /// assert!(z.is_zero()); |

75 | /// assert!(T::one() / z == n); |

76 | /// } |

77 | /// |

78 | /// check(f32::NEG_INFINITY); |

79 | /// check(f64::NEG_INFINITY); |

80 | /// ``` |

81 | fn neg_zero() -> Self; |

82 | |

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

84 | /// |

85 | /// # Examples |

86 | /// |

87 | /// ``` |

88 | /// use num_traits::float::FloatCore; |

89 | /// use std::{f32, f64}; |

90 | /// |

91 | /// fn check<T: FloatCore>(x: T) { |

92 | /// assert!(T::min_value() == x); |

93 | /// } |

94 | /// |

95 | /// check(f32::MIN); |

96 | /// check(f64::MIN); |

97 | /// ``` |

98 | fn min_value() -> Self; |

99 | |

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

101 | /// |

102 | /// # Examples |

103 | /// |

104 | /// ``` |

105 | /// use num_traits::float::FloatCore; |

106 | /// use std::{f32, f64}; |

107 | /// |

108 | /// fn check<T: FloatCore>(x: T) { |

109 | /// assert!(T::min_positive_value() == x); |

110 | /// } |

111 | /// |

112 | /// check(f32::MIN_POSITIVE); |

113 | /// check(f64::MIN_POSITIVE); |

114 | /// ``` |

115 | fn min_positive_value() -> Self; |

116 | |

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

118 | /// |

119 | /// # Examples |

120 | /// |

121 | /// ``` |

122 | /// use num_traits::float::FloatCore; |

123 | /// use std::{f32, f64}; |

124 | /// |

125 | /// fn check<T: FloatCore>(x: T) { |

126 | /// assert!(T::epsilon() == x); |

127 | /// } |

128 | /// |

129 | /// check(f32::EPSILON); |

130 | /// check(f64::EPSILON); |

131 | /// ``` |

132 | fn epsilon() -> Self; |

133 | |

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

135 | /// |

136 | /// # Examples |

137 | /// |

138 | /// ``` |

139 | /// use num_traits::float::FloatCore; |

140 | /// use std::{f32, f64}; |

141 | /// |

142 | /// fn check<T: FloatCore>(x: T) { |

143 | /// assert!(T::max_value() == x); |

144 | /// } |

145 | /// |

146 | /// check(f32::MAX); |

147 | /// check(f64::MAX); |

148 | /// ``` |

149 | fn max_value() -> Self; |

150 | |

151 | /// Returns `true` if the number is NaN. |

152 | /// |

153 | /// # Examples |

154 | /// |

155 | /// ``` |

156 | /// use num_traits::float::FloatCore; |

157 | /// use std::{f32, f64}; |

158 | /// |

159 | /// fn check<T: FloatCore>(x: T, p: bool) { |

160 | /// assert!(x.is_nan() == p); |

161 | /// } |

162 | /// |

163 | /// check(f32::NAN, true); |

164 | /// check(f32::INFINITY, false); |

165 | /// check(f64::NAN, true); |

166 | /// check(0.0f64, false); |

167 | /// ``` |

168 | #[inline] |

169 | #[allow(clippy::eq_op)] |

170 | fn is_nan(self) -> bool { |

171 | self != self |

172 | } |

173 | |

174 | /// Returns `true` if the number is infinite. |

175 | /// |

176 | /// # Examples |

177 | /// |

178 | /// ``` |

179 | /// use num_traits::float::FloatCore; |

180 | /// use std::{f32, f64}; |

181 | /// |

182 | /// fn check<T: FloatCore>(x: T, p: bool) { |

183 | /// assert!(x.is_infinite() == p); |

184 | /// } |

185 | /// |

186 | /// check(f32::INFINITY, true); |

187 | /// check(f32::NEG_INFINITY, true); |

188 | /// check(f32::NAN, false); |

189 | /// check(f64::INFINITY, true); |

190 | /// check(f64::NEG_INFINITY, true); |

191 | /// check(0.0f64, false); |

192 | /// ``` |

193 | #[inline] |

194 | fn is_infinite(self) -> bool { |

195 | self == Self::infinity() || self == Self::neg_infinity() |

196 | } |

197 | |

198 | /// Returns `true` if the number is neither infinite or NaN. |

199 | /// |

200 | /// # Examples |

201 | /// |

202 | /// ``` |

203 | /// use num_traits::float::FloatCore; |

204 | /// use std::{f32, f64}; |

205 | /// |

206 | /// fn check<T: FloatCore>(x: T, p: bool) { |

207 | /// assert!(x.is_finite() == p); |

208 | /// } |

209 | /// |

210 | /// check(f32::INFINITY, false); |

211 | /// check(f32::MAX, true); |

212 | /// check(f64::NEG_INFINITY, false); |

213 | /// check(f64::MIN_POSITIVE, true); |

214 | /// check(f64::NAN, false); |

215 | /// ``` |

216 | #[inline] |

217 | fn is_finite(self) -> bool { |

218 | !(self.is_nan() || self.is_infinite()) |

219 | } |

220 | |

221 | /// Returns `true` if the number is neither zero, infinite, subnormal or NaN. |

222 | /// |

223 | /// # Examples |

224 | /// |

225 | /// ``` |

226 | /// use num_traits::float::FloatCore; |

227 | /// use std::{f32, f64}; |

228 | /// |

229 | /// fn check<T: FloatCore>(x: T, p: bool) { |

230 | /// assert!(x.is_normal() == p); |

231 | /// } |

232 | /// |

233 | /// check(f32::INFINITY, false); |

234 | /// check(f32::MAX, true); |

235 | /// check(f64::NEG_INFINITY, false); |

236 | /// check(f64::MIN_POSITIVE, true); |

237 | /// check(0.0f64, false); |

238 | /// ``` |

239 | #[inline] |

240 | fn is_normal(self) -> bool { |

241 | self.classify() == FpCategory::Normal |

242 | } |

243 | |

244 | /// Returns `true` if the number is [subnormal]. |

245 | /// |

246 | /// ``` |

247 | /// use num_traits::float::FloatCore; |

248 | /// use std::f64; |

249 | /// |

250 | /// let min = f64::MIN_POSITIVE; // 2.2250738585072014e-308_f64 |

251 | /// let max = f64::MAX; |

252 | /// let lower_than_min = 1.0e-308_f64; |

253 | /// let zero = 0.0_f64; |

254 | /// |

255 | /// assert!(!min.is_subnormal()); |

256 | /// assert!(!max.is_subnormal()); |

257 | /// |

258 | /// assert!(!zero.is_subnormal()); |

259 | /// assert!(!f64::NAN.is_subnormal()); |

260 | /// assert!(!f64::INFINITY.is_subnormal()); |

261 | /// // Values between `0` and `min` are Subnormal. |

262 | /// assert!(lower_than_min.is_subnormal()); |

263 | /// ``` |

264 | /// [subnormal]: https://en.wikipedia.org/wiki/Subnormal_number |

265 | #[inline] |

266 | fn is_subnormal(self) -> bool { |

267 | self.classify() == FpCategory::Subnormal |

268 | } |

269 | |

270 | /// Returns the floating point category of the number. If only one property |

271 | /// is going to be tested, it is generally faster to use the specific |

272 | /// predicate instead. |

273 | /// |

274 | /// # Examples |

275 | /// |

276 | /// ``` |

277 | /// use num_traits::float::FloatCore; |

278 | /// use std::{f32, f64}; |

279 | /// use std::num::FpCategory; |

280 | /// |

281 | /// fn check<T: FloatCore>(x: T, c: FpCategory) { |

282 | /// assert!(x.classify() == c); |

283 | /// } |

284 | /// |

285 | /// check(f32::INFINITY, FpCategory::Infinite); |

286 | /// check(f32::MAX, FpCategory::Normal); |

287 | /// check(f64::NAN, FpCategory::Nan); |

288 | /// check(f64::MIN_POSITIVE, FpCategory::Normal); |

289 | /// check(f64::MIN_POSITIVE / 2.0, FpCategory::Subnormal); |

290 | /// check(0.0f64, FpCategory::Zero); |

291 | /// ``` |

292 | fn classify(self) -> FpCategory; |

293 | |

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

295 | /// |

296 | /// # Examples |

297 | /// |

298 | /// ``` |

299 | /// use num_traits::float::FloatCore; |

300 | /// use std::{f32, f64}; |

301 | /// |

302 | /// fn check<T: FloatCore>(x: T, y: T) { |

303 | /// assert!(x.floor() == y); |

304 | /// } |

305 | /// |

306 | /// check(f32::INFINITY, f32::INFINITY); |

307 | /// check(0.9f32, 0.0); |

308 | /// check(1.0f32, 1.0); |

309 | /// check(1.1f32, 1.0); |

310 | /// check(-0.0f64, 0.0); |

311 | /// check(-0.9f64, -1.0); |

312 | /// check(-1.0f64, -1.0); |

313 | /// check(-1.1f64, -2.0); |

314 | /// check(f64::MIN, f64::MIN); |

315 | /// ``` |

316 | #[inline] |

317 | fn floor(self) -> Self { |

318 | let f = self.fract(); |

319 | if f.is_nan() || f.is_zero() { |

320 | self |

321 | } else if self < Self::zero() { |

322 | self - f - Self::one() |

323 | } else { |

324 | self - f |

325 | } |

326 | } |

327 | |

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

329 | /// |

330 | /// # Examples |

331 | /// |

332 | /// ``` |

333 | /// use num_traits::float::FloatCore; |

334 | /// use std::{f32, f64}; |

335 | /// |

336 | /// fn check<T: FloatCore>(x: T, y: T) { |

337 | /// assert!(x.ceil() == y); |

338 | /// } |

339 | /// |

340 | /// check(f32::INFINITY, f32::INFINITY); |

341 | /// check(0.9f32, 1.0); |

342 | /// check(1.0f32, 1.0); |

343 | /// check(1.1f32, 2.0); |

344 | /// check(-0.0f64, 0.0); |

345 | /// check(-0.9f64, -0.0); |

346 | /// check(-1.0f64, -1.0); |

347 | /// check(-1.1f64, -1.0); |

348 | /// check(f64::MIN, f64::MIN); |

349 | /// ``` |

350 | #[inline] |

351 | fn ceil(self) -> Self { |

352 | let f = self.fract(); |

353 | if f.is_nan() || f.is_zero() { |

354 | self |

355 | } else if self > Self::zero() { |

356 | self - f + Self::one() |

357 | } else { |

358 | self - f |

359 | } |

360 | } |

361 | |

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

363 | /// |

364 | /// # Examples |

365 | /// |

366 | /// ``` |

367 | /// use num_traits::float::FloatCore; |

368 | /// use std::{f32, f64}; |

369 | /// |

370 | /// fn check<T: FloatCore>(x: T, y: T) { |

371 | /// assert!(x.round() == y); |

372 | /// } |

373 | /// |

374 | /// check(f32::INFINITY, f32::INFINITY); |

375 | /// check(0.4f32, 0.0); |

376 | /// check(0.5f32, 1.0); |

377 | /// check(0.6f32, 1.0); |

378 | /// check(-0.4f64, 0.0); |

379 | /// check(-0.5f64, -1.0); |

380 | /// check(-0.6f64, -1.0); |

381 | /// check(f64::MIN, f64::MIN); |

382 | /// ``` |

383 | #[inline] |

384 | fn round(self) -> Self { |

385 | let one = Self::one(); |

386 | let h = Self::from(0.5).expect("Unable to cast from 0.5"); |

387 | let f = self.fract(); |

388 | if f.is_nan() || f.is_zero() { |

389 | self |

390 | } else if self > Self::zero() { |

391 | if f < h { |

392 | self - f |

393 | } else { |

394 | self - f + one |

395 | } |

396 | } else if -f < h { |

397 | self - f |

398 | } else { |

399 | self - f - one |

400 | } |

401 | } |

402 | |

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

404 | /// |

405 | /// # Examples |

406 | /// |

407 | /// ``` |

408 | /// use num_traits::float::FloatCore; |

409 | /// use std::{f32, f64}; |

410 | /// |

411 | /// fn check<T: FloatCore>(x: T, y: T) { |

412 | /// assert!(x.trunc() == y); |

413 | /// } |

414 | /// |

415 | /// check(f32::INFINITY, f32::INFINITY); |

416 | /// check(0.9f32, 0.0); |

417 | /// check(1.0f32, 1.0); |

418 | /// check(1.1f32, 1.0); |

419 | /// check(-0.0f64, 0.0); |

420 | /// check(-0.9f64, -0.0); |

421 | /// check(-1.0f64, -1.0); |

422 | /// check(-1.1f64, -1.0); |

423 | /// check(f64::MIN, f64::MIN); |

424 | /// ``` |

425 | #[inline] |

426 | fn trunc(self) -> Self { |

427 | let f = self.fract(); |

428 | if f.is_nan() { |

429 | self |

430 | } else { |

431 | self - f |

432 | } |

433 | } |

434 | |

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

436 | /// |

437 | /// # Examples |

438 | /// |

439 | /// ``` |

440 | /// use num_traits::float::FloatCore; |

441 | /// use std::{f32, f64}; |

442 | /// |

443 | /// fn check<T: FloatCore>(x: T, y: T) { |

444 | /// assert!(x.fract() == y); |

445 | /// } |

446 | /// |

447 | /// check(f32::MAX, 0.0); |

448 | /// check(0.75f32, 0.75); |

449 | /// check(1.0f32, 0.0); |

450 | /// check(1.25f32, 0.25); |

451 | /// check(-0.0f64, 0.0); |

452 | /// check(-0.75f64, -0.75); |

453 | /// check(-1.0f64, 0.0); |

454 | /// check(-1.25f64, -0.25); |

455 | /// check(f64::MIN, 0.0); |

456 | /// ``` |

457 | #[inline] |

458 | fn fract(self) -> Self { |

459 | if self.is_zero() { |

460 | Self::zero() |

461 | } else { |

462 | self % Self::one() |

463 | } |

464 | } |

465 | |

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

467 | /// number is `FloatCore::nan()`. |

468 | /// |

469 | /// # Examples |

470 | /// |

471 | /// ``` |

472 | /// use num_traits::float::FloatCore; |

473 | /// use std::{f32, f64}; |

474 | /// |

475 | /// fn check<T: FloatCore>(x: T, y: T) { |

476 | /// assert!(x.abs() == y); |

477 | /// } |

478 | /// |

479 | /// check(f32::INFINITY, f32::INFINITY); |

480 | /// check(1.0f32, 1.0); |

481 | /// check(0.0f64, 0.0); |

482 | /// check(-0.0f64, 0.0); |

483 | /// check(-1.0f64, 1.0); |

484 | /// check(f64::MIN, f64::MAX); |

485 | /// ``` |

486 | #[inline] |

487 | fn abs(self) -> Self { |

488 | if self.is_sign_positive() { |

489 | return self; |

490 | } |

491 | if self.is_sign_negative() { |

492 | return -self; |

493 | } |

494 | Self::nan() |

495 | } |

496 | |

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

498 | /// |

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

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

501 | /// - `FloatCore::nan()` if the number is `FloatCore::nan()` |

502 | /// |

503 | /// # Examples |

504 | /// |

505 | /// ``` |

506 | /// use num_traits::float::FloatCore; |

507 | /// use std::{f32, f64}; |

508 | /// |

509 | /// fn check<T: FloatCore>(x: T, y: T) { |

510 | /// assert!(x.signum() == y); |

511 | /// } |

512 | /// |

513 | /// check(f32::INFINITY, 1.0); |

514 | /// check(3.0f32, 1.0); |

515 | /// check(0.0f32, 1.0); |

516 | /// check(-0.0f64, -1.0); |

517 | /// check(-3.0f64, -1.0); |

518 | /// check(f64::MIN, -1.0); |

519 | /// ``` |

520 | #[inline] |

521 | fn signum(self) -> Self { |

522 | if self.is_nan() { |

523 | Self::nan() |

524 | } else if self.is_sign_negative() { |

525 | -Self::one() |

526 | } else { |

527 | Self::one() |

528 | } |

529 | } |

530 | |

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

532 | /// `FloatCore::infinity()`, and `FloatCore::nan()`. |

533 | /// |

534 | /// # Examples |

535 | /// |

536 | /// ``` |

537 | /// use num_traits::float::FloatCore; |

538 | /// use std::{f32, f64}; |

539 | /// |

540 | /// fn check<T: FloatCore>(x: T, p: bool) { |

541 | /// assert!(x.is_sign_positive() == p); |

542 | /// } |

543 | /// |

544 | /// check(f32::INFINITY, true); |

545 | /// check(f32::MAX, true); |

546 | /// check(0.0f32, true); |

547 | /// check(-0.0f64, false); |

548 | /// check(f64::NEG_INFINITY, false); |

549 | /// check(f64::MIN_POSITIVE, true); |

550 | /// check(f64::NAN, true); |

551 | /// check(-f64::NAN, false); |

552 | /// ``` |

553 | #[inline] |

554 | fn is_sign_positive(self) -> bool { |

555 | !self.is_sign_negative() |

556 | } |

557 | |

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

559 | /// `FloatCore::neg_infinity()`, and `-FloatCore::nan()`. |

560 | /// |

561 | /// # Examples |

562 | /// |

563 | /// ``` |

564 | /// use num_traits::float::FloatCore; |

565 | /// use std::{f32, f64}; |

566 | /// |

567 | /// fn check<T: FloatCore>(x: T, p: bool) { |

568 | /// assert!(x.is_sign_negative() == p); |

569 | /// } |

570 | /// |

571 | /// check(f32::INFINITY, false); |

572 | /// check(f32::MAX, false); |

573 | /// check(0.0f32, false); |

574 | /// check(-0.0f64, true); |

575 | /// check(f64::NEG_INFINITY, true); |

576 | /// check(f64::MIN_POSITIVE, false); |

577 | /// check(f64::NAN, false); |

578 | /// check(-f64::NAN, true); |

579 | /// ``` |

580 | #[inline] |

581 | fn is_sign_negative(self) -> bool { |

582 | let (_, _, sign) = self.integer_decode(); |

583 | sign < 0 |

584 | } |

585 | |

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

587 | /// |

588 | /// If one of the arguments is NaN, then the other argument is returned. |

589 | /// |

590 | /// # Examples |

591 | /// |

592 | /// ``` |

593 | /// use num_traits::float::FloatCore; |

594 | /// use std::{f32, f64}; |

595 | /// |

596 | /// fn check<T: FloatCore>(x: T, y: T, min: T) { |

597 | /// assert!(x.min(y) == min); |

598 | /// } |

599 | /// |

600 | /// check(1.0f32, 2.0, 1.0); |

601 | /// check(f32::NAN, 2.0, 2.0); |

602 | /// check(1.0f64, -2.0, -2.0); |

603 | /// check(1.0f64, f64::NAN, 1.0); |

604 | /// ``` |

605 | #[inline] |

606 | fn min(self, other: Self) -> Self { |

607 | if self.is_nan() { |

608 | return other; |

609 | } |

610 | if other.is_nan() { |

611 | return self; |

612 | } |

613 | if self < other { |

614 | self |

615 | } else { |

616 | other |

617 | } |

618 | } |

619 | |

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

621 | /// |

622 | /// If one of the arguments is NaN, then the other argument is returned. |

623 | /// |

624 | /// # Examples |

625 | /// |

626 | /// ``` |

627 | /// use num_traits::float::FloatCore; |

628 | /// use std::{f32, f64}; |

629 | /// |

630 | /// fn check<T: FloatCore>(x: T, y: T, max: T) { |

631 | /// assert!(x.max(y) == max); |

632 | /// } |

633 | /// |

634 | /// check(1.0f32, 2.0, 2.0); |

635 | /// check(1.0f32, f32::NAN, 1.0); |

636 | /// check(-1.0f64, 2.0, 2.0); |

637 | /// check(-1.0f64, f64::NAN, -1.0); |

638 | /// ``` |

639 | #[inline] |

640 | fn max(self, other: Self) -> Self { |

641 | if self.is_nan() { |

642 | return other; |

643 | } |

644 | if other.is_nan() { |

645 | return self; |

646 | } |

647 | if self > other { |

648 | self |

649 | } else { |

650 | other |

651 | } |

652 | } |

653 | |

654 | /// Returns the reciprocal (multiplicative inverse) of the number. |

655 | /// |

656 | /// # Examples |

657 | /// |

658 | /// ``` |

659 | /// use num_traits::float::FloatCore; |

660 | /// use std::{f32, f64}; |

661 | /// |

662 | /// fn check<T: FloatCore>(x: T, y: T) { |

663 | /// assert!(x.recip() == y); |

664 | /// assert!(y.recip() == x); |

665 | /// } |

666 | /// |

667 | /// check(f32::INFINITY, 0.0); |

668 | /// check(2.0f32, 0.5); |

669 | /// check(-0.25f64, -4.0); |

670 | /// check(-0.0f64, f64::NEG_INFINITY); |

671 | /// ``` |

672 | #[inline] |

673 | fn recip(self) -> Self { |

674 | Self::one() / self |

675 | } |

676 | |

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

678 | /// |

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

680 | /// |

681 | /// # Examples |

682 | /// |

683 | /// ``` |

684 | /// use num_traits::float::FloatCore; |

685 | /// |

686 | /// fn check<T: FloatCore>(x: T, exp: i32, powi: T) { |

687 | /// assert!(x.powi(exp) == powi); |

688 | /// } |

689 | /// |

690 | /// check(9.0f32, 2, 81.0); |

691 | /// check(1.0f32, -2, 1.0); |

692 | /// check(10.0f64, 20, 1e20); |

693 | /// check(4.0f64, -2, 0.0625); |

694 | /// check(-1.0f64, std::i32::MIN, 1.0); |

695 | /// ``` |

696 | #[inline] |

697 | fn powi(mut self, mut exp: i32) -> Self { |

698 | if exp < 0 { |

699 | exp = exp.wrapping_neg(); |

700 | self = self.recip(); |

701 | } |

702 | // It should always be possible to convert a positive `i32` to a `usize`. |

703 | // Note, `i32::MIN` will wrap and still be negative, so we need to convert |

704 | // to `u32` without sign-extension before growing to `usize`. |

705 | super::pow(self, (exp as u32).to_usize().unwrap()) |

706 | } |

707 | |

708 | /// Converts to degrees, assuming the number is in radians. |

709 | /// |

710 | /// # Examples |

711 | /// |

712 | /// ``` |

713 | /// use num_traits::float::FloatCore; |

714 | /// use std::{f32, f64}; |

715 | /// |

716 | /// fn check<T: FloatCore>(rad: T, deg: T) { |

717 | /// assert!(rad.to_degrees() == deg); |

718 | /// } |

719 | /// |

720 | /// check(0.0f32, 0.0); |

721 | /// check(f32::consts::PI, 180.0); |

722 | /// check(f64::consts::FRAC_PI_4, 45.0); |

723 | /// check(f64::INFINITY, f64::INFINITY); |

724 | /// ``` |

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

726 | |

727 | /// Converts to radians, assuming the number is in degrees. |

728 | /// |

729 | /// # Examples |

730 | /// |

731 | /// ``` |

732 | /// use num_traits::float::FloatCore; |

733 | /// use std::{f32, f64}; |

734 | /// |

735 | /// fn check<T: FloatCore>(deg: T, rad: T) { |

736 | /// assert!(deg.to_radians() == rad); |

737 | /// } |

738 | /// |

739 | /// check(0.0f32, 0.0); |

740 | /// check(180.0, f32::consts::PI); |

741 | /// check(45.0, f64::consts::FRAC_PI_4); |

742 | /// check(f64::INFINITY, f64::INFINITY); |

743 | /// ``` |

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

745 | |

746 | /// Returns the mantissa, base 2 exponent, and sign as integers, respectively. |

747 | /// The original number can be recovered by `sign * mantissa * 2 ^ exponent`. |

748 | /// |

749 | /// # Examples |

750 | /// |

751 | /// ``` |

752 | /// use num_traits::float::FloatCore; |

753 | /// use std::{f32, f64}; |

754 | /// |

755 | /// fn check<T: FloatCore>(x: T, m: u64, e: i16, s:i8) { |

756 | /// let (mantissa, exponent, sign) = x.integer_decode(); |

757 | /// assert_eq!(mantissa, m); |

758 | /// assert_eq!(exponent, e); |

759 | /// assert_eq!(sign, s); |

760 | /// } |

761 | /// |

762 | /// check(2.0f32, 1 << 23, -22, 1); |

763 | /// check(-2.0f32, 1 << 23, -22, -1); |

764 | /// check(f32::INFINITY, 1 << 23, 105, 1); |

765 | /// check(f64::NEG_INFINITY, 1 << 52, 972, -1); |

766 | /// ``` |

767 | fn integer_decode(self) -> (u64, i16, i8); |

768 | } |

769 | |

770 | impl FloatCore for f32 { |

771 | constant! { |

772 | infinity() -> f32::INFINITY; |

773 | neg_infinity() -> f32::NEG_INFINITY; |

774 | nan() -> f32::NAN; |

775 | neg_zero() -> -0.0; |

776 | min_value() -> f32::MIN; |

777 | min_positive_value() -> f32::MIN_POSITIVE; |

778 | epsilon() -> f32::EPSILON; |

779 | max_value() -> f32::MAX; |

780 | } |

781 | |

782 | #[inline] |

783 | fn integer_decode(self) -> (u64, i16, i8) { |

784 | integer_decode_f32(self) |

785 | } |

786 | |

787 | forward! { |

788 | Self::is_nan(self) -> bool; |

789 | Self::is_infinite(self) -> bool; |

790 | Self::is_finite(self) -> bool; |

791 | Self::is_normal(self) -> bool; |

792 | Self::classify(self) -> FpCategory; |

793 | Self::is_sign_positive(self) -> bool; |

794 | Self::is_sign_negative(self) -> bool; |

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

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

797 | Self::recip(self) -> Self; |

798 | Self::to_degrees(self) -> Self; |

799 | Self::to_radians(self) -> Self; |

800 | } |

801 | |

802 | #[cfg(has_is_subnormal)] |

803 | forward! { |

804 | Self::is_subnormal(self) -> bool; |

805 | } |

806 | |

807 | #[cfg(feature = "std")] |

808 | forward! { |

809 | Self::floor(self) -> Self; |

810 | Self::ceil(self) -> Self; |

811 | Self::round(self) -> Self; |

812 | Self::trunc(self) -> Self; |

813 | Self::fract(self) -> Self; |

814 | Self::abs(self) -> Self; |

815 | Self::signum(self) -> Self; |

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

817 | } |

818 | |

819 | #[cfg(all(not(feature = "std"), feature = "libm"))] |

820 | forward! { |

821 | libm::floorf as floor(self) -> Self; |

822 | libm::ceilf as ceil(self) -> Self; |

823 | libm::roundf as round(self) -> Self; |

824 | libm::truncf as trunc(self) -> Self; |

825 | libm::fabsf as abs(self) -> Self; |

826 | } |

827 | |

828 | #[cfg(all(not(feature = "std"), feature = "libm"))] |

829 | #[inline] |

830 | fn fract(self) -> Self { |

831 | self - libm::truncf(self) |

832 | } |

833 | } |

834 | |

835 | impl FloatCore for f64 { |

836 | constant! { |

837 | infinity() -> f64::INFINITY; |

838 | neg_infinity() -> f64::NEG_INFINITY; |

839 | nan() -> f64::NAN; |

840 | neg_zero() -> -0.0; |

841 | min_value() -> f64::MIN; |

842 | min_positive_value() -> f64::MIN_POSITIVE; |

843 | epsilon() -> f64::EPSILON; |

844 | max_value() -> f64::MAX; |

845 | } |

846 | |

847 | #[inline] |

848 | fn integer_decode(self) -> (u64, i16, i8) { |

849 | integer_decode_f64(self) |

850 | } |

851 | |

852 | forward! { |

853 | Self::is_nan(self) -> bool; |

854 | Self::is_infinite(self) -> bool; |

855 | Self::is_finite(self) -> bool; |

856 | Self::is_normal(self) -> bool; |

857 | Self::classify(self) -> FpCategory; |

858 | Self::is_sign_positive(self) -> bool; |

859 | Self::is_sign_negative(self) -> bool; |

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

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

862 | Self::recip(self) -> Self; |

863 | Self::to_degrees(self) -> Self; |

864 | Self::to_radians(self) -> Self; |

865 | } |

866 | |

867 | #[cfg(has_is_subnormal)] |

868 | forward! { |

869 | Self::is_subnormal(self) -> bool; |

870 | } |

871 | |

872 | #[cfg(feature = "std")] |

873 | forward! { |

874 | Self::floor(self) -> Self; |

875 | Self::ceil(self) -> Self; |

876 | Self::round(self) -> Self; |

877 | Self::trunc(self) -> Self; |

878 | Self::fract(self) -> Self; |

879 | Self::abs(self) -> Self; |

880 | Self::signum(self) -> Self; |

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

882 | } |

883 | |

884 | #[cfg(all(not(feature = "std"), feature = "libm"))] |

885 | forward! { |

886 | libm::floor as floor(self) -> Self; |

887 | libm::ceil as ceil(self) -> Self; |

888 | libm::round as round(self) -> Self; |

889 | libm::trunc as trunc(self) -> Self; |

890 | libm::fabs as abs(self) -> Self; |

891 | } |

892 | |

893 | #[cfg(all(not(feature = "std"), feature = "libm"))] |

894 | #[inline] |

895 | fn fract(self) -> Self { |

896 | self - libm::trunc(self) |

897 | } |

898 | } |

899 | |

900 | // FIXME: these doctests aren't actually helpful, because they're using and |

901 | // testing the inherent methods directly, not going through `Float`. |

902 | |

903 | /// Generic trait for floating point numbers |

904 | /// |

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

906 | #[cfg(any(feature = "std", feature = "libm"))] |

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

908 | /// Returns the `NaN` value. |

909 | /// |

910 | /// ``` |

911 | /// use num_traits::Float; |

912 | /// |

913 | /// let nan: f32 = Float::nan(); |

914 | /// |

915 | /// assert!(nan.is_nan()); |

916 | /// ``` |

917 | fn nan() -> Self; |

918 | /// Returns the infinite value. |

919 | /// |

920 | /// ``` |

921 | /// use num_traits::Float; |

922 | /// use std::f32; |

923 | /// |

924 | /// let infinity: f32 = Float::infinity(); |

925 | /// |

926 | /// assert!(infinity.is_infinite()); |

927 | /// assert!(!infinity.is_finite()); |

928 | /// assert!(infinity > f32::MAX); |

929 | /// ``` |

930 | fn infinity() -> Self; |

931 | /// Returns the negative infinite value. |

932 | /// |

933 | /// ``` |

934 | /// use num_traits::Float; |

935 | /// use std::f32; |

936 | /// |

937 | /// let neg_infinity: f32 = Float::neg_infinity(); |

938 | /// |

939 | /// assert!(neg_infinity.is_infinite()); |

940 | /// assert!(!neg_infinity.is_finite()); |

941 | /// assert!(neg_infinity < f32::MIN); |

942 | /// ``` |

943 | fn neg_infinity() -> Self; |

944 | /// Returns `-0.0`. |

945 | /// |

946 | /// ``` |

947 | /// use num_traits::{Zero, Float}; |

948 | /// |

949 | /// let inf: f32 = Float::infinity(); |

950 | /// let zero: f32 = Zero::zero(); |

951 | /// let neg_zero: f32 = Float::neg_zero(); |

952 | /// |

953 | /// assert_eq!(zero, neg_zero); |

954 | /// assert_eq!(7.0f32/inf, zero); |

955 | /// assert_eq!(zero * 10.0, zero); |

956 | /// ``` |

957 | fn neg_zero() -> Self; |

958 | |

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

960 | /// |

961 | /// ``` |

962 | /// use num_traits::Float; |

963 | /// use std::f64; |

964 | /// |

965 | /// let x: f64 = Float::min_value(); |

966 | /// |

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

968 | /// ``` |

969 | fn min_value() -> Self; |

970 | |

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

972 | /// |

973 | /// ``` |

974 | /// use num_traits::Float; |

975 | /// use std::f64; |

976 | /// |

977 | /// let x: f64 = Float::min_positive_value(); |

978 | /// |

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

980 | /// ``` |

981 | fn min_positive_value() -> Self; |

982 | |

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

984 | /// |

985 | /// ``` |

986 | /// use num_traits::Float; |

987 | /// use std::f64; |

988 | /// |

989 | /// let x: f64 = Float::epsilon(); |

990 | /// |

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

992 | /// ``` |

993 | /// |

994 | /// # Panics |

995 | /// |

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

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

998 | fn epsilon() -> Self { |

999 | Self::from(f32::EPSILON).expect("Unable to cast from f32::EPSILON") |

1000 | } |

1001 | |

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

1003 | /// |

1004 | /// ``` |

1005 | /// use num_traits::Float; |

1006 | /// use std::f64; |

1007 | /// |

1008 | /// let x: f64 = Float::max_value(); |

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

1010 | /// ``` |

1011 | fn max_value() -> Self; |

1012 | |

1013 | /// Returns `true` if this value is `NaN` and false otherwise. |

1014 | /// |

1015 | /// ``` |

1016 | /// use num_traits::Float; |

1017 | /// use std::f64; |

1018 | /// |

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

1020 | /// let f = 7.0; |

1021 | /// |

1022 | /// assert!(nan.is_nan()); |

1023 | /// assert!(!f.is_nan()); |

1024 | /// ``` |

1025 | fn is_nan(self) -> bool; |

1026 | |

1027 | /// Returns `true` if this value is positive infinity or negative infinity and |

1028 | /// false otherwise. |

1029 | /// |

1030 | /// ``` |

1031 | /// use num_traits::Float; |

1032 | /// use std::f32; |

1033 | /// |

1034 | /// let f = 7.0f32; |

1035 | /// let inf: f32 = Float::infinity(); |

1036 | /// let neg_inf: f32 = Float::neg_infinity(); |

1037 | /// let nan: f32 = f32::NAN; |

1038 | /// |

1039 | /// assert!(!f.is_infinite()); |

1040 | /// assert!(!nan.is_infinite()); |

1041 | /// |

1042 | /// assert!(inf.is_infinite()); |

1043 | /// assert!(neg_inf.is_infinite()); |

1044 | /// ``` |

1045 | fn is_infinite(self) -> bool; |

1046 | |

1047 | /// Returns `true` if this number is neither infinite nor `NaN`. |

1048 | /// |

1049 | /// ``` |

1050 | /// use num_traits::Float; |

1051 | /// use std::f32; |

1052 | /// |

1053 | /// let f = 7.0f32; |

1054 | /// let inf: f32 = Float::infinity(); |

1055 | /// let neg_inf: f32 = Float::neg_infinity(); |

1056 | /// let nan: f32 = f32::NAN; |

1057 | /// |

1058 | /// assert!(f.is_finite()); |

1059 | /// |

1060 | /// assert!(!nan.is_finite()); |

1061 | /// assert!(!inf.is_finite()); |

1062 | /// assert!(!neg_inf.is_finite()); |

1063 | /// ``` |

1064 | fn is_finite(self) -> bool; |

1065 | |

1066 | /// Returns `true` if the number is neither zero, infinite, |

1067 | /// [subnormal][subnormal], or `NaN`. |

1068 | /// |

1069 | /// ``` |

1070 | /// use num_traits::Float; |

1071 | /// use std::f32; |

1072 | /// |

1073 | /// let min = f32::MIN_POSITIVE; // 1.17549435e-38f32 |

1074 | /// let max = f32::MAX; |

1075 | /// let lower_than_min = 1.0e-40_f32; |

1076 | /// let zero = 0.0f32; |

1077 | /// |

1078 | /// assert!(min.is_normal()); |

1079 | /// assert!(max.is_normal()); |

1080 | /// |

1081 | /// assert!(!zero.is_normal()); |

1082 | /// assert!(!f32::NAN.is_normal()); |

1083 | /// assert!(!f32::INFINITY.is_normal()); |

1084 | /// // Values between `0` and `min` are Subnormal. |

1085 | /// assert!(!lower_than_min.is_normal()); |

1086 | /// ``` |

1087 | /// [subnormal]: http://en.wikipedia.org/wiki/Subnormal_number |

1088 | fn is_normal(self) -> bool; |

1089 | |

1090 | /// Returns `true` if the number is [subnormal]. |

1091 | /// |

1092 | /// ``` |

1093 | /// use num_traits::Float; |

1094 | /// use std::f64; |

1095 | /// |

1096 | /// let min = f64::MIN_POSITIVE; // 2.2250738585072014e-308_f64 |

1097 | /// let max = f64::MAX; |

1098 | /// let lower_than_min = 1.0e-308_f64; |

1099 | /// let zero = 0.0_f64; |

1100 | /// |

1101 | /// assert!(!min.is_subnormal()); |

1102 | /// assert!(!max.is_subnormal()); |

1103 | /// |

1104 | /// assert!(!zero.is_subnormal()); |

1105 | /// assert!(!f64::NAN.is_subnormal()); |

1106 | /// assert!(!f64::INFINITY.is_subnormal()); |

1107 | /// // Values between `0` and `min` are Subnormal. |

1108 | /// assert!(lower_than_min.is_subnormal()); |

1109 | /// ``` |

1110 | /// [subnormal]: https://en.wikipedia.org/wiki/Subnormal_number |

1111 | #[inline] |

1112 | fn is_subnormal(self) -> bool { |

1113 | self.classify() == FpCategory::Subnormal |

1114 | } |

1115 | |

1116 | /// Returns the floating point category of the number. If only one property |

1117 | /// is going to be tested, it is generally faster to use the specific |

1118 | /// predicate instead. |

1119 | /// |

1120 | /// ``` |

1121 | /// use num_traits::Float; |

1122 | /// use std::num::FpCategory; |

1123 | /// use std::f32; |

1124 | /// |

1125 | /// let num = 12.4f32; |

1126 | /// let inf = f32::INFINITY; |

1127 | /// |

1128 | /// assert_eq!(num.classify(), FpCategory::Normal); |

1129 | /// assert_eq!(inf.classify(), FpCategory::Infinite); |

1130 | /// ``` |

1131 | fn classify(self) -> FpCategory; |

1132 | |

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

1134 | /// |

1135 | /// ``` |

1136 | /// use num_traits::Float; |

1137 | /// |

1138 | /// let f = 3.99; |

1139 | /// let g = 3.0; |

1140 | /// |

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

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

1143 | /// ``` |

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

1145 | |

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

1147 | /// |

1148 | /// ``` |

1149 | /// use num_traits::Float; |

1150 | /// |

1151 | /// let f = 3.01; |

1152 | /// let g = 4.0; |

1153 | /// |

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

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

1156 | /// ``` |

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

1158 | |

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

1160 | /// `0.0`. |

1161 | /// |

1162 | /// ``` |

1163 | /// use num_traits::Float; |

1164 | /// |

1165 | /// let f = 3.3; |

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

1167 | /// |

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

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

1170 | /// ``` |

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

1172 | |

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

1174 | /// |

1175 | /// ``` |

1176 | /// use num_traits::Float; |

1177 | /// |

1178 | /// let f = 3.3; |

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

1180 | /// |

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

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

1183 | /// ``` |

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

1185 | |

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

1187 | /// |

1188 | /// ``` |

1189 | /// use num_traits::Float; |

1190 | /// |

1191 | /// let x = 3.5; |

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

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

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

1195 | /// |

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

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

1198 | /// ``` |

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

1200 | |

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

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

1203 | /// |

1204 | /// ``` |

1205 | /// use num_traits::Float; |

1206 | /// use std::f64; |

1207 | /// |

1208 | /// let x = 3.5; |

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

1210 | /// |

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

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

1213 | /// |

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

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

1216 | /// |

1217 | /// assert!(f64::NAN.abs().is_nan()); |

1218 | /// ``` |

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

1220 | |

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

1222 | /// |

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

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

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

1226 | /// |

1227 | /// ``` |

1228 | /// use num_traits::Float; |

1229 | /// use std::f64; |

1230 | /// |

1231 | /// let f = 3.5; |

1232 | /// |

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

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

1235 | /// |

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

1237 | /// ``` |

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

1239 | |

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

1241 | /// `Float::infinity()`, and `Float::nan()`. |

1242 | /// |

1243 | /// ``` |

1244 | /// use num_traits::Float; |

1245 | /// use std::f64; |

1246 | /// |

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

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

1249 | /// |

1250 | /// let f = 7.0; |

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

1252 | /// |

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

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

1255 | /// assert!(nan.is_sign_positive()); |

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

1257 | /// ``` |

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

1259 | |

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

1261 | /// `Float::neg_infinity()`, and `-Float::nan()`. |

1262 | /// |

1263 | /// ``` |

1264 | /// use num_traits::Float; |

1265 | /// use std::f64; |

1266 | /// |

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

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

1269 | /// |

1270 | /// let f = 7.0; |

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

1272 | /// |

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

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

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

1276 | /// assert!(neg_nan.is_sign_negative()); |

1277 | /// ``` |

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

1279 | |

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

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

1282 | /// |

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

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

1285 | /// |

1286 | /// ``` |

1287 | /// use num_traits::Float; |

1288 | /// |

1289 | /// let m = 10.0; |

1290 | /// let x = 4.0; |

1291 | /// let b = 60.0; |

1292 | /// |

1293 | /// // 100.0 |

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

1295 | /// |

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

1297 | /// ``` |

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

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

1300 | /// |

1301 | /// ``` |

1302 | /// use num_traits::Float; |

1303 | /// |

1304 | /// let x = 2.0; |

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

1306 | /// |

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

1308 | /// ``` |

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

1310 | |

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

1312 | /// |

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

1314 | /// |

1315 | /// ``` |

1316 | /// use num_traits::Float; |

1317 | /// |

1318 | /// let x = 2.0; |

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

1320 | /// |

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

1322 | /// ``` |

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

1324 | |

1325 | /// Raise a number to a floating point power. |

1326 | /// |

1327 | /// ``` |

1328 | /// use num_traits::Float; |

1329 | /// |

1330 | /// let x = 2.0; |

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

1332 | /// |

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

1334 | /// ``` |

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

1336 | |

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

1338 | /// |

1339 | /// Returns NaN if `self` is a negative number. |

1340 | /// |

1341 | /// ``` |

1342 | /// use num_traits::Float; |

1343 | /// |

1344 | /// let positive = 4.0; |

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

1346 | /// |

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

1348 | /// |

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

1350 | /// assert!(negative.sqrt().is_nan()); |

1351 | /// ``` |

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

1353 | |

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

1355 | /// |

1356 | /// ``` |

1357 | /// use num_traits::Float; |

1358 | /// |

1359 | /// let one = 1.0; |

1360 | /// // e^1 |

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

1362 | /// |

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

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

1365 | /// |

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

1367 | /// ``` |

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

1369 | |

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

1371 | /// |

1372 | /// ``` |

1373 | /// use num_traits::Float; |

1374 | /// |

1375 | /// let f = 2.0; |

1376 | /// |

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

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

1379 | /// |

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

1381 | /// ``` |

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

1383 | |

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

1385 | /// |

1386 | /// ``` |

1387 | /// use num_traits::Float; |

1388 | /// |

1389 | /// let one = 1.0; |

1390 | /// // e^1 |

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

1392 | /// |

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

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

1395 | /// |

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

1397 | /// ``` |

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

1399 | |

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

1401 | /// |

1402 | /// ``` |

1403 | /// use num_traits::Float; |

1404 | /// |

1405 | /// let ten = 10.0; |

1406 | /// let two = 2.0; |

1407 | /// |

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

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

1410 | /// |

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

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

1413 | /// |

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

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

1416 | /// ``` |

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

1418 | |

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

1420 | /// |

1421 | /// ``` |

1422 | /// use num_traits::Float; |

1423 | /// |

1424 | /// let two = 2.0; |

1425 | /// |

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

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

1428 | /// |

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

1430 | /// ``` |

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

1432 | |

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

1434 | /// |

1435 | /// ``` |

1436 | /// use num_traits::Float; |

1437 | /// |

1438 | /// let ten = 10.0; |

1439 | /// |

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

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

1442 | /// |

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

1444 | /// ``` |

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

1446 | |

1447 | /// Converts radians to degrees. |

1448 | /// |

1449 | /// ``` |

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

1451 | /// |

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

1453 | /// |

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

1455 | /// |

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

1457 | /// ``` |

1458 | #[inline] |

1459 | fn to_degrees(self) -> Self { |

1460 | let halfpi = Self::zero().acos(); |

1461 | let ninety = Self::from(90u8).unwrap(); |

1462 | self * ninety / halfpi |

1463 | } |

1464 | |

1465 | /// Converts degrees to radians. |

1466 | /// |

1467 | /// ``` |

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

1469 | /// |

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

1471 | /// |

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

1473 | /// |

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

1475 | /// ``` |

1476 | #[inline] |

1477 | fn to_radians(self) -> Self { |

1478 | let halfpi = Self::zero().acos(); |

1479 | let ninety = Self::from(90u8).unwrap(); |

1480 | self * halfpi / ninety |

1481 | } |

1482 | |

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

1484 | /// |

1485 | /// ``` |

1486 | /// use num_traits::Float; |

1487 | /// |

1488 | /// let x = 1.0; |

1489 | /// let y = 2.0; |

1490 | /// |

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

1492 | /// ``` |

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

1494 | |

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

1496 | /// |

1497 | /// ``` |

1498 | /// use num_traits::Float; |

1499 | /// |

1500 | /// let x = 1.0; |

1501 | /// let y = 2.0; |

1502 | /// |

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

1504 | /// ``` |

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

1506 | |

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

1508 | /// |

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

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

1511 | /// |

1512 | /// ``` |

1513 | /// use num_traits::Float; |

1514 | /// |

1515 | /// let x = 3.0; |

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

1517 | /// |

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

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

1520 | /// |

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

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

1523 | /// ``` |

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

1525 | |

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

1527 | /// |

1528 | /// ``` |

1529 | /// use num_traits::Float; |

1530 | /// |

1531 | /// let x = 8.0; |

1532 | /// |

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

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

1535 | /// |

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

1537 | /// ``` |

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

1539 | |

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

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

1542 | /// |

1543 | /// ``` |

1544 | /// use num_traits::Float; |

1545 | /// |

1546 | /// let x = 2.0; |

1547 | /// let y = 3.0; |

1548 | /// |

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

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

1551 | /// |

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

1553 | /// ``` |

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

1555 | |

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

1557 | /// |

1558 | /// ``` |

1559 | /// use num_traits::Float; |

1560 | /// use std::f64; |

1561 | /// |

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

1563 | /// |

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

1565 | /// |

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

1567 | /// ``` |

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

1569 | |

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

1571 | /// |

1572 | /// ``` |

1573 | /// use num_traits::Float; |

1574 | /// use std::f64; |

1575 | /// |

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

1577 | /// |

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

1579 | /// |

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

1581 | /// ``` |

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

1583 | |

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

1585 | /// |

1586 | /// ``` |

1587 | /// use num_traits::Float; |

1588 | /// use std::f64; |

1589 | /// |

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

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

1592 | /// |

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

1594 | /// ``` |

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

1596 | |

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

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

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

1600 | /// |

1601 | /// ``` |

1602 | /// use num_traits::Float; |

1603 | /// use std::f64; |

1604 | /// |

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

1606 | /// |

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

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

1609 | /// |

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

1611 | /// ``` |

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

1613 | |

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

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

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

1617 | /// |

1618 | /// ``` |

1619 | /// use num_traits::Float; |

1620 | /// use std::f64; |

1621 | /// |

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

1623 | /// |

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

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

1626 | /// |

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

1628 | /// ``` |

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

1630 | |

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

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

1633 | /// |

1634 | /// ``` |

1635 | /// use num_traits::Float; |

1636 | /// |

1637 | /// let f = 1.0; |

1638 | /// |

1639 | /// // atan(tan(1)) |

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

1641 | /// |

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

1643 | /// ``` |

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

1645 | |

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

1647 | /// |

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

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

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

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

1652 | /// |

1653 | /// ``` |

1654 | /// use num_traits::Float; |

1655 | /// use std::f64; |

1656 | /// |

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

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

1659 | /// // 45 deg counter-clockwise |

1660 | /// let x1 = 3.0; |

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

1662 | /// |

1663 | /// // 135 deg clockwise |

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

1665 | /// let y2 = 3.0; |

1666 | /// |

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

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

1669 | /// |

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

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

1672 | /// ``` |

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

1674 | |

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

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

1677 | /// |

1678 | /// ``` |

1679 | /// use num_traits::Float; |

1680 | /// use std::f64; |

1681 | /// |

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

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

1684 | /// |

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

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

1687 | /// |

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

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

1690 | /// ``` |

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

1692 | |

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

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

1695 | /// |

1696 | /// ``` |

1697 | /// use num_traits::Float; |

1698 | /// |

1699 | /// let x = 7.0; |

1700 | /// |

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

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

1703 | /// |

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

1705 | /// ``` |

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

1707 | |

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

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

1710 | /// |

1711 | /// ``` |

1712 | /// use num_traits::Float; |

1713 | /// use std::f64; |

1714 | /// |

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

1716 | /// |

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

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

1719 | /// |

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

1721 | /// ``` |

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

1723 | |

1724 | /// Hyperbolic sine function. |

1725 | /// |

1726 | /// ``` |

1727 | /// use num_traits::Float; |

1728 | /// use std::f64; |

1729 | /// |

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

1731 | /// let x = 1.0; |

1732 | /// |

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

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

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

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

1737 | /// |

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

1739 | /// ``` |

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

1741 | |

1742 | /// Hyperbolic cosine function. |

1743 | /// |

1744 | /// ``` |

1745 | /// use num_traits::Float; |

1746 | /// use std::f64; |

1747 | /// |

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

1749 | /// let x = 1.0; |

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

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

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

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

1754 | /// |

1755 | /// // Same result |

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

1757 | /// ``` |

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

1759 | |

1760 | /// Hyperbolic tangent function. |

1761 | /// |

1762 | /// ``` |

1763 | /// use num_traits::Float; |

1764 | /// use std::f64; |

1765 | /// |

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

1767 | /// let x = 1.0; |

1768 | /// |

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

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

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

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

1773 | /// |

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

1775 | /// ``` |

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

1777 | |

1778 | /// Inverse hyperbolic sine function. |

1779 | /// |

1780 | /// ``` |

1781 | /// use num_traits::Float; |

1782 | /// |

1783 | /// let x = 1.0; |

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

1785 | /// |

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

1787 | /// |

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

1789 | /// ``` |

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

1791 | |

1792 | /// Inverse hyperbolic cosine function. |

1793 | /// |

1794 | /// ``` |

1795 | /// use num_traits::Float; |

1796 | /// |

1797 | /// let x = 1.0; |

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

1799 | /// |

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

1801 | /// |

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

1803 | /// ``` |

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

1805 | |

1806 | /// Inverse hyperbolic tangent function. |

1807 | /// |

1808 | /// ``` |

1809 | /// use num_traits::Float; |

1810 | /// use std::f64; |

1811 | /// |

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

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

1814 | /// |

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

1816 | /// |

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

1818 | /// ``` |

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

1820 | |

1821 | /// Returns the mantissa, base 2 exponent, and sign as integers, respectively. |

1822 | /// The original number can be recovered by `sign * mantissa * 2 ^ exponent`. |

1823 | /// |

1824 | /// ``` |

1825 | /// use num_traits::Float; |

1826 | /// |

1827 | /// let num = 2.0f32; |

1828 | /// |

1829 | /// // (8388608, -22, 1) |

1830 | /// let (mantissa, exponent, sign) = Float::integer_decode(num); |

1831 | /// let sign_f = sign as f32; |

1832 | /// let mantissa_f = mantissa as f32; |

1833 | /// let exponent_f = num.powf(exponent as f32); |

1834 | /// |

1835 | /// // 1 * 8388608 * 2^(-22) == 2 |

1836 | /// let abs_difference = (sign_f * mantissa_f * exponent_f - num).abs(); |

1837 | /// |

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

1839 | /// ``` |

1840 | fn integer_decode(self) -> (u64, i16, i8); |

1841 | |

1842 | /// Returns a number composed of the magnitude of `self` and the sign of |

1843 | /// `sign`. |

1844 | /// |

1845 | /// Equal to `self` if the sign of `self` and `sign` are the same, otherwise |

1846 | /// equal to `-self`. If `self` is a `NAN`, then a `NAN` with the sign of |

1847 | /// `sign` is returned. |

1848 | /// |

1849 | /// # Examples |

1850 | /// |

1851 | /// ``` |

1852 | /// use num_traits::Float; |

1853 | /// |

1854 | /// let f = 3.5_f32; |

1855 | /// |

1856 | /// assert_eq!(f.copysign(0.42), 3.5_f32); |

1857 | /// assert_eq!(f.copysign(-0.42), -3.5_f32); |

1858 | /// assert_eq!((-f).copysign(0.42), 3.5_f32); |

1859 | /// assert_eq!((-f).copysign(-0.42), -3.5_f32); |

1860 | /// |

1861 | /// assert!(f32::nan().copysign(1.0).is_nan()); |

1862 | /// ``` |

1863 | fn copysign(self, sign: Self) -> Self { |

1864 | if self.is_sign_negative() == sign.is_sign_negative() { |

1865 | self |

1866 | } else { |

1867 | self.neg() |

1868 | } |

1869 | } |

1870 | } |

1871 | |

1872 | #[cfg(feature = "std")] |

1873 | macro_rules! float_impl_std { |

1874 | ($T:ident $decode:ident) => { |

1875 | impl Float for $T { |

1876 | constant! { |

1877 | nan() -> $T::NAN; |

1878 | infinity() -> $T::INFINITY; |

1879 | neg_infinity() -> $T::NEG_INFINITY; |

1880 | neg_zero() -> -0.0; |

1881 | min_value() -> $T::MIN; |

1882 | min_positive_value() -> $T::MIN_POSITIVE; |

1883 | epsilon() -> $T::EPSILON; |

1884 | max_value() -> $T::MAX; |

1885 | } |

1886 | |

1887 | #[inline] |

1888 | #[allow(deprecated)] |

1889 | fn abs_sub(self, other: Self) -> Self { |

1890 | <$T>::abs_sub(self, other) |

1891 | } |

1892 | |

1893 | #[inline] |

1894 | fn integer_decode(self) -> (u64, i16, i8) { |

1895 | $decode(self) |

1896 | } |

1897 | |

1898 | forward! { |

1899 | Self::is_nan(self) -> bool; |

1900 | Self::is_infinite(self) -> bool; |

1901 | Self::is_finite(self) -> bool; |

1902 | Self::is_normal(self) -> bool; |

1903 | Self::classify(self) -> FpCategory; |

1904 | Self::floor(self) -> Self; |

1905 | Self::ceil(self) -> Self; |

1906 | Self::round(self) -> Self; |

1907 | Self::trunc(self) -> Self; |

1908 | Self::fract(self) -> Self; |

1909 | Self::abs(self) -> Self; |

1910 | Self::signum(self) -> Self; |

1911 | Self::is_sign_positive(self) -> bool; |

1912 | Self::is_sign_negative(self) -> bool; |

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

1914 | Self::recip(self) -> Self; |

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

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

1917 | Self::sqrt(self) -> Self; |

1918 | Self::exp(self) -> Self; |

1919 | Self::exp2(self) -> Self; |

1920 | Self::ln(self) -> Self; |

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

1922 | Self::log2(self) -> Self; |

1923 | Self::log10(self) -> Self; |

1924 | Self::to_degrees(self) -> Self; |

1925 | Self::to_radians(self) -> Self; |

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

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

1928 | Self::cbrt(self) -> Self; |

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

1930 | Self::sin(self) -> Self; |

1931 | Self::cos(self) -> Self; |

1932 | Self::tan(self) -> Self; |

1933 | Self::asin(self) -> Self; |

1934 | Self::acos(self) -> Self; |

1935 | Self::atan(self) -> Self; |

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

1937 | Self::sin_cos(self) -> (Self, Self); |

1938 | Self::exp_m1(self) -> Self; |

1939 | Self::ln_1p(self) -> Self; |

1940 | Self::sinh(self) -> Self; |

1941 | Self::cosh(self) -> Self; |

1942 | Self::tanh(self) -> Self; |

1943 | Self::asinh(self) -> Self; |

1944 | Self::acosh(self) -> Self; |

1945 | Self::atanh(self) -> Self; |

1946 | } |

1947 | |

1948 | #[cfg(has_copysign)] |

1949 | forward! { |

1950 | Self::copysign(self, sign: Self) -> Self; |

1951 | } |

1952 | |

1953 | #[cfg(has_is_subnormal)] |

1954 | forward! { |

1955 | Self::is_subnormal(self) -> bool; |

1956 | } |

1957 | } |

1958 | }; |

1959 | } |

1960 | |

1961 | #[cfg(all(not(feature = "std"), feature = "libm"))] |

1962 | macro_rules! float_impl_libm { |

1963 | ($T:ident $decode:ident) => { |

1964 | constant! { |

1965 | nan() -> $T::NAN; |

1966 | infinity() -> $T::INFINITY; |

1967 | neg_infinity() -> $T::NEG_INFINITY; |

1968 | neg_zero() -> -0.0; |

1969 | min_value() -> $T::MIN; |

1970 | min_positive_value() -> $T::MIN_POSITIVE; |

1971 | epsilon() -> $T::EPSILON; |

1972 | max_value() -> $T::MAX; |

1973 | } |

1974 | |

1975 | #[inline] |

1976 | fn integer_decode(self) -> (u64, i16, i8) { |

1977 | $decode(self) |

1978 | } |

1979 | |

1980 | #[inline] |

1981 | fn fract(self) -> Self { |

1982 | self - Float::trunc(self) |

1983 | } |

1984 | |

1985 | #[inline] |

1986 | fn log(self, base: Self) -> Self { |

1987 | self.ln() / base.ln() |

1988 | } |

1989 | |

1990 | forward! { |

1991 | Self::is_nan(self) -> bool; |

1992 | Self::is_infinite(self) -> bool; |

1993 | Self::is_finite(self) -> bool; |

1994 | Self::is_normal(self) -> bool; |

1995 | Self::classify(self) -> FpCategory; |

1996 | Self::is_sign_positive(self) -> bool; |

1997 | Self::is_sign_negative(self) -> bool; |

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

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

2000 | Self::recip(self) -> Self; |

2001 | Self::to_degrees(self) -> Self; |

2002 | Self::to_radians(self) -> Self; |

2003 | } |

2004 | |

2005 | #[cfg(has_is_subnormal)] |

2006 | forward! { |

2007 | Self::is_subnormal(self) -> bool; |

2008 | } |

2009 | |

2010 | forward! { |

2011 | FloatCore::signum(self) -> Self; |

2012 | FloatCore::powi(self, n: i32) -> Self; |

2013 | } |

2014 | }; |

2015 | } |

2016 | |

2017 | fn integer_decode_f32(f: f32) -> (u64, i16, i8) { |

2018 | let bits: u32 = f.to_bits(); |

2019 | let sign: i8 = if bits >> 31 == 0 { 1 } else { -1 }; |

2020 | let mut exponent: i16 = ((bits >> 23) & 0xff) as i16; |

2021 | let mantissa = if exponent == 0 { |

2022 | (bits & 0x7fffff) << 1 |

2023 | } else { |

2024 | (bits & 0x7fffff) | 0x800000 |

2025 | }; |

2026 | // Exponent bias + mantissa shift |

2027 | exponent -= 127 + 23; |

2028 | (mantissa as u64, exponent, sign) |

2029 | } |

2030 | |

2031 | fn integer_decode_f64(f: f64) -> (u64, i16, i8) { |

2032 | let bits: u64 = f.to_bits(); |

2033 | let sign: i8 = if bits >> 63 == 0 { 1 } else { -1 }; |

2034 | let mut exponent: i16 = ((bits >> 52) & 0x7ff) as i16; |

2035 | let mantissa = if exponent == 0 { |

2036 | (bits & 0xfffffffffffff) << 1 |

2037 | } else { |

2038 | (bits & 0xfffffffffffff) | 0x10000000000000 |

2039 | }; |

2040 | // Exponent bias + mantissa shift |

2041 | exponent -= 1023 + 52; |

2042 | (mantissa, exponent, sign) |

2043 | } |

2044 | |

2045 | #[cfg(feature = "std")] |

2046 | float_impl_std!(f32 integer_decode_f32); |

2047 | #[cfg(feature = "std")] |

2048 | float_impl_std!(f64 integer_decode_f64); |

2049 | |

2050 | #[cfg(all(not(feature = "std"), feature = "libm"))] |

2051 | impl Float for f32 { |

2052 | float_impl_libm!(f32 integer_decode_f32); |

2053 | |

2054 | #[inline] |

2055 | #[allow(deprecated)] |

2056 | fn abs_sub(self, other: Self) -> Self { |

2057 | libm::fdimf(self, other) |

2058 | } |

2059 | |

2060 | forward! { |

2061 | libm::floorf as floor(self) -> Self; |

2062 | libm::ceilf as ceil(self) -> Self; |

2063 | libm::roundf as round(self) -> Self; |

2064 | libm::truncf as trunc(self) -> Self; |

2065 | libm::fabsf as abs(self) -> Self; |

2066 | libm::fmaf as mul_add(self, a: Self, b: Self) -> Self; |

2067 | libm::powf as powf(self, n: Self) -> Self; |

2068 | libm::sqrtf as sqrt(self) -> Self; |

2069 | libm::expf as exp(self) -> Self; |

2070 | libm::exp2f as exp2(self) -> Self; |

2071 | libm::logf as ln(self) -> Self; |

2072 | libm::log2f as log2(self) -> Self; |

2073 | libm::log10f as log10(self) -> Self; |

2074 | libm::cbrtf as cbrt(self) -> Self; |

2075 | libm::hypotf as hypot(self, other: Self) -> Self; |

2076 | libm::sinf as sin(self) -> Self; |

2077 | libm::cosf as cos(self) -> Self; |

2078 | libm::tanf as tan(self) -> Self; |

2079 | libm::asinf as asin(self) -> Self; |

2080 | libm::acosf as acos(self) -> Self; |

2081 | libm::atanf as atan(self) -> Self; |

2082 | libm::atan2f as atan2(self, other: Self) -> Self; |

2083 | libm::sincosf as sin_cos(self) -> (Self, Self); |

2084 | libm::expm1f as exp_m1(self) -> Self; |

2085 | libm::log1pf as ln_1p(self) -> Self; |

2086 | libm::sinhf as sinh(self) -> Self; |

2087 | libm::coshf as cosh(self) -> Self; |

2088 | libm::tanhf as tanh(self) -> Self; |

2089 | libm::asinhf as asinh(self) -> Self; |

2090 | libm::acoshf as acosh(self) -> Self; |

2091 | libm::atanhf as atanh(self) -> Self; |

2092 | libm::copysignf as copysign(self, other: Self) -> Self; |

2093 | } |

2094 | } |

2095 | |

2096 | #[cfg(all(not(feature = "std"), feature = "libm"))] |

2097 | impl Float for f64 { |

2098 | float_impl_libm!(f64 integer_decode_f64); |

2099 | |

2100 | #[inline] |

2101 | #[allow(deprecated)] |

2102 | fn abs_sub(self, other: Self) -> Self { |

2103 | libm::fdim(self, other) |

2104 | } |

2105 | |

2106 | forward! { |

2107 | libm::floor as floor(self) -> Self; |

2108 | libm::ceil as ceil(self) -> Self; |

2109 | libm::round as round(self) -> Self; |

2110 | libm::trunc as trunc(self) -> Self; |

2111 | libm::fabs as abs(self) -> Self; |

2112 | libm::fma as mul_add(self, a: Self, b: Self) -> Self; |

2113 | libm::pow as powf(self, n: Self) -> Self; |

2114 | libm::sqrt as sqrt(self) -> Self; |

2115 | libm::exp as exp(self) -> Self; |

2116 | libm::exp2 as exp2(self) -> Self; |

2117 | libm::log as ln(self) -> Self; |

2118 | libm::log2 as log2(self) -> Self; |

2119 | libm::log10 as log10(self) -> Self; |

2120 | libm::cbrt as cbrt(self) -> Self; |

2121 | libm::hypot as hypot(self, other: Self) -> Self; |

2122 | libm::sin as sin(self) -> Self; |

2123 | libm::cos as cos(self) -> Self; |

2124 | libm::tan as tan(self) -> Self; |

2125 | libm::asin as asin(self) -> Self; |

2126 | libm::acos as acos(self) -> Self; |

2127 | libm::atan as atan(self) -> Self; |

2128 | libm::atan2 as atan2(self, other: Self) -> Self; |

2129 | libm::sincos as sin_cos(self) -> (Self, Self); |

2130 | libm::expm1 as exp_m1(self) -> Self; |

2131 | libm::log1p as ln_1p(self) -> Self; |

2132 | libm::sinh as sinh(self) -> Self; |

2133 | libm::cosh as cosh(self) -> Self; |

2134 | libm::tanh as tanh(self) -> Self; |

2135 | libm::asinh as asinh(self) -> Self; |

2136 | libm::acosh as acosh(self) -> Self; |

2137 | libm::atanh as atanh(self) -> Self; |

2138 | libm::copysign as copysign(self, sign: Self) -> Self; |

2139 | } |

2140 | } |

2141 | |

2142 | macro_rules! float_const_impl { |

2143 | ($(#[$doc:meta] $constant:ident,)+) => ( |

2144 | #[allow(non_snake_case)] |

2145 | pub trait FloatConst { |

2146 | $(#[$doc] fn $constant() -> Self;)+ |

2147 | #[doc = "Return the full circle constant `τ`."] |

2148 | #[inline] |

2149 | fn TAU() -> Self where Self: Sized + Add<Self, Output = Self> { |

2150 | Self::PI() + Self::PI() |

2151 | } |

2152 | #[doc = "Return `log10(2.0)`."] |

2153 | #[inline] |

2154 | fn LOG10_2() -> Self where Self: Sized + Div<Self, Output = Self> { |

2155 | Self::LN_2() / Self::LN_10() |

2156 | } |

2157 | #[doc = "Return `log2(10.0)`."] |

2158 | #[inline] |

2159 | fn LOG2_10() -> Self where Self: Sized + Div<Self, Output = Self> { |

2160 | Self::LN_10() / Self::LN_2() |

2161 | } |

2162 | } |

2163 | float_const_impl! { @float f32, $($constant,)+ } |

2164 | float_const_impl! { @float f64, $($constant,)+ } |

2165 | ); |

2166 | (@float $T:ident, $($constant:ident,)+) => ( |

2167 | impl FloatConst for $T { |

2168 | constant! { |

2169 | $( $constant() -> $T::consts::$constant; )+ |

2170 | TAU() -> 6.28318530717958647692528676655900577; |

2171 | LOG10_2() -> 0.301029995663981195213738894724493027; |

2172 | LOG2_10() -> 3.32192809488736234787031942948939018; |

2173 | } |

2174 | } |

2175 | ); |

2176 | } |

2177 | |

2178 | float_const_impl! { |

2179 | #[doc= "Return Euler’s number."] |

2180 | E, |

2181 | #[doc= "Return `1.0 / π`."] |

2182 | FRAC_1_PI, |

2183 | #[doc= "Return `1.0 / sqrt(2.0)`."] |

2184 | FRAC_1_SQRT_2, |

2185 | #[doc= "Return `2.0 / π`."] |

2186 | FRAC_2_PI, |

2187 | #[doc= "Return `2.0 / sqrt(π)`."] |

2188 | FRAC_2_SQRT_PI, |

2189 | #[doc= "Return `π / 2.0`."] |

2190 | FRAC_PI_2, |

2191 | #[doc= "Return `π / 3.0`."] |

2192 | FRAC_PI_3, |

2193 | #[doc= "Return `π / 4.0`."] |

2194 | FRAC_PI_4, |

2195 | #[doc= "Return `π / 6.0`."] |

2196 | FRAC_PI_6, |

2197 | #[doc= "Return `π / 8.0`."] |

2198 | FRAC_PI_8, |

2199 | #[doc= "Return `ln(10.0)`."] |

2200 | LN_10, |

2201 | #[doc= "Return `ln(2.0)`."] |

2202 | LN_2, |

2203 | #[doc= "Return `log10(e)`."] |

2204 | LOG10_E, |

2205 | #[doc= "Return `log2(e)`."] |

2206 | LOG2_E, |

2207 | #[doc= "Return Archimedes’ constant `π`."] |

2208 | PI, |

2209 | #[doc= "Return `sqrt(2.0)`."] |

2210 | SQRT_2, |

2211 | } |

2212 | |

2213 | #[cfg(test)] |

2214 | mod tests { |

2215 | use core::f64::consts; |

2216 | |

2217 | const DEG_RAD_PAIRS: [(f64, f64); 7] = [ |

2218 | (0.0, 0.), |

2219 | (22.5, consts::FRAC_PI_8), |

2220 | (30.0, consts::FRAC_PI_6), |

2221 | (45.0, consts::FRAC_PI_4), |

2222 | (60.0, consts::FRAC_PI_3), |

2223 | (90.0, consts::FRAC_PI_2), |

2224 | (180.0, consts::PI), |

2225 | ]; |

2226 | |

2227 | #[test] |

2228 | fn convert_deg_rad() { |

2229 | use crate::float::FloatCore; |

2230 | |

2231 | for &(deg, rad) in &DEG_RAD_PAIRS { |

2232 | assert!((FloatCore::to_degrees(rad) - deg).abs() < 1e-6); |

2233 | assert!((FloatCore::to_radians(deg) - rad).abs() < 1e-6); |

2234 | |

2235 | let (deg, rad) = (deg as f32, rad as f32); |

2236 | assert!((FloatCore::to_degrees(rad) - deg).abs() < 1e-5); |

2237 | assert!((FloatCore::to_radians(deg) - rad).abs() < 1e-5); |

2238 | } |

2239 | } |

2240 | |

2241 | #[cfg(any(feature = "std", feature = "libm"))] |

2242 | #[test] |

2243 | fn convert_deg_rad_std() { |

2244 | for &(deg, rad) in &DEG_RAD_PAIRS { |

2245 | use crate::Float; |

2246 | |

2247 | assert!((Float::to_degrees(rad) - deg).abs() < 1e-6); |

2248 | assert!((Float::to_radians(deg) - rad).abs() < 1e-6); |

2249 | |

2250 | let (deg, rad) = (deg as f32, rad as f32); |

2251 | assert!((Float::to_degrees(rad) - deg).abs() < 1e-5); |

2252 | assert!((Float::to_radians(deg) - rad).abs() < 1e-5); |

2253 | } |

2254 | } |

2255 | |

2256 | #[test] |

2257 | fn to_degrees_rounding() { |

2258 | use crate::float::FloatCore; |

2259 | |

2260 | assert_eq!( |

2261 | FloatCore::to_degrees(1_f32), |

2262 | 57.2957795130823208767981548141051703 |

2263 | ); |

2264 | } |

2265 | |

2266 | #[test] |

2267 | #[cfg(any(feature = "std", feature = "libm"))] |

2268 | fn extra_logs() { |

2269 | use crate::float::{Float, FloatConst}; |

2270 | |

2271 | fn check<F: Float + FloatConst>(diff: F) { |

2272 | let _2 = F::from(2.0).unwrap(); |

2273 | assert!((F::LOG10_2() - F::log10(_2)).abs() < diff); |

2274 | assert!((F::LOG10_2() - F::LN_2() / F::LN_10()).abs() < diff); |

2275 | |

2276 | let _10 = F::from(10.0).unwrap(); |

2277 | assert!((F::LOG2_10() - F::log2(_10)).abs() < diff); |

2278 | assert!((F::LOG2_10() - F::LN_10() / F::LN_2()).abs() < diff); |

2279 | } |

2280 | |

2281 | check::<f32>(1e-6); |

2282 | check::<f64>(1e-12); |

2283 | } |

2284 | |

2285 | #[test] |

2286 | #[cfg(any(feature = "std", feature = "libm"))] |

2287 | fn copysign() { |

2288 | use crate::float::Float; |

2289 | test_copysign_generic(2.0_f32, -2.0_f32, f32::nan()); |

2290 | test_copysign_generic(2.0_f64, -2.0_f64, f64::nan()); |

2291 | test_copysignf(2.0_f32, -2.0_f32, f32::nan()); |

2292 | } |

2293 | |

2294 | #[cfg(any(feature = "std", feature = "libm"))] |

2295 | fn test_copysignf(p: f32, n: f32, nan: f32) { |

2296 | use crate::float::Float; |

2297 | use core::ops::Neg; |

2298 | |

2299 | assert!(p.is_sign_positive()); |

2300 | assert!(n.is_sign_negative()); |

2301 | assert!(nan.is_nan()); |

2302 | |

2303 | assert_eq!(p, Float::copysign(p, p)); |

2304 | assert_eq!(p.neg(), Float::copysign(p, n)); |

2305 | |

2306 | assert_eq!(n, Float::copysign(n, n)); |

2307 | assert_eq!(n.neg(), Float::copysign(n, p)); |

2308 | |

2309 | assert!(Float::copysign(nan, p).is_sign_positive()); |

2310 | assert!(Float::copysign(nan, n).is_sign_negative()); |

2311 | } |

2312 | |

2313 | #[cfg(any(feature = "std", feature = "libm"))] |

2314 | fn test_copysign_generic<F: crate::float::Float + ::core::fmt::Debug>(p: F, n: F, nan: F) { |

2315 | assert!(p.is_sign_positive()); |

2316 | assert!(n.is_sign_negative()); |

2317 | assert!(nan.is_nan()); |

2318 | assert!(!nan.is_subnormal()); |

2319 | |

2320 | assert_eq!(p, p.copysign(p)); |

2321 | assert_eq!(p.neg(), p.copysign(n)); |

2322 | |

2323 | assert_eq!(n, n.copysign(n)); |

2324 | assert_eq!(n.neg(), n.copysign(p)); |

2325 | |

2326 | assert!(nan.copysign(p).is_sign_positive()); |

2327 | assert!(nan.copysign(n).is_sign_negative()); |

2328 | } |

2329 | |

2330 | #[cfg(any(feature = "std", feature = "libm"))] |

2331 | fn test_subnormal<F: crate::float::Float + ::core::fmt::Debug>() { |

2332 | let min_positive = F::min_positive_value(); |

2333 | let lower_than_min = min_positive / F::from(2.0f32).unwrap(); |

2334 | assert!(!min_positive.is_subnormal()); |

2335 | assert!(lower_than_min.is_subnormal()); |

2336 | } |

2337 | |

2338 | #[test] |

2339 | #[cfg(any(feature = "std", feature = "libm"))] |

2340 | fn subnormal() { |

2341 | test_subnormal::<f64>(); |

2342 | test_subnormal::<f32>(); |

2343 | } |

2344 | } |

2345 |