1 use crate::{bf16, f16}; 2 use core::cmp::Ordering; 3 use core::{num::FpCategory, ops::Div}; 4 use num_traits::{ 5 AsPrimitive, Bounded, FloatConst, FromPrimitive, Num, NumCast, One, ToPrimitive, Zero, 6 }; 7 8 impl ToPrimitive for f16 { 9 #[inline] to_i64(&self) -> Option<i64>10 fn to_i64(&self) -> Option<i64> { 11 Self::to_f32(*self).to_i64() 12 } 13 #[inline] to_u64(&self) -> Option<u64>14 fn to_u64(&self) -> Option<u64> { 15 Self::to_f32(*self).to_u64() 16 } 17 #[inline] to_i8(&self) -> Option<i8>18 fn to_i8(&self) -> Option<i8> { 19 Self::to_f32(*self).to_i8() 20 } 21 #[inline] to_u8(&self) -> Option<u8>22 fn to_u8(&self) -> Option<u8> { 23 Self::to_f32(*self).to_u8() 24 } 25 #[inline] to_i16(&self) -> Option<i16>26 fn to_i16(&self) -> Option<i16> { 27 Self::to_f32(*self).to_i16() 28 } 29 #[inline] to_u16(&self) -> Option<u16>30 fn to_u16(&self) -> Option<u16> { 31 Self::to_f32(*self).to_u16() 32 } 33 #[inline] to_i32(&self) -> Option<i32>34 fn to_i32(&self) -> Option<i32> { 35 Self::to_f32(*self).to_i32() 36 } 37 #[inline] to_u32(&self) -> Option<u32>38 fn to_u32(&self) -> Option<u32> { 39 Self::to_f32(*self).to_u32() 40 } 41 #[inline] to_f32(&self) -> Option<f32>42 fn to_f32(&self) -> Option<f32> { 43 Some(Self::to_f32(*self)) 44 } 45 #[inline] to_f64(&self) -> Option<f64>46 fn to_f64(&self) -> Option<f64> { 47 Some(Self::to_f64(*self)) 48 } 49 } 50 51 impl FromPrimitive for f16 { 52 #[inline] from_i64(n: i64) -> Option<Self>53 fn from_i64(n: i64) -> Option<Self> { 54 n.to_f32().map(Self::from_f32) 55 } 56 #[inline] from_u64(n: u64) -> Option<Self>57 fn from_u64(n: u64) -> Option<Self> { 58 n.to_f32().map(Self::from_f32) 59 } 60 #[inline] from_i8(n: i8) -> Option<Self>61 fn from_i8(n: i8) -> Option<Self> { 62 n.to_f32().map(Self::from_f32) 63 } 64 #[inline] from_u8(n: u8) -> Option<Self>65 fn from_u8(n: u8) -> Option<Self> { 66 n.to_f32().map(Self::from_f32) 67 } 68 #[inline] from_i16(n: i16) -> Option<Self>69 fn from_i16(n: i16) -> Option<Self> { 70 n.to_f32().map(Self::from_f32) 71 } 72 #[inline] from_u16(n: u16) -> Option<Self>73 fn from_u16(n: u16) -> Option<Self> { 74 n.to_f32().map(Self::from_f32) 75 } 76 #[inline] from_i32(n: i32) -> Option<Self>77 fn from_i32(n: i32) -> Option<Self> { 78 n.to_f32().map(Self::from_f32) 79 } 80 #[inline] from_u32(n: u32) -> Option<Self>81 fn from_u32(n: u32) -> Option<Self> { 82 n.to_f32().map(Self::from_f32) 83 } 84 #[inline] from_f32(n: f32) -> Option<Self>85 fn from_f32(n: f32) -> Option<Self> { 86 n.to_f32().map(Self::from_f32) 87 } 88 #[inline] from_f64(n: f64) -> Option<Self>89 fn from_f64(n: f64) -> Option<Self> { 90 n.to_f64().map(Self::from_f64) 91 } 92 } 93 94 impl Num for f16 { 95 type FromStrRadixErr = <f32 as Num>::FromStrRadixErr; 96 97 #[inline] from_str_radix(str: &str, radix: u32) -> Result<Self, Self::FromStrRadixErr>98 fn from_str_radix(str: &str, radix: u32) -> Result<Self, Self::FromStrRadixErr> { 99 Ok(Self::from_f32(f32::from_str_radix(str, radix)?)) 100 } 101 } 102 103 impl One for f16 { 104 #[inline] one() -> Self105 fn one() -> Self { 106 Self::ONE 107 } 108 } 109 110 impl Zero for f16 { 111 #[inline] zero() -> Self112 fn zero() -> Self { 113 Self::ZERO 114 } 115 116 #[inline] is_zero(&self) -> bool117 fn is_zero(&self) -> bool { 118 *self == Self::ZERO 119 } 120 } 121 122 impl NumCast for f16 { 123 #[inline] from<T: ToPrimitive>(n: T) -> Option<Self>124 fn from<T: ToPrimitive>(n: T) -> Option<Self> { 125 n.to_f32().map(Self::from_f32) 126 } 127 } 128 129 impl num_traits::float::FloatCore for f16 { 130 #[inline] infinity() -> Self131 fn infinity() -> Self { 132 Self::INFINITY 133 } 134 135 #[inline] neg_infinity() -> Self136 fn neg_infinity() -> Self { 137 Self::NEG_INFINITY 138 } 139 140 #[inline] nan() -> Self141 fn nan() -> Self { 142 Self::NAN 143 } 144 145 #[inline] neg_zero() -> Self146 fn neg_zero() -> Self { 147 Self::NEG_ZERO 148 } 149 150 #[inline] min_value() -> Self151 fn min_value() -> Self { 152 Self::MIN 153 } 154 155 #[inline] min_positive_value() -> Self156 fn min_positive_value() -> Self { 157 Self::MIN_POSITIVE 158 } 159 160 #[inline] epsilon() -> Self161 fn epsilon() -> Self { 162 Self::EPSILON 163 } 164 165 #[inline] max_value() -> Self166 fn max_value() -> Self { 167 Self::MAX 168 } 169 170 #[inline] is_nan(self) -> bool171 fn is_nan(self) -> bool { 172 self.is_nan() 173 } 174 175 #[inline] is_infinite(self) -> bool176 fn is_infinite(self) -> bool { 177 self.is_infinite() 178 } 179 180 #[inline] is_finite(self) -> bool181 fn is_finite(self) -> bool { 182 self.is_finite() 183 } 184 185 #[inline] is_normal(self) -> bool186 fn is_normal(self) -> bool { 187 self.is_normal() 188 } 189 190 #[inline] classify(self) -> FpCategory191 fn classify(self) -> FpCategory { 192 self.classify() 193 } 194 195 #[inline] floor(self) -> Self196 fn floor(self) -> Self { 197 Self::from_f32(self.to_f32().floor()) 198 } 199 200 #[inline] ceil(self) -> Self201 fn ceil(self) -> Self { 202 Self::from_f32(self.to_f32().ceil()) 203 } 204 205 #[inline] round(self) -> Self206 fn round(self) -> Self { 207 Self::from_f32(self.to_f32().round()) 208 } 209 210 #[inline] trunc(self) -> Self211 fn trunc(self) -> Self { 212 Self::from_f32(self.to_f32().trunc()) 213 } 214 215 #[inline] fract(self) -> Self216 fn fract(self) -> Self { 217 Self::from_f32(self.to_f32().fract()) 218 } 219 220 #[inline] abs(self) -> Self221 fn abs(self) -> Self { 222 Self::from_bits(self.to_bits() & 0x7FFF) 223 } 224 225 #[inline] signum(self) -> Self226 fn signum(self) -> Self { 227 self.signum() 228 } 229 230 #[inline] is_sign_positive(self) -> bool231 fn is_sign_positive(self) -> bool { 232 self.is_sign_positive() 233 } 234 235 #[inline] is_sign_negative(self) -> bool236 fn is_sign_negative(self) -> bool { 237 self.is_sign_negative() 238 } 239 min(self, other: Self) -> Self240 fn min(self, other: Self) -> Self { 241 match self.partial_cmp(&other) { 242 None => { 243 if self.is_nan() { 244 other 245 } else { 246 self 247 } 248 } 249 Some(Ordering::Greater) | Some(Ordering::Equal) => other, 250 Some(Ordering::Less) => self, 251 } 252 } 253 max(self, other: Self) -> Self254 fn max(self, other: Self) -> Self { 255 match self.partial_cmp(&other) { 256 None => { 257 if self.is_nan() { 258 other 259 } else { 260 self 261 } 262 } 263 Some(Ordering::Greater) | Some(Ordering::Equal) => self, 264 Some(Ordering::Less) => other, 265 } 266 } 267 268 #[inline] recip(self) -> Self269 fn recip(self) -> Self { 270 Self::from_f32(self.to_f32().recip()) 271 } 272 273 #[inline] powi(self, exp: i32) -> Self274 fn powi(self, exp: i32) -> Self { 275 Self::from_f32(self.to_f32().powi(exp)) 276 } 277 278 #[inline] to_degrees(self) -> Self279 fn to_degrees(self) -> Self { 280 Self::from_f32(self.to_f32().to_degrees()) 281 } 282 283 #[inline] to_radians(self) -> Self284 fn to_radians(self) -> Self { 285 Self::from_f32(self.to_f32().to_radians()) 286 } 287 288 #[inline] integer_decode(self) -> (u64, i16, i8)289 fn integer_decode(self) -> (u64, i16, i8) { 290 num_traits::float::FloatCore::integer_decode(self.to_f32()) 291 } 292 } 293 294 impl num_traits::float::Float for f16 { 295 #[inline] nan() -> Self296 fn nan() -> Self { 297 Self::NAN 298 } 299 300 #[inline] infinity() -> Self301 fn infinity() -> Self { 302 Self::INFINITY 303 } 304 305 #[inline] neg_infinity() -> Self306 fn neg_infinity() -> Self { 307 Self::NEG_INFINITY 308 } 309 310 #[inline] neg_zero() -> Self311 fn neg_zero() -> Self { 312 Self::NEG_ZERO 313 } 314 315 #[inline] min_value() -> Self316 fn min_value() -> Self { 317 Self::MIN 318 } 319 320 #[inline] min_positive_value() -> Self321 fn min_positive_value() -> Self { 322 Self::MIN_POSITIVE 323 } 324 325 #[inline] epsilon() -> Self326 fn epsilon() -> Self { 327 Self::EPSILON 328 } 329 330 #[inline] max_value() -> Self331 fn max_value() -> Self { 332 Self::MAX 333 } 334 335 #[inline] is_nan(self) -> bool336 fn is_nan(self) -> bool { 337 self.is_nan() 338 } 339 340 #[inline] is_infinite(self) -> bool341 fn is_infinite(self) -> bool { 342 self.is_infinite() 343 } 344 345 #[inline] is_finite(self) -> bool346 fn is_finite(self) -> bool { 347 self.is_finite() 348 } 349 350 #[inline] is_normal(self) -> bool351 fn is_normal(self) -> bool { 352 self.is_normal() 353 } 354 355 #[inline] classify(self) -> FpCategory356 fn classify(self) -> FpCategory { 357 self.classify() 358 } 359 360 #[inline] floor(self) -> Self361 fn floor(self) -> Self { 362 Self::from_f32(self.to_f32().floor()) 363 } 364 365 #[inline] ceil(self) -> Self366 fn ceil(self) -> Self { 367 Self::from_f32(self.to_f32().ceil()) 368 } 369 370 #[inline] round(self) -> Self371 fn round(self) -> Self { 372 Self::from_f32(self.to_f32().round()) 373 } 374 375 #[inline] trunc(self) -> Self376 fn trunc(self) -> Self { 377 Self::from_f32(self.to_f32().trunc()) 378 } 379 380 #[inline] fract(self) -> Self381 fn fract(self) -> Self { 382 Self::from_f32(self.to_f32().fract()) 383 } 384 385 #[inline] abs(self) -> Self386 fn abs(self) -> Self { 387 Self::from_f32(self.to_f32().abs()) 388 } 389 390 #[inline] signum(self) -> Self391 fn signum(self) -> Self { 392 Self::from_f32(self.to_f32().signum()) 393 } 394 395 #[inline] is_sign_positive(self) -> bool396 fn is_sign_positive(self) -> bool { 397 self.is_sign_positive() 398 } 399 400 #[inline] is_sign_negative(self) -> bool401 fn is_sign_negative(self) -> bool { 402 self.is_sign_negative() 403 } 404 405 #[inline] mul_add(self, a: Self, b: Self) -> Self406 fn mul_add(self, a: Self, b: Self) -> Self { 407 Self::from_f32(self.to_f32().mul_add(a.to_f32(), b.to_f32())) 408 } 409 410 #[inline] recip(self) -> Self411 fn recip(self) -> Self { 412 Self::from_f32(self.to_f32().recip()) 413 } 414 415 #[inline] powi(self, n: i32) -> Self416 fn powi(self, n: i32) -> Self { 417 Self::from_f32(self.to_f32().powi(n)) 418 } 419 420 #[inline] powf(self, n: Self) -> Self421 fn powf(self, n: Self) -> Self { 422 Self::from_f32(self.to_f32().powf(n.to_f32())) 423 } 424 425 #[inline] sqrt(self) -> Self426 fn sqrt(self) -> Self { 427 Self::from_f32(self.to_f32().sqrt()) 428 } 429 430 #[inline] exp(self) -> Self431 fn exp(self) -> Self { 432 Self::from_f32(self.to_f32().exp()) 433 } 434 435 #[inline] exp2(self) -> Self436 fn exp2(self) -> Self { 437 Self::from_f32(self.to_f32().exp2()) 438 } 439 440 #[inline] ln(self) -> Self441 fn ln(self) -> Self { 442 Self::from_f32(self.to_f32().ln()) 443 } 444 445 #[inline] log(self, base: Self) -> Self446 fn log(self, base: Self) -> Self { 447 Self::from_f32(self.to_f32().log(base.to_f32())) 448 } 449 450 #[inline] log2(self) -> Self451 fn log2(self) -> Self { 452 Self::from_f32(self.to_f32().log2()) 453 } 454 455 #[inline] log10(self) -> Self456 fn log10(self) -> Self { 457 Self::from_f32(self.to_f32().log10()) 458 } 459 460 #[inline] to_degrees(self) -> Self461 fn to_degrees(self) -> Self { 462 Self::from_f32(self.to_f32().to_degrees()) 463 } 464 465 #[inline] to_radians(self) -> Self466 fn to_radians(self) -> Self { 467 Self::from_f32(self.to_f32().to_radians()) 468 } 469 470 #[inline] max(self, other: Self) -> Self471 fn max(self, other: Self) -> Self { 472 self.max(other) 473 } 474 475 #[inline] min(self, other: Self) -> Self476 fn min(self, other: Self) -> Self { 477 self.min(other) 478 } 479 480 #[inline] abs_sub(self, other: Self) -> Self481 fn abs_sub(self, other: Self) -> Self { 482 Self::from_f32((self.to_f32() - other.to_f32()).max(0.0)) 483 } 484 485 #[inline] cbrt(self) -> Self486 fn cbrt(self) -> Self { 487 Self::from_f32(self.to_f32().cbrt()) 488 } 489 490 #[inline] hypot(self, other: Self) -> Self491 fn hypot(self, other: Self) -> Self { 492 Self::from_f32(self.to_f32().hypot(other.to_f32())) 493 } 494 495 #[inline] sin(self) -> Self496 fn sin(self) -> Self { 497 Self::from_f32(self.to_f32().sin()) 498 } 499 500 #[inline] cos(self) -> Self501 fn cos(self) -> Self { 502 Self::from_f32(self.to_f32().cos()) 503 } 504 505 #[inline] tan(self) -> Self506 fn tan(self) -> Self { 507 Self::from_f32(self.to_f32().tan()) 508 } 509 510 #[inline] asin(self) -> Self511 fn asin(self) -> Self { 512 Self::from_f32(self.to_f32().asin()) 513 } 514 515 #[inline] acos(self) -> Self516 fn acos(self) -> Self { 517 Self::from_f32(self.to_f32().acos()) 518 } 519 520 #[inline] atan(self) -> Self521 fn atan(self) -> Self { 522 Self::from_f32(self.to_f32().atan()) 523 } 524 525 #[inline] atan2(self, other: Self) -> Self526 fn atan2(self, other: Self) -> Self { 527 Self::from_f32(self.to_f32().atan2(other.to_f32())) 528 } 529 530 #[inline] sin_cos(self) -> (Self, Self)531 fn sin_cos(self) -> (Self, Self) { 532 let (sin, cos) = self.to_f32().sin_cos(); 533 (Self::from_f32(sin), Self::from_f32(cos)) 534 } 535 536 #[inline] exp_m1(self) -> Self537 fn exp_m1(self) -> Self { 538 Self::from_f32(self.to_f32().exp_m1()) 539 } 540 541 #[inline] ln_1p(self) -> Self542 fn ln_1p(self) -> Self { 543 Self::from_f32(self.to_f32().ln_1p()) 544 } 545 546 #[inline] sinh(self) -> Self547 fn sinh(self) -> Self { 548 Self::from_f32(self.to_f32().sinh()) 549 } 550 551 #[inline] cosh(self) -> Self552 fn cosh(self) -> Self { 553 Self::from_f32(self.to_f32().cosh()) 554 } 555 556 #[inline] tanh(self) -> Self557 fn tanh(self) -> Self { 558 Self::from_f32(self.to_f32().tanh()) 559 } 560 561 #[inline] asinh(self) -> Self562 fn asinh(self) -> Self { 563 Self::from_f32(self.to_f32().asinh()) 564 } 565 566 #[inline] acosh(self) -> Self567 fn acosh(self) -> Self { 568 Self::from_f32(self.to_f32().acosh()) 569 } 570 571 #[inline] atanh(self) -> Self572 fn atanh(self) -> Self { 573 Self::from_f32(self.to_f32().atanh()) 574 } 575 576 #[inline] integer_decode(self) -> (u64, i16, i8)577 fn integer_decode(self) -> (u64, i16, i8) { 578 num_traits::float::Float::integer_decode(self.to_f32()) 579 } 580 } 581 582 impl FloatConst for f16 { 583 #[inline] E() -> Self584 fn E() -> Self { 585 Self::E 586 } 587 588 #[inline] FRAC_1_PI() -> Self589 fn FRAC_1_PI() -> Self { 590 Self::FRAC_1_PI 591 } 592 593 #[inline] FRAC_1_SQRT_2() -> Self594 fn FRAC_1_SQRT_2() -> Self { 595 Self::FRAC_1_SQRT_2 596 } 597 598 #[inline] FRAC_2_PI() -> Self599 fn FRAC_2_PI() -> Self { 600 Self::FRAC_2_PI 601 } 602 603 #[inline] FRAC_2_SQRT_PI() -> Self604 fn FRAC_2_SQRT_PI() -> Self { 605 Self::FRAC_2_SQRT_PI 606 } 607 608 #[inline] FRAC_PI_2() -> Self609 fn FRAC_PI_2() -> Self { 610 Self::FRAC_PI_2 611 } 612 613 #[inline] FRAC_PI_3() -> Self614 fn FRAC_PI_3() -> Self { 615 Self::FRAC_PI_3 616 } 617 618 #[inline] FRAC_PI_4() -> Self619 fn FRAC_PI_4() -> Self { 620 Self::FRAC_PI_4 621 } 622 623 #[inline] FRAC_PI_6() -> Self624 fn FRAC_PI_6() -> Self { 625 Self::FRAC_PI_6 626 } 627 628 #[inline] FRAC_PI_8() -> Self629 fn FRAC_PI_8() -> Self { 630 Self::FRAC_PI_8 631 } 632 633 #[inline] LN_10() -> Self634 fn LN_10() -> Self { 635 Self::LN_10 636 } 637 638 #[inline] LN_2() -> Self639 fn LN_2() -> Self { 640 Self::LN_2 641 } 642 643 #[inline] LOG10_E() -> Self644 fn LOG10_E() -> Self { 645 Self::LOG10_E 646 } 647 648 #[inline] LOG2_E() -> Self649 fn LOG2_E() -> Self { 650 Self::LOG2_E 651 } 652 653 #[inline] PI() -> Self654 fn PI() -> Self { 655 Self::PI 656 } 657 SQRT_2() -> Self658 fn SQRT_2() -> Self { 659 Self::SQRT_2 660 } 661 662 #[inline] LOG10_2() -> Self where Self: Sized + Div<Self, Output = Self>,663 fn LOG10_2() -> Self 664 where 665 Self: Sized + Div<Self, Output = Self>, 666 { 667 Self::LOG10_2 668 } 669 670 #[inline] LOG2_10() -> Self where Self: Sized + Div<Self, Output = Self>,671 fn LOG2_10() -> Self 672 where 673 Self: Sized + Div<Self, Output = Self>, 674 { 675 Self::LOG2_10 676 } 677 } 678 679 impl Bounded for f16 { 680 #[inline] min_value() -> Self681 fn min_value() -> Self { 682 f16::MIN 683 } 684 685 #[inline] max_value() -> Self686 fn max_value() -> Self { 687 f16::MAX 688 } 689 } 690 691 macro_rules! impl_as_primitive_to_f16 { 692 ($ty:ty, $meth:ident) => { 693 impl AsPrimitive<$ty> for f16 { 694 #[inline] 695 fn as_(self) -> $ty { 696 self.$meth().as_() 697 } 698 } 699 }; 700 } 701 702 impl AsPrimitive<f16> for f16 { 703 #[inline] as_(self) -> f16704 fn as_(self) -> f16 { 705 self 706 } 707 } 708 709 impl_as_primitive_to_f16!(i64, to_f32); 710 impl_as_primitive_to_f16!(u64, to_f32); 711 impl_as_primitive_to_f16!(i8, to_f32); 712 impl_as_primitive_to_f16!(u8, to_f32); 713 impl_as_primitive_to_f16!(i16, to_f32); 714 impl_as_primitive_to_f16!(u16, to_f32); 715 impl_as_primitive_to_f16!(i32, to_f32); 716 impl_as_primitive_to_f16!(u32, to_f32); 717 impl_as_primitive_to_f16!(isize, to_f32); 718 impl_as_primitive_to_f16!(usize, to_f32); 719 impl_as_primitive_to_f16!(f32, to_f32); 720 impl_as_primitive_to_f16!(f64, to_f64); 721 722 macro_rules! impl_as_primitive_f16_from { 723 ($ty:ty, $meth:ident) => { 724 impl AsPrimitive<f16> for $ty { 725 #[inline] 726 fn as_(self) -> f16 { 727 f16::$meth(self.as_()) 728 } 729 } 730 }; 731 } 732 733 impl_as_primitive_f16_from!(i64, from_f32); 734 impl_as_primitive_f16_from!(u64, from_f32); 735 impl_as_primitive_f16_from!(i8, from_f32); 736 impl_as_primitive_f16_from!(u8, from_f32); 737 impl_as_primitive_f16_from!(i16, from_f32); 738 impl_as_primitive_f16_from!(u16, from_f32); 739 impl_as_primitive_f16_from!(i32, from_f32); 740 impl_as_primitive_f16_from!(u32, from_f32); 741 impl_as_primitive_f16_from!(isize, from_f32); 742 impl_as_primitive_f16_from!(usize, from_f32); 743 impl_as_primitive_f16_from!(f32, from_f32); 744 impl_as_primitive_f16_from!(f64, from_f64); 745 746 impl ToPrimitive for bf16 { 747 #[inline] to_i64(&self) -> Option<i64>748 fn to_i64(&self) -> Option<i64> { 749 Self::to_f32(*self).to_i64() 750 } 751 #[inline] to_u64(&self) -> Option<u64>752 fn to_u64(&self) -> Option<u64> { 753 Self::to_f32(*self).to_u64() 754 } 755 #[inline] to_i8(&self) -> Option<i8>756 fn to_i8(&self) -> Option<i8> { 757 Self::to_f32(*self).to_i8() 758 } 759 #[inline] to_u8(&self) -> Option<u8>760 fn to_u8(&self) -> Option<u8> { 761 Self::to_f32(*self).to_u8() 762 } 763 #[inline] to_i16(&self) -> Option<i16>764 fn to_i16(&self) -> Option<i16> { 765 Self::to_f32(*self).to_i16() 766 } 767 #[inline] to_u16(&self) -> Option<u16>768 fn to_u16(&self) -> Option<u16> { 769 Self::to_f32(*self).to_u16() 770 } 771 #[inline] to_i32(&self) -> Option<i32>772 fn to_i32(&self) -> Option<i32> { 773 Self::to_f32(*self).to_i32() 774 } 775 #[inline] to_u32(&self) -> Option<u32>776 fn to_u32(&self) -> Option<u32> { 777 Self::to_f32(*self).to_u32() 778 } 779 #[inline] to_f32(&self) -> Option<f32>780 fn to_f32(&self) -> Option<f32> { 781 Some(Self::to_f32(*self)) 782 } 783 #[inline] to_f64(&self) -> Option<f64>784 fn to_f64(&self) -> Option<f64> { 785 Some(Self::to_f64(*self)) 786 } 787 } 788 789 impl FromPrimitive for bf16 { 790 #[inline] from_i64(n: i64) -> Option<Self>791 fn from_i64(n: i64) -> Option<Self> { 792 n.to_f32().map(Self::from_f32) 793 } 794 #[inline] from_u64(n: u64) -> Option<Self>795 fn from_u64(n: u64) -> Option<Self> { 796 n.to_f32().map(Self::from_f32) 797 } 798 #[inline] from_i8(n: i8) -> Option<Self>799 fn from_i8(n: i8) -> Option<Self> { 800 n.to_f32().map(Self::from_f32) 801 } 802 #[inline] from_u8(n: u8) -> Option<Self>803 fn from_u8(n: u8) -> Option<Self> { 804 n.to_f32().map(Self::from_f32) 805 } 806 #[inline] from_i16(n: i16) -> Option<Self>807 fn from_i16(n: i16) -> Option<Self> { 808 n.to_f32().map(Self::from_f32) 809 } 810 #[inline] from_u16(n: u16) -> Option<Self>811 fn from_u16(n: u16) -> Option<Self> { 812 n.to_f32().map(Self::from_f32) 813 } 814 #[inline] from_i32(n: i32) -> Option<Self>815 fn from_i32(n: i32) -> Option<Self> { 816 n.to_f32().map(Self::from_f32) 817 } 818 #[inline] from_u32(n: u32) -> Option<Self>819 fn from_u32(n: u32) -> Option<Self> { 820 n.to_f32().map(Self::from_f32) 821 } 822 #[inline] from_f32(n: f32) -> Option<Self>823 fn from_f32(n: f32) -> Option<Self> { 824 n.to_f32().map(Self::from_f32) 825 } 826 #[inline] from_f64(n: f64) -> Option<Self>827 fn from_f64(n: f64) -> Option<Self> { 828 n.to_f64().map(Self::from_f64) 829 } 830 } 831 832 impl Num for bf16 { 833 type FromStrRadixErr = <f32 as Num>::FromStrRadixErr; 834 835 #[inline] from_str_radix(str: &str, radix: u32) -> Result<Self, Self::FromStrRadixErr>836 fn from_str_radix(str: &str, radix: u32) -> Result<Self, Self::FromStrRadixErr> { 837 Ok(Self::from_f32(f32::from_str_radix(str, radix)?)) 838 } 839 } 840 841 impl One for bf16 { 842 #[inline] one() -> Self843 fn one() -> Self { 844 Self::ONE 845 } 846 } 847 848 impl Zero for bf16 { 849 #[inline] zero() -> Self850 fn zero() -> Self { 851 Self::ZERO 852 } 853 854 #[inline] is_zero(&self) -> bool855 fn is_zero(&self) -> bool { 856 *self == Self::ZERO 857 } 858 } 859 860 impl NumCast for bf16 { 861 #[inline] from<T: ToPrimitive>(n: T) -> Option<Self>862 fn from<T: ToPrimitive>(n: T) -> Option<Self> { 863 n.to_f32().map(Self::from_f32) 864 } 865 } 866 867 impl num_traits::float::FloatCore for bf16 { 868 #[inline] infinity() -> Self869 fn infinity() -> Self { 870 Self::INFINITY 871 } 872 873 #[inline] neg_infinity() -> Self874 fn neg_infinity() -> Self { 875 Self::NEG_INFINITY 876 } 877 878 #[inline] nan() -> Self879 fn nan() -> Self { 880 Self::NAN 881 } 882 883 #[inline] neg_zero() -> Self884 fn neg_zero() -> Self { 885 Self::NEG_ZERO 886 } 887 888 #[inline] min_value() -> Self889 fn min_value() -> Self { 890 Self::MIN 891 } 892 893 #[inline] min_positive_value() -> Self894 fn min_positive_value() -> Self { 895 Self::MIN_POSITIVE 896 } 897 898 #[inline] epsilon() -> Self899 fn epsilon() -> Self { 900 Self::EPSILON 901 } 902 903 #[inline] max_value() -> Self904 fn max_value() -> Self { 905 Self::MAX 906 } 907 908 #[inline] is_nan(self) -> bool909 fn is_nan(self) -> bool { 910 self.is_nan() 911 } 912 913 #[inline] is_infinite(self) -> bool914 fn is_infinite(self) -> bool { 915 self.is_infinite() 916 } 917 918 #[inline] is_finite(self) -> bool919 fn is_finite(self) -> bool { 920 self.is_finite() 921 } 922 923 #[inline] is_normal(self) -> bool924 fn is_normal(self) -> bool { 925 self.is_normal() 926 } 927 928 #[inline] classify(self) -> FpCategory929 fn classify(self) -> FpCategory { 930 self.classify() 931 } 932 933 #[inline] floor(self) -> Self934 fn floor(self) -> Self { 935 Self::from_f32(self.to_f32().floor()) 936 } 937 938 #[inline] ceil(self) -> Self939 fn ceil(self) -> Self { 940 Self::from_f32(self.to_f32().ceil()) 941 } 942 943 #[inline] round(self) -> Self944 fn round(self) -> Self { 945 Self::from_f32(self.to_f32().round()) 946 } 947 948 #[inline] trunc(self) -> Self949 fn trunc(self) -> Self { 950 Self::from_f32(self.to_f32().trunc()) 951 } 952 953 #[inline] fract(self) -> Self954 fn fract(self) -> Self { 955 Self::from_f32(self.to_f32().fract()) 956 } 957 958 #[inline] abs(self) -> Self959 fn abs(self) -> Self { 960 Self::from_bits(self.to_bits() & 0x7FFF) 961 } 962 963 #[inline] signum(self) -> Self964 fn signum(self) -> Self { 965 self.signum() 966 } 967 968 #[inline] is_sign_positive(self) -> bool969 fn is_sign_positive(self) -> bool { 970 self.is_sign_positive() 971 } 972 973 #[inline] is_sign_negative(self) -> bool974 fn is_sign_negative(self) -> bool { 975 self.is_sign_negative() 976 } 977 min(self, other: Self) -> Self978 fn min(self, other: Self) -> Self { 979 match self.partial_cmp(&other) { 980 None => { 981 if self.is_nan() { 982 other 983 } else { 984 self 985 } 986 } 987 Some(Ordering::Greater) | Some(Ordering::Equal) => other, 988 Some(Ordering::Less) => self, 989 } 990 } 991 max(self, other: Self) -> Self992 fn max(self, other: Self) -> Self { 993 match self.partial_cmp(&other) { 994 None => { 995 if self.is_nan() { 996 other 997 } else { 998 self 999 } 1000 } 1001 Some(Ordering::Greater) | Some(Ordering::Equal) => self, 1002 Some(Ordering::Less) => other, 1003 } 1004 } 1005 1006 #[inline] recip(self) -> Self1007 fn recip(self) -> Self { 1008 Self::from_f32(self.to_f32().recip()) 1009 } 1010 1011 #[inline] powi(self, exp: i32) -> Self1012 fn powi(self, exp: i32) -> Self { 1013 Self::from_f32(self.to_f32().powi(exp)) 1014 } 1015 1016 #[inline] to_degrees(self) -> Self1017 fn to_degrees(self) -> Self { 1018 Self::from_f32(self.to_f32().to_degrees()) 1019 } 1020 1021 #[inline] to_radians(self) -> Self1022 fn to_radians(self) -> Self { 1023 Self::from_f32(self.to_f32().to_radians()) 1024 } 1025 1026 #[inline] integer_decode(self) -> (u64, i16, i8)1027 fn integer_decode(self) -> (u64, i16, i8) { 1028 num_traits::float::FloatCore::integer_decode(self.to_f32()) 1029 } 1030 } 1031 1032 impl num_traits::float::Float for bf16 { 1033 #[inline] nan() -> Self1034 fn nan() -> Self { 1035 Self::NAN 1036 } 1037 1038 #[inline] infinity() -> Self1039 fn infinity() -> Self { 1040 Self::INFINITY 1041 } 1042 1043 #[inline] neg_infinity() -> Self1044 fn neg_infinity() -> Self { 1045 Self::NEG_INFINITY 1046 } 1047 1048 #[inline] neg_zero() -> Self1049 fn neg_zero() -> Self { 1050 Self::NEG_ZERO 1051 } 1052 1053 #[inline] min_value() -> Self1054 fn min_value() -> Self { 1055 Self::MIN 1056 } 1057 1058 #[inline] min_positive_value() -> Self1059 fn min_positive_value() -> Self { 1060 Self::MIN_POSITIVE 1061 } 1062 1063 #[inline] epsilon() -> Self1064 fn epsilon() -> Self { 1065 Self::EPSILON 1066 } 1067 1068 #[inline] max_value() -> Self1069 fn max_value() -> Self { 1070 Self::MAX 1071 } 1072 1073 #[inline] is_nan(self) -> bool1074 fn is_nan(self) -> bool { 1075 self.is_nan() 1076 } 1077 1078 #[inline] is_infinite(self) -> bool1079 fn is_infinite(self) -> bool { 1080 self.is_infinite() 1081 } 1082 1083 #[inline] is_finite(self) -> bool1084 fn is_finite(self) -> bool { 1085 self.is_finite() 1086 } 1087 1088 #[inline] is_normal(self) -> bool1089 fn is_normal(self) -> bool { 1090 self.is_normal() 1091 } 1092 1093 #[inline] classify(self) -> FpCategory1094 fn classify(self) -> FpCategory { 1095 self.classify() 1096 } 1097 1098 #[inline] floor(self) -> Self1099 fn floor(self) -> Self { 1100 Self::from_f32(self.to_f32().floor()) 1101 } 1102 1103 #[inline] ceil(self) -> Self1104 fn ceil(self) -> Self { 1105 Self::from_f32(self.to_f32().ceil()) 1106 } 1107 1108 #[inline] round(self) -> Self1109 fn round(self) -> Self { 1110 Self::from_f32(self.to_f32().round()) 1111 } 1112 1113 #[inline] trunc(self) -> Self1114 fn trunc(self) -> Self { 1115 Self::from_f32(self.to_f32().trunc()) 1116 } 1117 1118 #[inline] fract(self) -> Self1119 fn fract(self) -> Self { 1120 Self::from_f32(self.to_f32().fract()) 1121 } 1122 1123 #[inline] abs(self) -> Self1124 fn abs(self) -> Self { 1125 Self::from_f32(self.to_f32().abs()) 1126 } 1127 1128 #[inline] signum(self) -> Self1129 fn signum(self) -> Self { 1130 Self::from_f32(self.to_f32().signum()) 1131 } 1132 1133 #[inline] is_sign_positive(self) -> bool1134 fn is_sign_positive(self) -> bool { 1135 self.is_sign_positive() 1136 } 1137 1138 #[inline] is_sign_negative(self) -> bool1139 fn is_sign_negative(self) -> bool { 1140 self.is_sign_negative() 1141 } 1142 1143 #[inline] mul_add(self, a: Self, b: Self) -> Self1144 fn mul_add(self, a: Self, b: Self) -> Self { 1145 Self::from_f32(self.to_f32().mul_add(a.to_f32(), b.to_f32())) 1146 } 1147 1148 #[inline] recip(self) -> Self1149 fn recip(self) -> Self { 1150 Self::from_f32(self.to_f32().recip()) 1151 } 1152 1153 #[inline] powi(self, n: i32) -> Self1154 fn powi(self, n: i32) -> Self { 1155 Self::from_f32(self.to_f32().powi(n)) 1156 } 1157 1158 #[inline] powf(self, n: Self) -> Self1159 fn powf(self, n: Self) -> Self { 1160 Self::from_f32(self.to_f32().powf(n.to_f32())) 1161 } 1162 1163 #[inline] sqrt(self) -> Self1164 fn sqrt(self) -> Self { 1165 Self::from_f32(self.to_f32().sqrt()) 1166 } 1167 1168 #[inline] exp(self) -> Self1169 fn exp(self) -> Self { 1170 Self::from_f32(self.to_f32().exp()) 1171 } 1172 1173 #[inline] exp2(self) -> Self1174 fn exp2(self) -> Self { 1175 Self::from_f32(self.to_f32().exp2()) 1176 } 1177 1178 #[inline] ln(self) -> Self1179 fn ln(self) -> Self { 1180 Self::from_f32(self.to_f32().ln()) 1181 } 1182 1183 #[inline] log(self, base: Self) -> Self1184 fn log(self, base: Self) -> Self { 1185 Self::from_f32(self.to_f32().log(base.to_f32())) 1186 } 1187 1188 #[inline] log2(self) -> Self1189 fn log2(self) -> Self { 1190 Self::from_f32(self.to_f32().log2()) 1191 } 1192 1193 #[inline] log10(self) -> Self1194 fn log10(self) -> Self { 1195 Self::from_f32(self.to_f32().log10()) 1196 } 1197 1198 #[inline] to_degrees(self) -> Self1199 fn to_degrees(self) -> Self { 1200 Self::from_f32(self.to_f32().to_degrees()) 1201 } 1202 1203 #[inline] to_radians(self) -> Self1204 fn to_radians(self) -> Self { 1205 Self::from_f32(self.to_f32().to_radians()) 1206 } 1207 1208 #[inline] max(self, other: Self) -> Self1209 fn max(self, other: Self) -> Self { 1210 self.max(other) 1211 } 1212 1213 #[inline] min(self, other: Self) -> Self1214 fn min(self, other: Self) -> Self { 1215 self.min(other) 1216 } 1217 1218 #[inline] abs_sub(self, other: Self) -> Self1219 fn abs_sub(self, other: Self) -> Self { 1220 Self::from_f32((self.to_f32() - other.to_f32()).max(0.0)) 1221 } 1222 1223 #[inline] cbrt(self) -> Self1224 fn cbrt(self) -> Self { 1225 Self::from_f32(self.to_f32().cbrt()) 1226 } 1227 1228 #[inline] hypot(self, other: Self) -> Self1229 fn hypot(self, other: Self) -> Self { 1230 Self::from_f32(self.to_f32().hypot(other.to_f32())) 1231 } 1232 1233 #[inline] sin(self) -> Self1234 fn sin(self) -> Self { 1235 Self::from_f32(self.to_f32().sin()) 1236 } 1237 1238 #[inline] cos(self) -> Self1239 fn cos(self) -> Self { 1240 Self::from_f32(self.to_f32().cos()) 1241 } 1242 1243 #[inline] tan(self) -> Self1244 fn tan(self) -> Self { 1245 Self::from_f32(self.to_f32().tan()) 1246 } 1247 1248 #[inline] asin(self) -> Self1249 fn asin(self) -> Self { 1250 Self::from_f32(self.to_f32().asin()) 1251 } 1252 1253 #[inline] acos(self) -> Self1254 fn acos(self) -> Self { 1255 Self::from_f32(self.to_f32().acos()) 1256 } 1257 1258 #[inline] atan(self) -> Self1259 fn atan(self) -> Self { 1260 Self::from_f32(self.to_f32().atan()) 1261 } 1262 1263 #[inline] atan2(self, other: Self) -> Self1264 fn atan2(self, other: Self) -> Self { 1265 Self::from_f32(self.to_f32().atan2(other.to_f32())) 1266 } 1267 1268 #[inline] sin_cos(self) -> (Self, Self)1269 fn sin_cos(self) -> (Self, Self) { 1270 let (sin, cos) = self.to_f32().sin_cos(); 1271 (Self::from_f32(sin), Self::from_f32(cos)) 1272 } 1273 1274 #[inline] exp_m1(self) -> Self1275 fn exp_m1(self) -> Self { 1276 Self::from_f32(self.to_f32().exp_m1()) 1277 } 1278 1279 #[inline] ln_1p(self) -> Self1280 fn ln_1p(self) -> Self { 1281 Self::from_f32(self.to_f32().ln_1p()) 1282 } 1283 1284 #[inline] sinh(self) -> Self1285 fn sinh(self) -> Self { 1286 Self::from_f32(self.to_f32().sinh()) 1287 } 1288 1289 #[inline] cosh(self) -> Self1290 fn cosh(self) -> Self { 1291 Self::from_f32(self.to_f32().cosh()) 1292 } 1293 1294 #[inline] tanh(self) -> Self1295 fn tanh(self) -> Self { 1296 Self::from_f32(self.to_f32().tanh()) 1297 } 1298 1299 #[inline] asinh(self) -> Self1300 fn asinh(self) -> Self { 1301 Self::from_f32(self.to_f32().asinh()) 1302 } 1303 1304 #[inline] acosh(self) -> Self1305 fn acosh(self) -> Self { 1306 Self::from_f32(self.to_f32().acosh()) 1307 } 1308 1309 #[inline] atanh(self) -> Self1310 fn atanh(self) -> Self { 1311 Self::from_f32(self.to_f32().atanh()) 1312 } 1313 1314 #[inline] integer_decode(self) -> (u64, i16, i8)1315 fn integer_decode(self) -> (u64, i16, i8) { 1316 num_traits::float::Float::integer_decode(self.to_f32()) 1317 } 1318 } 1319 1320 impl FloatConst for bf16 { 1321 #[inline] E() -> Self1322 fn E() -> Self { 1323 Self::E 1324 } 1325 1326 #[inline] FRAC_1_PI() -> Self1327 fn FRAC_1_PI() -> Self { 1328 Self::FRAC_1_PI 1329 } 1330 1331 #[inline] FRAC_1_SQRT_2() -> Self1332 fn FRAC_1_SQRT_2() -> Self { 1333 Self::FRAC_1_SQRT_2 1334 } 1335 1336 #[inline] FRAC_2_PI() -> Self1337 fn FRAC_2_PI() -> Self { 1338 Self::FRAC_2_PI 1339 } 1340 1341 #[inline] FRAC_2_SQRT_PI() -> Self1342 fn FRAC_2_SQRT_PI() -> Self { 1343 Self::FRAC_2_SQRT_PI 1344 } 1345 1346 #[inline] FRAC_PI_2() -> Self1347 fn FRAC_PI_2() -> Self { 1348 Self::FRAC_PI_2 1349 } 1350 1351 #[inline] FRAC_PI_3() -> Self1352 fn FRAC_PI_3() -> Self { 1353 Self::FRAC_PI_3 1354 } 1355 1356 #[inline] FRAC_PI_4() -> Self1357 fn FRAC_PI_4() -> Self { 1358 Self::FRAC_PI_4 1359 } 1360 1361 #[inline] FRAC_PI_6() -> Self1362 fn FRAC_PI_6() -> Self { 1363 Self::FRAC_PI_6 1364 } 1365 1366 #[inline] FRAC_PI_8() -> Self1367 fn FRAC_PI_8() -> Self { 1368 Self::FRAC_PI_8 1369 } 1370 1371 #[inline] LN_10() -> Self1372 fn LN_10() -> Self { 1373 Self::LN_10 1374 } 1375 1376 #[inline] LN_2() -> Self1377 fn LN_2() -> Self { 1378 Self::LN_2 1379 } 1380 1381 #[inline] LOG10_E() -> Self1382 fn LOG10_E() -> Self { 1383 Self::LOG10_E 1384 } 1385 1386 #[inline] LOG2_E() -> Self1387 fn LOG2_E() -> Self { 1388 Self::LOG2_E 1389 } 1390 1391 #[inline] PI() -> Self1392 fn PI() -> Self { 1393 Self::PI 1394 } 1395 1396 #[inline] SQRT_2() -> Self1397 fn SQRT_2() -> Self { 1398 Self::SQRT_2 1399 } 1400 1401 #[inline] LOG10_2() -> Self where Self: Sized + Div<Self, Output = Self>,1402 fn LOG10_2() -> Self 1403 where 1404 Self: Sized + Div<Self, Output = Self>, 1405 { 1406 Self::LOG10_2 1407 } 1408 1409 #[inline] LOG2_10() -> Self where Self: Sized + Div<Self, Output = Self>,1410 fn LOG2_10() -> Self 1411 where 1412 Self: Sized + Div<Self, Output = Self>, 1413 { 1414 Self::LOG2_10 1415 } 1416 } 1417 1418 impl Bounded for bf16 { 1419 #[inline] min_value() -> Self1420 fn min_value() -> Self { 1421 bf16::MIN 1422 } 1423 1424 #[inline] max_value() -> Self1425 fn max_value() -> Self { 1426 bf16::MAX 1427 } 1428 } 1429 1430 impl AsPrimitive<bf16> for bf16 { 1431 #[inline] as_(self) -> bf161432 fn as_(self) -> bf16 { 1433 self 1434 } 1435 } 1436 1437 macro_rules! impl_as_primitive_to_bf16 { 1438 ($ty:ty, $meth:ident) => { 1439 impl AsPrimitive<$ty> for bf16 { 1440 #[inline] 1441 fn as_(self) -> $ty { 1442 self.$meth().as_() 1443 } 1444 } 1445 }; 1446 } 1447 1448 impl_as_primitive_to_bf16!(i64, to_f32); 1449 impl_as_primitive_to_bf16!(u64, to_f32); 1450 impl_as_primitive_to_bf16!(i8, to_f32); 1451 impl_as_primitive_to_bf16!(u8, to_f32); 1452 impl_as_primitive_to_bf16!(i16, to_f32); 1453 impl_as_primitive_to_bf16!(u16, to_f32); 1454 impl_as_primitive_to_bf16!(i32, to_f32); 1455 impl_as_primitive_to_bf16!(u32, to_f32); 1456 impl_as_primitive_to_bf16!(isize, to_f32); 1457 impl_as_primitive_to_bf16!(usize, to_f32); 1458 impl_as_primitive_to_bf16!(f32, to_f32); 1459 impl_as_primitive_to_bf16!(f64, to_f64); 1460 1461 macro_rules! impl_as_primitive_bf16_from { 1462 ($ty:ty, $meth:ident) => { 1463 impl AsPrimitive<bf16> for $ty { 1464 #[inline] 1465 fn as_(self) -> bf16 { 1466 bf16::$meth(self.as_()) 1467 } 1468 } 1469 }; 1470 } 1471 1472 impl_as_primitive_bf16_from!(i64, from_f32); 1473 impl_as_primitive_bf16_from!(u64, from_f32); 1474 impl_as_primitive_bf16_from!(i8, from_f32); 1475 impl_as_primitive_bf16_from!(u8, from_f32); 1476 impl_as_primitive_bf16_from!(i16, from_f32); 1477 impl_as_primitive_bf16_from!(u16, from_f32); 1478 impl_as_primitive_bf16_from!(i32, from_f32); 1479 impl_as_primitive_bf16_from!(u32, from_f32); 1480 impl_as_primitive_bf16_from!(isize, from_f32); 1481 impl_as_primitive_bf16_from!(usize, from_f32); 1482 impl_as_primitive_bf16_from!(f32, from_f32); 1483 impl_as_primitive_bf16_from!(f64, from_f64); 1484