Rollup merge of #128417 - tgross35:f16-f128-math, r=dtolnay · patricklam/verify-rust-std@5d7906c (original) (raw)

`@@ -686,6 +686,182 @@ impl f128 {

`

686

686

`self * RADS_PER_DEG

`

687

687

`}

`

688

688

``

``

689

`+

/// Returns the maximum of the two numbers, ignoring NaN.

`

``

690

`+

///

`

``

691

`+

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

`

``

692

`+

/// This follows the IEEE 754-2008 semantics for maxNum, except for handling of signaling NaNs;

`

``

693

`+

/// this function handles all NaNs the same way and avoids maxNum's problems with associativity.

`

``

694

`+

/// This also matches the behavior of libm’s fmax.

`

``

695

`+

///

`

``

696


/// ```

``

697

`+

/// #![feature(f128)]

`

``

698

`` +

/// # // Using aarch64 because reliable_f128_math is needed

``

``

699

`+

/// # #[cfg(all(target_arch = "aarch64", target_os = "linux"))] {

`

``

700

`+

///

`

``

701

`+

/// let x = 1.0f128;

`

``

702

`+

/// let y = 2.0f128;

`

``

703

`+

///

`

``

704

`+

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

`

``

705

`+

/// # }

`

``

706


/// ```

``

707

`+

#[inline]

`

``

708

`+

#[unstable(feature = "f128", issue = "116909")]

`

``

709

`+

#[must_use = "this returns the result of the comparison, without modifying either input"]

`

``

710

`+

pub fn max(self, other: f128) -> f128 {

`

``

711

`+

intrinsics::maxnumf128(self, other)

`

``

712

`+

}

`

``

713

+

``

714

`+

/// Returns the minimum of the two numbers, ignoring NaN.

`

``

715

`+

///

`

``

716

`+

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

`

``

717

`+

/// This follows the IEEE 754-2008 semantics for minNum, except for handling of signaling NaNs;

`

``

718

`+

/// this function handles all NaNs the same way and avoids minNum's problems with associativity.

`

``

719

`+

/// This also matches the behavior of libm’s fmin.

`

``

720

`+

///

`

``

721


/// ```

``

722

`+

/// #![feature(f128)]

`

``

723

`` +

/// # // Using aarch64 because reliable_f128_math is needed

``

``

724

`+

/// # #[cfg(all(target_arch = "aarch64", target_os = "linux"))] {

`

``

725

`+

///

`

``

726

`+

/// let x = 1.0f128;

`

``

727

`+

/// let y = 2.0f128;

`

``

728

`+

///

`

``

729

`+

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

`

``

730

`+

/// # }

`

``

731


/// ```

``

732

`+

#[inline]

`

``

733

`+

#[unstable(feature = "f128", issue = "116909")]

`

``

734

`+

#[must_use = "this returns the result of the comparison, without modifying either input"]

`

``

735

`+

pub fn min(self, other: f128) -> f128 {

`

``

736

`+

intrinsics::minnumf128(self, other)

`

``

737

`+

}

`

``

738

+

``

739

`+

/// Returns the maximum of the two numbers, propagating NaN.

`

``

740

`+

///

`

``

741

`+

/// This returns NaN when either argument is NaN, as opposed to

`

``

742

`` +

/// [f128::max] which only returns NaN when both arguments are NaN.

``

``

743

`+

///

`

``

744


/// ```

``

745

`+

/// #![feature(f128)]

`

``

746

`+

/// #![feature(float_minimum_maximum)]

`

``

747

`` +

/// # // Using aarch64 because reliable_f128_math is needed

``

``

748

`+

/// # #[cfg(all(target_arch = "aarch64", target_os = "linux"))] {

`

``

749

`+

///

`

``

750

`+

/// let x = 1.0f128;

`

``

751

`+

/// let y = 2.0f128;

`

``

752

`+

///

`

``

753

`+

/// assert_eq!(x.maximum(y), y);

`

``

754

`+

/// assert!(x.maximum(f128::NAN).is_nan());

`

``

755

`+

/// # }

`

``

756


/// ```

``

757

`+

///

`

``

758

`+

/// If one of the arguments is NaN, then NaN is returned. Otherwise this returns the greater

`

``

759

`+

/// of the two numbers. For this operation, -0.0 is considered to be less than +0.0.

`

``

760

`+

/// Note that this follows the semantics specified in IEEE 754-2019.

`

``

761

`+

///

`

``

762

`+

/// Also note that "propagation" of NaNs here doesn't necessarily mean that the bitpattern of a NaN

`

``

763

`+

/// operand is conserved; see explanation of NaN as a special value for more info.

`

``

764

`+

#[inline]

`

``

765

`+

#[unstable(feature = "f128", issue = "116909")]

`

``

766

`+

// #[unstable(feature = "float_minimum_maximum", issue = "91079")]

`

``

767

`+

#[must_use = "this returns the result of the comparison, without modifying either input"]

`

``

768

`+

pub fn maximum(self, other: f128) -> f128 {

`

``

769

`+

if self > other {

`

``

770

`+

self

`

``

771

`+

} else if other > self {

`

``

772

`+

other

`

``

773

`+

} else if self == other {

`

``

774

`+

if self.is_sign_positive() && other.is_sign_negative() { self } else { other }

`

``

775

`+

} else {

`

``

776

`+

self + other

`

``

777

`+

}

`

``

778

`+

}

`

``

779

+

``

780

`+

/// Returns the minimum of the two numbers, propagating NaN.

`

``

781

`+

///

`

``

782

`+

/// This returns NaN when either argument is NaN, as opposed to

`

``

783

`` +

/// [f128::min] which only returns NaN when both arguments are NaN.

``

``

784

`+

///

`

``

785


/// ```

``

786

`+

/// #![feature(f128)]

`

``

787

`+

/// #![feature(float_minimum_maximum)]

`

``

788

`` +

/// # // Using aarch64 because reliable_f128_math is needed

``

``

789

`+

/// # #[cfg(all(target_arch = "aarch64", target_os = "linux"))] {

`

``

790

`+

///

`

``

791

`+

/// let x = 1.0f128;

`

``

792

`+

/// let y = 2.0f128;

`

``

793

`+

///

`

``

794

`+

/// assert_eq!(x.minimum(y), x);

`

``

795

`+

/// assert!(x.minimum(f128::NAN).is_nan());

`

``

796

`+

/// # }

`

``

797


/// ```

``

798

`+

///

`

``

799

`+

/// If one of the arguments is NaN, then NaN is returned. Otherwise this returns the lesser

`

``

800

`+

/// of the two numbers. For this operation, -0.0 is considered to be less than +0.0.

`

``

801

`+

/// Note that this follows the semantics specified in IEEE 754-2019.

`

``

802

`+

///

`

``

803

`+

/// Also note that "propagation" of NaNs here doesn't necessarily mean that the bitpattern of a NaN

`

``

804

`+

/// operand is conserved; see explanation of NaN as a special value for more info.

`

``

805

`+

#[inline]

`

``

806

`+

#[unstable(feature = "f128", issue = "116909")]

`

``

807

`+

// #[unstable(feature = "float_minimum_maximum", issue = "91079")]

`

``

808

`+

#[must_use = "this returns the result of the comparison, without modifying either input"]

`

``

809

`+

pub fn minimum(self, other: f128) -> f128 {

`

``

810

`+

if self < other {

`

``

811

`+

self

`

``

812

`+

} else if other < self {

`

``

813

`+

other

`

``

814

`+

} else if self == other {

`

``

815

`+

if self.is_sign_negative() && other.is_sign_positive() { self } else { other }

`

``

816

`+

} else {

`

``

817

`` +

// At least one input is NaN. Use + to perform NaN propagation and quieting.

``

``

818

`+

self + other

`

``

819

`+

}

`

``

820

`+

}

`

``

821

+

``

822

`` +

/// Calculates the middle point of self and rhs.

``

``

823

`+

///

`

``

824

`+

/// This returns NaN when either argument is NaN or if a combination of

`

``

825

`+

/// +inf and -inf is provided as arguments.

`

``

826

`+

///

`

``

827

`+

/// # Examples

`

``

828

`+

///

`

``

829


/// ```

``

830

`+

/// #![feature(f128)]

`

``

831

`+

/// #![feature(num_midpoint)]

`

``

832

`` +

/// # // Using aarch64 because reliable_f128_math is needed

``

``

833

`+

/// # #[cfg(all(target_arch = "aarch64", target_os = "linux"))] {

`

``

834

`+

///

`

``

835

`+

/// assert_eq!(1f128.midpoint(4.0), 2.5);

`

``

836

`+

/// assert_eq!((-5.5f128).midpoint(8.0), 1.25);

`

``

837

`+

/// # }

`

``

838


/// ```

``

839

`+

#[inline]

`

``

840

`+

#[unstable(feature = "f128", issue = "116909")]

`

``

841

`+

// #[unstable(feature = "num_midpoint", issue = "110840")]

`

``

842

`+

pub fn midpoint(self, other: f128) -> f128 {

`

``

843

`+

const LO: f128 = f128::MIN_POSITIVE * 2.;

`

``

844

`+

const HI: f128 = f128::MAX / 2.;

`

``

845

+

``

846

`+

let (a, b) = (self, other);

`

``

847

`+

let abs_a = a.abs_private();

`

``

848

`+

let abs_b = b.abs_private();

`

``

849

+

``

850

`+

if abs_a <= HI && abs_b <= HI {

`

``

851

`+

// Overflow is impossible

`

``

852

`+

(a + b) / 2.

`

``

853

`+

} else if abs_a < LO {

`

``

854

`` +

// Not safe to halve a (would underflow)

``

``

855

`+

a + (b / 2.)

`

``

856

`+

} else if abs_b < LO {

`

``

857

`` +

// Not safe to halve b (would underflow)

``

``

858

`+

(a / 2.) + b

`

``

859

`+

} else {

`

``

860

`` +

// Safe to halve a and b

``

``

861

`+

(a / 2.) + (b / 2.)

`

``

862

`+

}

`

``

863

`+

}

`

``

864

+

689

865

`/// Rounds toward zero and converts to any primitive integer type,

`

690

866

`/// assuming that the value is finite and fits in that type.

`

691

867

`///

`