|
20 | 20 | use intrinsics;
|
21 | 21 | use mem;
|
22 | 22 | use num::Float;
|
| 23 | +#[cfg(not(stage0))] use num::FpCategory; |
23 | 24 | use num::FpCategory as Fp;
|
24 | 25 |
|
25 | 26 | /// The radix or base of the internal representation of `f32`.
|
@@ -292,3 +293,286 @@ impl Float for f32 {
|
292 | 293 | unsafe { mem::transmute(v) }
|
293 | 294 | }
|
294 | 295 | }
|
| 296 | + |
| 297 | +// FIXME: remove (inline) this macro and the Float trait |
| 298 | +// when updating to a bootstrap compiler that has the new lang items. |
| 299 | +#[cfg_attr(stage0, macro_export)] |
| 300 | +#[unstable(feature = "core_float", issue = "32110")] |
| 301 | +macro_rules! f32_core_methods { () => { |
| 302 | + /// Returns `true` if this value is `NaN` and false otherwise. |
| 303 | + /// |
| 304 | + /// ``` |
| 305 | + /// use std::f32; |
| 306 | + /// |
| 307 | + /// let nan = f32::NAN; |
| 308 | + /// let f = 7.0_f32; |
| 309 | + /// |
| 310 | + /// assert!(nan.is_nan()); |
| 311 | + /// assert!(!f.is_nan()); |
| 312 | + /// ``` |
| 313 | + #[stable(feature = "rust1", since = "1.0.0")] |
| 314 | + #[inline] |
| 315 | + pub fn is_nan(self) -> bool { Float::is_nan(self) } |
| 316 | + |
| 317 | + /// Returns `true` if this value is positive infinity or negative infinity and |
| 318 | + /// false otherwise. |
| 319 | + /// |
| 320 | + /// ``` |
| 321 | + /// use std::f32; |
| 322 | + /// |
| 323 | + /// let f = 7.0f32; |
| 324 | + /// let inf = f32::INFINITY; |
| 325 | + /// let neg_inf = f32::NEG_INFINITY; |
| 326 | + /// let nan = f32::NAN; |
| 327 | + /// |
| 328 | + /// assert!(!f.is_infinite()); |
| 329 | + /// assert!(!nan.is_infinite()); |
| 330 | + /// |
| 331 | + /// assert!(inf.is_infinite()); |
| 332 | + /// assert!(neg_inf.is_infinite()); |
| 333 | + /// ``` |
| 334 | + #[stable(feature = "rust1", since = "1.0.0")] |
| 335 | + #[inline] |
| 336 | + pub fn is_infinite(self) -> bool { Float::is_infinite(self) } |
| 337 | + |
| 338 | + /// Returns `true` if this number is neither infinite nor `NaN`. |
| 339 | + /// |
| 340 | + /// ``` |
| 341 | + /// use std::f32; |
| 342 | + /// |
| 343 | + /// let f = 7.0f32; |
| 344 | + /// let inf = f32::INFINITY; |
| 345 | + /// let neg_inf = f32::NEG_INFINITY; |
| 346 | + /// let nan = f32::NAN; |
| 347 | + /// |
| 348 | + /// assert!(f.is_finite()); |
| 349 | + /// |
| 350 | + /// assert!(!nan.is_finite()); |
| 351 | + /// assert!(!inf.is_finite()); |
| 352 | + /// assert!(!neg_inf.is_finite()); |
| 353 | + /// ``` |
| 354 | + #[stable(feature = "rust1", since = "1.0.0")] |
| 355 | + #[inline] |
| 356 | + pub fn is_finite(self) -> bool { Float::is_finite(self) } |
| 357 | + |
| 358 | + /// Returns `true` if the number is neither zero, infinite, |
| 359 | + /// [subnormal][subnormal], or `NaN`. |
| 360 | + /// |
| 361 | + /// ``` |
| 362 | + /// use std::f32; |
| 363 | + /// |
| 364 | + /// let min = f32::MIN_POSITIVE; // 1.17549435e-38f32 |
| 365 | + /// let max = f32::MAX; |
| 366 | + /// let lower_than_min = 1.0e-40_f32; |
| 367 | + /// let zero = 0.0_f32; |
| 368 | + /// |
| 369 | + /// assert!(min.is_normal()); |
| 370 | + /// assert!(max.is_normal()); |
| 371 | + /// |
| 372 | + /// assert!(!zero.is_normal()); |
| 373 | + /// assert!(!f32::NAN.is_normal()); |
| 374 | + /// assert!(!f32::INFINITY.is_normal()); |
| 375 | + /// // Values between `0` and `min` are Subnormal. |
| 376 | + /// assert!(!lower_than_min.is_normal()); |
| 377 | + /// ``` |
| 378 | + /// [subnormal]: https://en.wikipedia.org/wiki/Denormal_number |
| 379 | + #[stable(feature = "rust1", since = "1.0.0")] |
| 380 | + #[inline] |
| 381 | + pub fn is_normal(self) -> bool { Float::is_normal(self) } |
| 382 | + |
| 383 | + /// Returns the floating point category of the number. If only one property |
| 384 | + /// is going to be tested, it is generally faster to use the specific |
| 385 | + /// predicate instead. |
| 386 | + /// |
| 387 | + /// ``` |
| 388 | + /// use std::num::FpCategory; |
| 389 | + /// use std::f32; |
| 390 | + /// |
| 391 | + /// let num = 12.4_f32; |
| 392 | + /// let inf = f32::INFINITY; |
| 393 | + /// |
| 394 | + /// assert_eq!(num.classify(), FpCategory::Normal); |
| 395 | + /// assert_eq!(inf.classify(), FpCategory::Infinite); |
| 396 | + /// ``` |
| 397 | + #[stable(feature = "rust1", since = "1.0.0")] |
| 398 | + #[inline] |
| 399 | + pub fn classify(self) -> FpCategory { Float::classify(self) } |
| 400 | + |
| 401 | + /// Returns `true` if and only if `self` has a positive sign, including `+0.0`, `NaN`s with |
| 402 | + /// positive sign bit and positive infinity. |
| 403 | + /// |
| 404 | + /// ``` |
| 405 | + /// let f = 7.0_f32; |
| 406 | + /// let g = -7.0_f32; |
| 407 | + /// |
| 408 | + /// assert!(f.is_sign_positive()); |
| 409 | + /// assert!(!g.is_sign_positive()); |
| 410 | + /// ``` |
| 411 | + #[stable(feature = "rust1", since = "1.0.0")] |
| 412 | + #[inline] |
| 413 | + pub fn is_sign_positive(self) -> bool { Float::is_sign_positive(self) } |
| 414 | + |
| 415 | + /// Returns `true` if and only if `self` has a negative sign, including `-0.0`, `NaN`s with |
| 416 | + /// negative sign bit and negative infinity. |
| 417 | + /// |
| 418 | + /// ``` |
| 419 | + /// let f = 7.0f32; |
| 420 | + /// let g = -7.0f32; |
| 421 | + /// |
| 422 | + /// assert!(!f.is_sign_negative()); |
| 423 | + /// assert!(g.is_sign_negative()); |
| 424 | + /// ``` |
| 425 | + #[stable(feature = "rust1", since = "1.0.0")] |
| 426 | + #[inline] |
| 427 | + pub fn is_sign_negative(self) -> bool { Float::is_sign_negative(self) } |
| 428 | + |
| 429 | + /// Takes the reciprocal (inverse) of a number, `1/x`. |
| 430 | + /// |
| 431 | + /// ``` |
| 432 | + /// use std::f32; |
| 433 | + /// |
| 434 | + /// let x = 2.0_f32; |
| 435 | + /// let abs_difference = (x.recip() - (1.0/x)).abs(); |
| 436 | + /// |
| 437 | + /// assert!(abs_difference <= f32::EPSILON); |
| 438 | + /// ``` |
| 439 | + #[stable(feature = "rust1", since = "1.0.0")] |
| 440 | + #[inline] |
| 441 | + pub fn recip(self) -> f32 { Float::recip(self) } |
| 442 | + |
| 443 | + /// Converts radians to degrees. |
| 444 | + /// |
| 445 | + /// ``` |
| 446 | + /// use std::f32::{self, consts}; |
| 447 | + /// |
| 448 | + /// let angle = consts::PI; |
| 449 | + /// |
| 450 | + /// let abs_difference = (angle.to_degrees() - 180.0).abs(); |
| 451 | + /// |
| 452 | + /// assert!(abs_difference <= f32::EPSILON); |
| 453 | + /// ``` |
| 454 | + #[stable(feature = "f32_deg_rad_conversions", since="1.7.0")] |
| 455 | + #[inline] |
| 456 | + pub fn to_degrees(self) -> f32 { Float::to_degrees(self) } |
| 457 | + |
| 458 | + /// Converts degrees to radians. |
| 459 | + /// |
| 460 | + /// ``` |
| 461 | + /// use std::f32::{self, consts}; |
| 462 | + /// |
| 463 | + /// let angle = 180.0f32; |
| 464 | + /// |
| 465 | + /// let abs_difference = (angle.to_radians() - consts::PI).abs(); |
| 466 | + /// |
| 467 | + /// assert!(abs_difference <= f32::EPSILON); |
| 468 | + /// ``` |
| 469 | + #[stable(feature = "f32_deg_rad_conversions", since="1.7.0")] |
| 470 | + #[inline] |
| 471 | + pub fn to_radians(self) -> f32 { Float::to_radians(self) } |
| 472 | + |
| 473 | + /// Returns the maximum of the two numbers. |
| 474 | + /// |
| 475 | + /// ``` |
| 476 | + /// let x = 1.0f32; |
| 477 | + /// let y = 2.0f32; |
| 478 | + /// |
| 479 | + /// assert_eq!(x.max(y), y); |
| 480 | + /// ``` |
| 481 | + /// |
| 482 | + /// If one of the arguments is NaN, then the other argument is returned. |
| 483 | + #[stable(feature = "rust1", since = "1.0.0")] |
| 484 | + #[inline] |
| 485 | + pub fn max(self, other: f32) -> f32 { |
| 486 | + Float::max(self, other) |
| 487 | + } |
| 488 | + |
| 489 | + /// Returns the minimum of the two numbers. |
| 490 | + /// |
| 491 | + /// ``` |
| 492 | + /// let x = 1.0f32; |
| 493 | + /// let y = 2.0f32; |
| 494 | + /// |
| 495 | + /// assert_eq!(x.min(y), x); |
| 496 | + /// ``` |
| 497 | + /// |
| 498 | + /// If one of the arguments is NaN, then the other argument is returned. |
| 499 | + #[stable(feature = "rust1", since = "1.0.0")] |
| 500 | + #[inline] |
| 501 | + pub fn min(self, other: f32) -> f32 { |
| 502 | + Float::min(self, other) |
| 503 | + } |
| 504 | + |
| 505 | + /// Raw transmutation to `u32`. |
| 506 | + /// |
| 507 | + /// This is currently identical to `transmute::<f32, u32>(self)` on all platforms. |
| 508 | + /// |
| 509 | + /// See `from_bits` for some discussion of the portability of this operation |
| 510 | + /// (there are almost no issues). |
| 511 | + /// |
| 512 | + /// Note that this function is distinct from `as` casting, which attempts to |
| 513 | + /// preserve the *numeric* value, and not the bitwise value. |
| 514 | + /// |
| 515 | + /// # Examples |
| 516 | + /// |
| 517 | + /// ``` |
| 518 | + /// assert_ne!((1f32).to_bits(), 1f32 as u32); // to_bits() is not casting! |
| 519 | + /// assert_eq!((12.5f32).to_bits(), 0x41480000); |
| 520 | + /// |
| 521 | + /// ``` |
| 522 | + #[stable(feature = "float_bits_conv", since = "1.20.0")] |
| 523 | + #[inline] |
| 524 | + pub fn to_bits(self) -> u32 { |
| 525 | + Float::to_bits(self) |
| 526 | + } |
| 527 | + |
| 528 | + /// Raw transmutation from `u32`. |
| 529 | + /// |
| 530 | + /// This is currently identical to `transmute::<u32, f32>(v)` on all platforms. |
| 531 | + /// It turns out this is incredibly portable, for two reasons: |
| 532 | + /// |
| 533 | + /// * Floats and Ints have the same endianness on all supported platforms. |
| 534 | + /// * IEEE-754 very precisely specifies the bit layout of floats. |
| 535 | + /// |
| 536 | + /// However there is one caveat: prior to the 2008 version of IEEE-754, how |
| 537 | + /// to interpret the NaN signaling bit wasn't actually specified. Most platforms |
| 538 | + /// (notably x86 and ARM) picked the interpretation that was ultimately |
| 539 | + /// standardized in 2008, but some didn't (notably MIPS). As a result, all |
| 540 | + /// signaling NaNs on MIPS are quiet NaNs on x86, and vice-versa. |
| 541 | + /// |
| 542 | + /// Rather than trying to preserve signaling-ness cross-platform, this |
| 543 | + /// implementation favours preserving the exact bits. This means that |
| 544 | + /// any payloads encoded in NaNs will be preserved even if the result of |
| 545 | + /// this method is sent over the network from an x86 machine to a MIPS one. |
| 546 | + /// |
| 547 | + /// If the results of this method are only manipulated by the same |
| 548 | + /// architecture that produced them, then there is no portability concern. |
| 549 | + /// |
| 550 | + /// If the input isn't NaN, then there is no portability concern. |
| 551 | + /// |
| 552 | + /// If you don't care about signalingness (very likely), then there is no |
| 553 | + /// portability concern. |
| 554 | + /// |
| 555 | + /// Note that this function is distinct from `as` casting, which attempts to |
| 556 | + /// preserve the *numeric* value, and not the bitwise value. |
| 557 | + /// |
| 558 | + /// # Examples |
| 559 | + /// |
| 560 | + /// ``` |
| 561 | + /// use std::f32; |
| 562 | + /// let v = f32::from_bits(0x41480000); |
| 563 | + /// let difference = (v - 12.5).abs(); |
| 564 | + /// assert!(difference <= 1e-5); |
| 565 | + /// ``` |
| 566 | + #[stable(feature = "float_bits_conv", since = "1.20.0")] |
| 567 | + #[inline] |
| 568 | + pub fn from_bits(v: u32) -> Self { |
| 569 | + Float::from_bits(v) |
| 570 | + } |
| 571 | +}} |
| 572 | + |
| 573 | +#[lang = "f32"] |
| 574 | +#[cfg(not(test))] |
| 575 | +#[cfg(not(stage0))] |
| 576 | +impl f32 { |
| 577 | + f32_core_methods!(); |
| 578 | +} |
0 commit comments