std/f128.rs
1//! Constants for the `f128` quadruple-precision floating point type.
2//!
3//! *[See also the `f128` primitive type](primitive@f128).*
4//!
5//! Mathematically significant numbers are provided in the `consts` sub-module.
6
7#[unstable(feature = "f128", issue = "116909")]
8pub use core::f128::consts;
9
10#[cfg(not(test))]
11use crate::intrinsics;
12#[cfg(not(test))]
13use crate::sys::cmath;
14
15#[cfg(not(test))]
16impl f128 {
17 /// Returns the largest integer less than or equal to `self`.
18 ///
19 /// This function always returns the precise result.
20 ///
21 /// # Examples
22 ///
23 /// ```
24 /// #![feature(f128)]
25 /// # #![feature(cfg_target_has_reliable_f16_f128)]
26 /// # #![expect(internal_features)]
27 /// # #[cfg(not(miri))]
28 /// # #[cfg(target_has_reliable_f128_math)] {
29 ///
30 /// let f = 3.7_f128;
31 /// let g = 3.0_f128;
32 /// let h = -3.7_f128;
33 ///
34 /// assert_eq!(f.floor(), 3.0);
35 /// assert_eq!(g.floor(), 3.0);
36 /// assert_eq!(h.floor(), -4.0);
37 /// # }
38 /// ```
39 #[inline]
40 #[rustc_allow_incoherent_impl]
41 #[unstable(feature = "f128", issue = "116909")]
42 #[must_use = "method returns a new number and does not mutate the original value"]
43 pub fn floor(self) -> f128 {
44 unsafe { intrinsics::floorf128(self) }
45 }
46
47 /// Returns the smallest integer greater than or equal to `self`.
48 ///
49 /// This function always returns the precise result.
50 ///
51 /// # Examples
52 ///
53 /// ```
54 /// #![feature(f128)]
55 /// # #![feature(cfg_target_has_reliable_f16_f128)]
56 /// # #![expect(internal_features)]
57 /// # #[cfg(not(miri))]
58 /// # #[cfg(target_has_reliable_f128_math)] {
59 ///
60 /// let f = 3.01_f128;
61 /// let g = 4.0_f128;
62 ///
63 /// assert_eq!(f.ceil(), 4.0);
64 /// assert_eq!(g.ceil(), 4.0);
65 /// # }
66 /// ```
67 #[inline]
68 #[doc(alias = "ceiling")]
69 #[rustc_allow_incoherent_impl]
70 #[unstable(feature = "f128", issue = "116909")]
71 #[must_use = "method returns a new number and does not mutate the original value"]
72 pub fn ceil(self) -> f128 {
73 unsafe { intrinsics::ceilf128(self) }
74 }
75
76 /// Returns the nearest integer to `self`. If a value is half-way between two
77 /// integers, round away from `0.0`.
78 ///
79 /// This function always returns the precise result.
80 ///
81 /// # Examples
82 ///
83 /// ```
84 /// #![feature(f128)]
85 /// # #![feature(cfg_target_has_reliable_f16_f128)]
86 /// # #![expect(internal_features)]
87 /// # #[cfg(not(miri))]
88 /// # #[cfg(target_has_reliable_f128_math)] {
89 ///
90 /// let f = 3.3_f128;
91 /// let g = -3.3_f128;
92 /// let h = -3.7_f128;
93 /// let i = 3.5_f128;
94 /// let j = 4.5_f128;
95 ///
96 /// assert_eq!(f.round(), 3.0);
97 /// assert_eq!(g.round(), -3.0);
98 /// assert_eq!(h.round(), -4.0);
99 /// assert_eq!(i.round(), 4.0);
100 /// assert_eq!(j.round(), 5.0);
101 /// # }
102 /// ```
103 #[inline]
104 #[rustc_allow_incoherent_impl]
105 #[unstable(feature = "f128", issue = "116909")]
106 #[must_use = "method returns a new number and does not mutate the original value"]
107 pub fn round(self) -> f128 {
108 unsafe { intrinsics::roundf128(self) }
109 }
110
111 /// Returns the nearest integer to a number. Rounds half-way cases to the number
112 /// with an even least significant digit.
113 ///
114 /// This function always returns the precise result.
115 ///
116 /// # Examples
117 ///
118 /// ```
119 /// #![feature(f128)]
120 /// # #![feature(cfg_target_has_reliable_f16_f128)]
121 /// # #![expect(internal_features)]
122 /// # #[cfg(not(miri))]
123 /// # #[cfg(target_has_reliable_f128_math)] {
124 ///
125 /// let f = 3.3_f128;
126 /// let g = -3.3_f128;
127 /// let h = 3.5_f128;
128 /// let i = 4.5_f128;
129 ///
130 /// assert_eq!(f.round_ties_even(), 3.0);
131 /// assert_eq!(g.round_ties_even(), -3.0);
132 /// assert_eq!(h.round_ties_even(), 4.0);
133 /// assert_eq!(i.round_ties_even(), 4.0);
134 /// # }
135 /// ```
136 #[inline]
137 #[rustc_allow_incoherent_impl]
138 #[unstable(feature = "f128", issue = "116909")]
139 #[must_use = "method returns a new number and does not mutate the original value"]
140 pub fn round_ties_even(self) -> f128 {
141 intrinsics::round_ties_even_f128(self)
142 }
143
144 /// Returns the integer part of `self`.
145 /// This means that non-integer numbers are always truncated towards zero.
146 ///
147 /// This function always returns the precise result.
148 ///
149 /// # Examples
150 ///
151 /// ```
152 /// #![feature(f128)]
153 /// # #![feature(cfg_target_has_reliable_f16_f128)]
154 /// # #![expect(internal_features)]
155 /// # #[cfg(not(miri))]
156 /// # #[cfg(target_has_reliable_f128_math)] {
157 ///
158 /// let f = 3.7_f128;
159 /// let g = 3.0_f128;
160 /// let h = -3.7_f128;
161 ///
162 /// assert_eq!(f.trunc(), 3.0);
163 /// assert_eq!(g.trunc(), 3.0);
164 /// assert_eq!(h.trunc(), -3.0);
165 /// # }
166 /// ```
167 #[inline]
168 #[doc(alias = "truncate")]
169 #[rustc_allow_incoherent_impl]
170 #[unstable(feature = "f128", issue = "116909")]
171 #[must_use = "method returns a new number and does not mutate the original value"]
172 pub fn trunc(self) -> f128 {
173 unsafe { intrinsics::truncf128(self) }
174 }
175
176 /// Returns the fractional part of `self`.
177 ///
178 /// This function always returns the precise result.
179 ///
180 /// # Examples
181 ///
182 /// ```
183 /// #![feature(f128)]
184 /// # #![feature(cfg_target_has_reliable_f16_f128)]
185 /// # #![expect(internal_features)]
186 /// # #[cfg(not(miri))]
187 /// # #[cfg(target_has_reliable_f128_math)] {
188 ///
189 /// let x = 3.6_f128;
190 /// let y = -3.6_f128;
191 /// let abs_difference_x = (x.fract() - 0.6).abs();
192 /// let abs_difference_y = (y.fract() - (-0.6)).abs();
193 ///
194 /// assert!(abs_difference_x <= f128::EPSILON);
195 /// assert!(abs_difference_y <= f128::EPSILON);
196 /// # }
197 /// ```
198 #[inline]
199 #[rustc_allow_incoherent_impl]
200 #[unstable(feature = "f128", issue = "116909")]
201 #[must_use = "method returns a new number and does not mutate the original value"]
202 pub fn fract(self) -> f128 {
203 self - self.trunc()
204 }
205
206 /// Fused multiply-add. Computes `(self * a) + b` with only one rounding
207 /// error, yielding a more accurate result than an unfused multiply-add.
208 ///
209 /// Using `mul_add` *may* be more performant than an unfused multiply-add if
210 /// the target architecture has a dedicated `fma` CPU instruction. However,
211 /// this is not always true, and will be heavily dependant on designing
212 /// algorithms with specific target hardware in mind.
213 ///
214 /// # Precision
215 ///
216 /// The result of this operation is guaranteed to be the rounded
217 /// infinite-precision result. It is specified by IEEE 754 as
218 /// `fusedMultiplyAdd` and guaranteed not to change.
219 ///
220 /// # Examples
221 ///
222 /// ```
223 /// #![feature(f128)]
224 /// # #![feature(cfg_target_has_reliable_f16_f128)]
225 /// # #![expect(internal_features)]
226 /// # #[cfg(not(miri))]
227 /// # #[cfg(target_has_reliable_f128_math)] {
228 ///
229 /// let m = 10.0_f128;
230 /// let x = 4.0_f128;
231 /// let b = 60.0_f128;
232 ///
233 /// assert_eq!(m.mul_add(x, b), 100.0);
234 /// assert_eq!(m * x + b, 100.0);
235 ///
236 /// let one_plus_eps = 1.0_f128 + f128::EPSILON;
237 /// let one_minus_eps = 1.0_f128 - f128::EPSILON;
238 /// let minus_one = -1.0_f128;
239 ///
240 /// // The exact result (1 + eps) * (1 - eps) = 1 - eps * eps.
241 /// assert_eq!(one_plus_eps.mul_add(one_minus_eps, minus_one), -f128::EPSILON * f128::EPSILON);
242 /// // Different rounding with the non-fused multiply and add.
243 /// assert_eq!(one_plus_eps * one_minus_eps + minus_one, 0.0);
244 /// # }
245 /// ```
246 #[inline]
247 #[rustc_allow_incoherent_impl]
248 #[doc(alias = "fmaf128", alias = "fusedMultiplyAdd")]
249 #[unstable(feature = "f128", issue = "116909")]
250 #[must_use = "method returns a new number and does not mutate the original value"]
251 pub fn mul_add(self, a: f128, b: f128) -> f128 {
252 unsafe { intrinsics::fmaf128(self, a, b) }
253 }
254
255 /// Calculates Euclidean division, the matching method for `rem_euclid`.
256 ///
257 /// This computes the integer `n` such that
258 /// `self = n * rhs + self.rem_euclid(rhs)`.
259 /// In other words, the result is `self / rhs` rounded to the integer `n`
260 /// such that `self >= n * rhs`.
261 ///
262 /// # Precision
263 ///
264 /// The result of this operation is guaranteed to be the rounded
265 /// infinite-precision result.
266 ///
267 /// # Examples
268 ///
269 /// ```
270 /// #![feature(f128)]
271 /// # #![feature(cfg_target_has_reliable_f16_f128)]
272 /// # #![expect(internal_features)]
273 /// # #[cfg(not(miri))]
274 /// # #[cfg(target_has_reliable_f128_math)] {
275 ///
276 /// let a: f128 = 7.0;
277 /// let b = 4.0;
278 /// assert_eq!(a.div_euclid(b), 1.0); // 7.0 > 4.0 * 1.0
279 /// assert_eq!((-a).div_euclid(b), -2.0); // -7.0 >= 4.0 * -2.0
280 /// assert_eq!(a.div_euclid(-b), -1.0); // 7.0 >= -4.0 * -1.0
281 /// assert_eq!((-a).div_euclid(-b), 2.0); // -7.0 >= -4.0 * 2.0
282 /// # }
283 /// ```
284 #[inline]
285 #[rustc_allow_incoherent_impl]
286 #[unstable(feature = "f128", issue = "116909")]
287 #[must_use = "method returns a new number and does not mutate the original value"]
288 pub fn div_euclid(self, rhs: f128) -> f128 {
289 let q = (self / rhs).trunc();
290 if self % rhs < 0.0 {
291 return if rhs > 0.0 { q - 1.0 } else { q + 1.0 };
292 }
293 q
294 }
295
296 /// Calculates the least nonnegative remainder of `self (mod rhs)`.
297 ///
298 /// In particular, the return value `r` satisfies `0.0 <= r < rhs.abs()` in
299 /// most cases. However, due to a floating point round-off error it can
300 /// result in `r == rhs.abs()`, violating the mathematical definition, if
301 /// `self` is much smaller than `rhs.abs()` in magnitude and `self < 0.0`.
302 /// This result is not an element of the function's codomain, but it is the
303 /// closest floating point number in the real numbers and thus fulfills the
304 /// property `self == self.div_euclid(rhs) * rhs + self.rem_euclid(rhs)`
305 /// approximately.
306 ///
307 /// # Precision
308 ///
309 /// The result of this operation is guaranteed to be the rounded
310 /// infinite-precision result.
311 ///
312 /// # Examples
313 ///
314 /// ```
315 /// #![feature(f128)]
316 /// # #![feature(cfg_target_has_reliable_f16_f128)]
317 /// # #![expect(internal_features)]
318 /// # #[cfg(not(miri))]
319 /// # #[cfg(target_has_reliable_f128_math)] {
320 ///
321 /// let a: f128 = 7.0;
322 /// let b = 4.0;
323 /// assert_eq!(a.rem_euclid(b), 3.0);
324 /// assert_eq!((-a).rem_euclid(b), 1.0);
325 /// assert_eq!(a.rem_euclid(-b), 3.0);
326 /// assert_eq!((-a).rem_euclid(-b), 1.0);
327 /// // limitation due to round-off error
328 /// assert!((-f128::EPSILON).rem_euclid(3.0) != 0.0);
329 /// # }
330 /// ```
331 #[inline]
332 #[rustc_allow_incoherent_impl]
333 #[doc(alias = "modulo", alias = "mod")]
334 #[unstable(feature = "f128", issue = "116909")]
335 #[must_use = "method returns a new number and does not mutate the original value"]
336 pub fn rem_euclid(self, rhs: f128) -> f128 {
337 let r = self % rhs;
338 if r < 0.0 { r + rhs.abs() } else { r }
339 }
340
341 /// Raises a number to an integer power.
342 ///
343 /// Using this function is generally faster than using `powf`.
344 /// It might have a different sequence of rounding operations than `powf`,
345 /// so the results are not guaranteed to agree.
346 ///
347 /// # Unspecified precision
348 ///
349 /// The precision of this function is non-deterministic. This means it varies by platform,
350 /// Rust version, and can even differ within the same execution from one invocation to the next.
351 ///
352 /// # Examples
353 ///
354 /// ```
355 /// #![feature(f128)]
356 /// # #![feature(cfg_target_has_reliable_f16_f128)]
357 /// # #![expect(internal_features)]
358 /// # #[cfg(not(miri))]
359 /// # #[cfg(target_has_reliable_f128_math)] {
360 ///
361 /// let x = 2.0_f128;
362 /// let abs_difference = (x.powi(2) - (x * x)).abs();
363 /// assert!(abs_difference <= f128::EPSILON);
364 ///
365 /// assert_eq!(f128::powi(f128::NAN, 0), 1.0);
366 /// # }
367 /// ```
368 #[inline]
369 #[rustc_allow_incoherent_impl]
370 #[unstable(feature = "f128", issue = "116909")]
371 #[must_use = "method returns a new number and does not mutate the original value"]
372 pub fn powi(self, n: i32) -> f128 {
373 unsafe { intrinsics::powif128(self, n) }
374 }
375
376 /// Raises a number to a floating point power.
377 ///
378 /// # Unspecified precision
379 ///
380 /// The precision of this function is non-deterministic. This means it varies by platform,
381 /// Rust version, and can even differ within the same execution from one invocation to the next.
382 ///
383 /// # Examples
384 ///
385 /// ```
386 /// #![feature(f128)]
387 /// # #![feature(cfg_target_has_reliable_f16_f128)]
388 /// # #![expect(internal_features)]
389 /// # #[cfg(not(miri))]
390 /// # #[cfg(target_has_reliable_f128_math)] {
391 ///
392 /// let x = 2.0_f128;
393 /// let abs_difference = (x.powf(2.0) - (x * x)).abs();
394 /// assert!(abs_difference <= f128::EPSILON);
395 ///
396 /// assert_eq!(f128::powf(1.0, f128::NAN), 1.0);
397 /// assert_eq!(f128::powf(f128::NAN, 0.0), 1.0);
398 /// # }
399 /// ```
400 #[inline]
401 #[rustc_allow_incoherent_impl]
402 #[unstable(feature = "f128", issue = "116909")]
403 #[must_use = "method returns a new number and does not mutate the original value"]
404 pub fn powf(self, n: f128) -> f128 {
405 unsafe { intrinsics::powf128(self, n) }
406 }
407
408 /// Returns the square root of a number.
409 ///
410 /// Returns NaN if `self` is a negative number other than `-0.0`.
411 ///
412 /// # Precision
413 ///
414 /// The result of this operation is guaranteed to be the rounded
415 /// infinite-precision result. It is specified by IEEE 754 as `squareRoot`
416 /// and guaranteed not to change.
417 ///
418 /// # Examples
419 ///
420 /// ```
421 /// #![feature(f128)]
422 /// # #![feature(cfg_target_has_reliable_f16_f128)]
423 /// # #![expect(internal_features)]
424 /// # #[cfg(not(miri))]
425 /// # #[cfg(target_has_reliable_f128_math)] {
426 ///
427 /// let positive = 4.0_f128;
428 /// let negative = -4.0_f128;
429 /// let negative_zero = -0.0_f128;
430 ///
431 /// assert_eq!(positive.sqrt(), 2.0);
432 /// assert!(negative.sqrt().is_nan());
433 /// assert!(negative_zero.sqrt() == negative_zero);
434 /// # }
435 /// ```
436 #[inline]
437 #[doc(alias = "squareRoot")]
438 #[rustc_allow_incoherent_impl]
439 #[unstable(feature = "f128", issue = "116909")]
440 #[must_use = "method returns a new number and does not mutate the original value"]
441 pub fn sqrt(self) -> f128 {
442 unsafe { intrinsics::sqrtf128(self) }
443 }
444
445 /// Returns `e^(self)`, (the exponential function).
446 ///
447 /// # Unspecified precision
448 ///
449 /// The precision of this function is non-deterministic. This means it varies by platform,
450 /// Rust version, and can even differ within the same execution from one invocation to the next.
451 ///
452 /// # Examples
453 ///
454 /// ```
455 /// #![feature(f128)]
456 /// # #![feature(cfg_target_has_reliable_f16_f128)]
457 /// # #![expect(internal_features)]
458 /// # #[cfg(not(miri))]
459 /// # #[cfg(target_has_reliable_f128_math)] {
460 ///
461 /// let one = 1.0f128;
462 /// // e^1
463 /// let e = one.exp();
464 ///
465 /// // ln(e) - 1 == 0
466 /// let abs_difference = (e.ln() - 1.0).abs();
467 ///
468 /// assert!(abs_difference <= f128::EPSILON);
469 /// # }
470 /// ```
471 #[inline]
472 #[rustc_allow_incoherent_impl]
473 #[unstable(feature = "f128", issue = "116909")]
474 #[must_use = "method returns a new number and does not mutate the original value"]
475 pub fn exp(self) -> f128 {
476 unsafe { intrinsics::expf128(self) }
477 }
478
479 /// Returns `2^(self)`.
480 ///
481 /// # Unspecified precision
482 ///
483 /// The precision of this function is non-deterministic. This means it varies by platform,
484 /// Rust version, and can even differ within the same execution from one invocation to the next.
485 ///
486 /// # Examples
487 ///
488 /// ```
489 /// #![feature(f128)]
490 /// # #![feature(cfg_target_has_reliable_f16_f128)]
491 /// # #![expect(internal_features)]
492 /// # #[cfg(not(miri))]
493 /// # #[cfg(target_has_reliable_f128_math)] {
494 ///
495 /// let f = 2.0f128;
496 ///
497 /// // 2^2 - 4 == 0
498 /// let abs_difference = (f.exp2() - 4.0).abs();
499 ///
500 /// assert!(abs_difference <= f128::EPSILON);
501 /// # }
502 /// ```
503 #[inline]
504 #[rustc_allow_incoherent_impl]
505 #[unstable(feature = "f128", issue = "116909")]
506 #[must_use = "method returns a new number and does not mutate the original value"]
507 pub fn exp2(self) -> f128 {
508 unsafe { intrinsics::exp2f128(self) }
509 }
510
511 /// Returns the natural logarithm of the number.
512 ///
513 /// This returns NaN when the number is negative, and negative infinity when number is zero.
514 ///
515 /// # Unspecified precision
516 ///
517 /// The precision of this function is non-deterministic. This means it varies by platform,
518 /// Rust version, and can even differ within the same execution from one invocation to the next.
519 ///
520 /// # Examples
521 ///
522 /// ```
523 /// #![feature(f128)]
524 /// # #![feature(cfg_target_has_reliable_f16_f128)]
525 /// # #![expect(internal_features)]
526 /// # #[cfg(not(miri))]
527 /// # #[cfg(target_has_reliable_f128_math)] {
528 ///
529 /// let one = 1.0f128;
530 /// // e^1
531 /// let e = one.exp();
532 ///
533 /// // ln(e) - 1 == 0
534 /// let abs_difference = (e.ln() - 1.0).abs();
535 ///
536 /// assert!(abs_difference <= f128::EPSILON);
537 /// # }
538 /// ```
539 ///
540 /// Non-positive values:
541 /// ```
542 /// #![feature(f128)]
543 /// # #![feature(cfg_target_has_reliable_f16_f128)]
544 /// # #![expect(internal_features)]
545 /// # #[cfg(not(miri))]
546 /// # #[cfg(target_has_reliable_f128_math)] {
547 ///
548 /// assert_eq!(0_f128.ln(), f128::NEG_INFINITY);
549 /// assert!((-42_f128).ln().is_nan());
550 /// # }
551 /// ```
552 #[inline]
553 #[rustc_allow_incoherent_impl]
554 #[unstable(feature = "f128", issue = "116909")]
555 #[must_use = "method returns a new number and does not mutate the original value"]
556 pub fn ln(self) -> f128 {
557 unsafe { intrinsics::logf128(self) }
558 }
559
560 /// Returns the logarithm of the number with respect to an arbitrary base.
561 ///
562 /// This returns NaN when the number is negative, and negative infinity when number is zero.
563 ///
564 /// The result might not be correctly rounded owing to implementation details;
565 /// `self.log2()` can produce more accurate results for base 2, and
566 /// `self.log10()` can produce more accurate results for base 10.
567 ///
568 /// # Unspecified precision
569 ///
570 /// The precision of this function is non-deterministic. This means it varies by platform,
571 /// Rust version, and can even differ within the same execution from one invocation to the next.
572 ///
573 /// # Examples
574 ///
575 /// ```
576 /// #![feature(f128)]
577 /// # #![feature(cfg_target_has_reliable_f16_f128)]
578 /// # #![expect(internal_features)]
579 /// # #[cfg(not(miri))]
580 /// # #[cfg(target_has_reliable_f128_math)] {
581 ///
582 /// let five = 5.0f128;
583 ///
584 /// // log5(5) - 1 == 0
585 /// let abs_difference = (five.log(5.0) - 1.0).abs();
586 ///
587 /// assert!(abs_difference <= f128::EPSILON);
588 /// # }
589 /// ```
590 ///
591 /// Non-positive values:
592 /// ```
593 /// #![feature(f128)]
594 /// # #![feature(cfg_target_has_reliable_f16_f128)]
595 /// # #![expect(internal_features)]
596 /// # #[cfg(not(miri))]
597 /// # #[cfg(target_has_reliable_f128_math)] {
598 ///
599 /// assert_eq!(0_f128.log(10.0), f128::NEG_INFINITY);
600 /// assert!((-42_f128).log(10.0).is_nan());
601 /// # }
602 /// ```
603 #[inline]
604 #[rustc_allow_incoherent_impl]
605 #[unstable(feature = "f128", issue = "116909")]
606 #[must_use = "method returns a new number and does not mutate the original value"]
607 pub fn log(self, base: f128) -> f128 {
608 self.ln() / base.ln()
609 }
610
611 /// Returns the base 2 logarithm of the number.
612 ///
613 /// This returns NaN when the number is negative, and negative infinity when number is zero.
614 ///
615 /// # Unspecified precision
616 ///
617 /// The precision of this function is non-deterministic. This means it varies by platform,
618 /// Rust version, and can even differ within the same execution from one invocation to the next.
619 ///
620 /// # Examples
621 ///
622 /// ```
623 /// #![feature(f128)]
624 /// # #![feature(cfg_target_has_reliable_f16_f128)]
625 /// # #![expect(internal_features)]
626 /// # #[cfg(not(miri))]
627 /// # #[cfg(target_has_reliable_f128_math)] {
628 ///
629 /// let two = 2.0f128;
630 ///
631 /// // log2(2) - 1 == 0
632 /// let abs_difference = (two.log2() - 1.0).abs();
633 ///
634 /// assert!(abs_difference <= f128::EPSILON);
635 /// # }
636 /// ```
637 ///
638 /// Non-positive values:
639 /// ```
640 /// #![feature(f128)]
641 /// # #![feature(cfg_target_has_reliable_f16_f128)]
642 /// # #![expect(internal_features)]
643 /// # #[cfg(not(miri))]
644 /// # #[cfg(target_has_reliable_f128_math)] {
645 ///
646 /// assert_eq!(0_f128.log2(), f128::NEG_INFINITY);
647 /// assert!((-42_f128).log2().is_nan());
648 /// # }
649 /// ```
650 #[inline]
651 #[rustc_allow_incoherent_impl]
652 #[unstable(feature = "f128", issue = "116909")]
653 #[must_use = "method returns a new number and does not mutate the original value"]
654 pub fn log2(self) -> f128 {
655 unsafe { intrinsics::log2f128(self) }
656 }
657
658 /// Returns the base 10 logarithm of the number.
659 ///
660 /// This returns NaN when the number is negative, and negative infinity when number is zero.
661 ///
662 /// # Unspecified precision
663 ///
664 /// The precision of this function is non-deterministic. This means it varies by platform,
665 /// Rust version, and can even differ within the same execution from one invocation to the next.
666 ///
667 /// # Examples
668 ///
669 /// ```
670 /// #![feature(f128)]
671 /// # #![feature(cfg_target_has_reliable_f16_f128)]
672 /// # #![expect(internal_features)]
673 /// # #[cfg(not(miri))]
674 /// # #[cfg(target_has_reliable_f128_math)] {
675 ///
676 /// let ten = 10.0f128;
677 ///
678 /// // log10(10) - 1 == 0
679 /// let abs_difference = (ten.log10() - 1.0).abs();
680 ///
681 /// assert!(abs_difference <= f128::EPSILON);
682 /// # }
683 /// ```
684 ///
685 /// Non-positive values:
686 /// ```
687 /// #![feature(f128)]
688 /// # #![feature(cfg_target_has_reliable_f16_f128)]
689 /// # #![expect(internal_features)]
690 /// # #[cfg(not(miri))]
691 /// # #[cfg(target_has_reliable_f128_math)] {
692 ///
693 /// assert_eq!(0_f128.log10(), f128::NEG_INFINITY);
694 /// assert!((-42_f128).log10().is_nan());
695 /// # }
696 /// ```
697 #[inline]
698 #[rustc_allow_incoherent_impl]
699 #[unstable(feature = "f128", issue = "116909")]
700 #[must_use = "method returns a new number and does not mutate the original value"]
701 pub fn log10(self) -> f128 {
702 unsafe { intrinsics::log10f128(self) }
703 }
704
705 /// Returns the cube root of a number.
706 ///
707 /// # Unspecified precision
708 ///
709 /// The precision of this function is non-deterministic. This means it varies by platform,
710 /// Rust version, and can even differ within the same execution from one invocation to the next.
711 ///
712 ///
713 /// This function currently corresponds to the `cbrtf128` from libc on Unix
714 /// and Windows. Note that this might change in the future.
715 ///
716 /// # Examples
717 ///
718 /// ```
719 /// #![feature(f128)]
720 /// # #![feature(cfg_target_has_reliable_f16_f128)]
721 /// # #![expect(internal_features)]
722 /// # #[cfg(not(miri))]
723 /// # #[cfg(target_has_reliable_f128_math)] {
724 ///
725 /// let x = 8.0f128;
726 ///
727 /// // x^(1/3) - 2 == 0
728 /// let abs_difference = (x.cbrt() - 2.0).abs();
729 ///
730 /// assert!(abs_difference <= f128::EPSILON);
731 /// # }
732 /// ```
733 #[inline]
734 #[rustc_allow_incoherent_impl]
735 #[unstable(feature = "f128", issue = "116909")]
736 #[must_use = "method returns a new number and does not mutate the original value"]
737 pub fn cbrt(self) -> f128 {
738 cmath::cbrtf128(self)
739 }
740
741 /// Compute the distance between the origin and a point (`x`, `y`) on the
742 /// Euclidean plane. Equivalently, compute the length of the hypotenuse of a
743 /// right-angle triangle with other sides having length `x.abs()` and
744 /// `y.abs()`.
745 ///
746 /// # Unspecified precision
747 ///
748 /// The precision of this function is non-deterministic. This means it varies by platform,
749 /// Rust version, and can even differ within the same execution from one invocation to the next.
750 ///
751 ///
752 /// This function currently corresponds to the `hypotf128` from libc on Unix
753 /// and Windows. Note that this might change in the future.
754 ///
755 /// # Examples
756 ///
757 /// ```
758 /// #![feature(f128)]
759 /// # #![feature(cfg_target_has_reliable_f16_f128)]
760 /// # #![expect(internal_features)]
761 /// # #[cfg(not(miri))]
762 /// # #[cfg(target_has_reliable_f128_math)] {
763 ///
764 /// let x = 2.0f128;
765 /// let y = 3.0f128;
766 ///
767 /// // sqrt(x^2 + y^2)
768 /// let abs_difference = (x.hypot(y) - (x.powi(2) + y.powi(2)).sqrt()).abs();
769 ///
770 /// assert!(abs_difference <= f128::EPSILON);
771 /// # }
772 /// ```
773 #[inline]
774 #[rustc_allow_incoherent_impl]
775 #[unstable(feature = "f128", issue = "116909")]
776 #[must_use = "method returns a new number and does not mutate the original value"]
777 pub fn hypot(self, other: f128) -> f128 {
778 cmath::hypotf128(self, other)
779 }
780
781 /// Computes the sine of a number (in radians).
782 ///
783 /// # Unspecified precision
784 ///
785 /// The precision of this function is non-deterministic. This means it varies by platform,
786 /// Rust version, and can even differ within the same execution from one invocation to the next.
787 ///
788 /// # Examples
789 ///
790 /// ```
791 /// #![feature(f128)]
792 /// # #![feature(cfg_target_has_reliable_f16_f128)]
793 /// # #![expect(internal_features)]
794 /// # #[cfg(not(miri))]
795 /// # #[cfg(target_has_reliable_f128_math)] {
796 ///
797 /// let x = std::f128::consts::FRAC_PI_2;
798 ///
799 /// let abs_difference = (x.sin() - 1.0).abs();
800 ///
801 /// assert!(abs_difference <= f128::EPSILON);
802 /// # }
803 /// ```
804 #[inline]
805 #[rustc_allow_incoherent_impl]
806 #[unstable(feature = "f128", issue = "116909")]
807 #[must_use = "method returns a new number and does not mutate the original value"]
808 pub fn sin(self) -> f128 {
809 unsafe { intrinsics::sinf128(self) }
810 }
811
812 /// Computes the cosine of a number (in radians).
813 ///
814 /// # Unspecified precision
815 ///
816 /// The precision of this function is non-deterministic. This means it varies by platform,
817 /// Rust version, and can even differ within the same execution from one invocation to the next.
818 ///
819 /// # Examples
820 ///
821 /// ```
822 /// #![feature(f128)]
823 /// # #![feature(cfg_target_has_reliable_f16_f128)]
824 /// # #![expect(internal_features)]
825 /// # #[cfg(not(miri))]
826 /// # #[cfg(target_has_reliable_f128_math)] {
827 ///
828 /// let x = 2.0 * std::f128::consts::PI;
829 ///
830 /// let abs_difference = (x.cos() - 1.0).abs();
831 ///
832 /// assert!(abs_difference <= f128::EPSILON);
833 /// # }
834 /// ```
835 #[inline]
836 #[rustc_allow_incoherent_impl]
837 #[unstable(feature = "f128", issue = "116909")]
838 #[must_use = "method returns a new number and does not mutate the original value"]
839 pub fn cos(self) -> f128 {
840 unsafe { intrinsics::cosf128(self) }
841 }
842
843 /// Computes the tangent of a number (in radians).
844 ///
845 /// # Unspecified precision
846 ///
847 /// The precision of this function is non-deterministic. This means it varies by platform,
848 /// Rust version, and can even differ within the same execution from one invocation to the next.
849 ///
850 /// This function currently corresponds to the `tanf128` from libc on Unix and
851 /// Windows. Note that this might change in the future.
852 ///
853 /// # Examples
854 ///
855 /// ```
856 /// #![feature(f128)]
857 /// # #![feature(cfg_target_has_reliable_f16_f128)]
858 /// # #![expect(internal_features)]
859 /// # #[cfg(not(miri))]
860 /// # #[cfg(target_has_reliable_f128_math)] {
861 ///
862 /// let x = std::f128::consts::FRAC_PI_4;
863 /// let abs_difference = (x.tan() - 1.0).abs();
864 ///
865 /// assert!(abs_difference <= f128::EPSILON);
866 /// # }
867 /// ```
868 #[inline]
869 #[rustc_allow_incoherent_impl]
870 #[unstable(feature = "f128", issue = "116909")]
871 #[must_use = "method returns a new number and does not mutate the original value"]
872 pub fn tan(self) -> f128 {
873 cmath::tanf128(self)
874 }
875
876 /// Computes the arcsine of a number. Return value is in radians in
877 /// the range [-pi/2, pi/2] or NaN if the number is outside the range
878 /// [-1, 1].
879 ///
880 /// # Unspecified precision
881 ///
882 /// The precision of this function is non-deterministic. This means it varies by platform,
883 /// Rust version, and can even differ within the same execution from one invocation to the next.
884 ///
885 /// This function currently corresponds to the `asinf128` from libc on Unix
886 /// and Windows. Note that this might change in the future.
887 ///
888 /// # Examples
889 ///
890 /// ```
891 /// #![feature(f128)]
892 /// # #![feature(cfg_target_has_reliable_f16_f128)]
893 /// # #![expect(internal_features)]
894 /// # #[cfg(not(miri))]
895 /// # #[cfg(target_has_reliable_f128_math)] {
896 ///
897 /// let f = std::f128::consts::FRAC_PI_2;
898 ///
899 /// // asin(sin(pi/2))
900 /// let abs_difference = (f.sin().asin() - std::f128::consts::FRAC_PI_2).abs();
901 ///
902 /// assert!(abs_difference <= f128::EPSILON);
903 /// # }
904 /// ```
905 #[inline]
906 #[doc(alias = "arcsin")]
907 #[rustc_allow_incoherent_impl]
908 #[unstable(feature = "f128", issue = "116909")]
909 #[must_use = "method returns a new number and does not mutate the original value"]
910 pub fn asin(self) -> f128 {
911 cmath::asinf128(self)
912 }
913
914 /// Computes the arccosine of a number. Return value is in radians in
915 /// the range [0, pi] or NaN if the number is outside the range
916 /// [-1, 1].
917 ///
918 /// # Unspecified precision
919 ///
920 /// The precision of this function is non-deterministic. This means it varies by platform,
921 /// Rust version, and can even differ within the same execution from one invocation to the next.
922 ///
923 /// This function currently corresponds to the `acosf128` from libc on Unix
924 /// and Windows. Note that this might change in the future.
925 ///
926 /// # Examples
927 ///
928 /// ```
929 /// #![feature(f128)]
930 /// # #![feature(cfg_target_has_reliable_f16_f128)]
931 /// # #![expect(internal_features)]
932 /// # #[cfg(not(miri))]
933 /// # #[cfg(target_has_reliable_f128_math)] {
934 ///
935 /// let f = std::f128::consts::FRAC_PI_4;
936 ///
937 /// // acos(cos(pi/4))
938 /// let abs_difference = (f.cos().acos() - std::f128::consts::FRAC_PI_4).abs();
939 ///
940 /// assert!(abs_difference <= f128::EPSILON);
941 /// # }
942 /// ```
943 #[inline]
944 #[doc(alias = "arccos")]
945 #[rustc_allow_incoherent_impl]
946 #[unstable(feature = "f128", issue = "116909")]
947 #[must_use = "method returns a new number and does not mutate the original value"]
948 pub fn acos(self) -> f128 {
949 cmath::acosf128(self)
950 }
951
952 /// Computes the arctangent of a number. Return value is in radians in the
953 /// range [-pi/2, pi/2];
954 ///
955 /// # Unspecified precision
956 ///
957 /// The precision of this function is non-deterministic. This means it varies by platform,
958 /// Rust version, and can even differ within the same execution from one invocation to the next.
959 ///
960 /// This function currently corresponds to the `atanf128` from libc on Unix
961 /// and Windows. Note that this might change in the future.
962 ///
963 /// # Examples
964 ///
965 /// ```
966 /// #![feature(f128)]
967 /// # #![feature(cfg_target_has_reliable_f16_f128)]
968 /// # #![expect(internal_features)]
969 /// # #[cfg(not(miri))]
970 /// # #[cfg(target_has_reliable_f128_math)] {
971 ///
972 /// let f = 1.0f128;
973 ///
974 /// // atan(tan(1))
975 /// let abs_difference = (f.tan().atan() - 1.0).abs();
976 ///
977 /// assert!(abs_difference <= f128::EPSILON);
978 /// # }
979 /// ```
980 #[inline]
981 #[doc(alias = "arctan")]
982 #[rustc_allow_incoherent_impl]
983 #[unstable(feature = "f128", issue = "116909")]
984 #[must_use = "method returns a new number and does not mutate the original value"]
985 pub fn atan(self) -> f128 {
986 cmath::atanf128(self)
987 }
988
989 /// Computes the four quadrant arctangent of `self` (`y`) and `other` (`x`) in radians.
990 ///
991 /// * `x = 0`, `y = 0`: `0`
992 /// * `x >= 0`: `arctan(y/x)` -> `[-pi/2, pi/2]`
993 /// * `y >= 0`: `arctan(y/x) + pi` -> `(pi/2, pi]`
994 /// * `y < 0`: `arctan(y/x) - pi` -> `(-pi, -pi/2)`
995 ///
996 /// # Unspecified precision
997 ///
998 /// The precision of this function is non-deterministic. This means it varies by platform,
999 /// Rust version, and can even differ within the same execution from one invocation to the next.
1000 ///
1001 /// This function currently corresponds to the `atan2f128` from libc on Unix
1002 /// and Windows. Note that this might change in the future.
1003 ///
1004 /// # Examples
1005 ///
1006 /// ```
1007 /// #![feature(f128)]
1008 /// # #![feature(cfg_target_has_reliable_f16_f128)]
1009 /// # #![expect(internal_features)]
1010 /// # #[cfg(not(miri))]
1011 /// # #[cfg(target_has_reliable_f128_math)] {
1012 ///
1013 /// // Positive angles measured counter-clockwise
1014 /// // from positive x axis
1015 /// // -pi/4 radians (45 deg clockwise)
1016 /// let x1 = 3.0f128;
1017 /// let y1 = -3.0f128;
1018 ///
1019 /// // 3pi/4 radians (135 deg counter-clockwise)
1020 /// let x2 = -3.0f128;
1021 /// let y2 = 3.0f128;
1022 ///
1023 /// let abs_difference_1 = (y1.atan2(x1) - (-std::f128::consts::FRAC_PI_4)).abs();
1024 /// let abs_difference_2 = (y2.atan2(x2) - (3.0 * std::f128::consts::FRAC_PI_4)).abs();
1025 ///
1026 /// assert!(abs_difference_1 <= f128::EPSILON);
1027 /// assert!(abs_difference_2 <= f128::EPSILON);
1028 /// # }
1029 /// ```
1030 #[inline]
1031 #[rustc_allow_incoherent_impl]
1032 #[unstable(feature = "f128", issue = "116909")]
1033 #[must_use = "method returns a new number and does not mutate the original value"]
1034 pub fn atan2(self, other: f128) -> f128 {
1035 cmath::atan2f128(self, other)
1036 }
1037
1038 /// Simultaneously computes the sine and cosine of the number, `x`. Returns
1039 /// `(sin(x), cos(x))`.
1040 ///
1041 /// # Unspecified precision
1042 ///
1043 /// The precision of this function is non-deterministic. This means it varies by platform,
1044 /// Rust version, and can even differ within the same execution from one invocation to the next.
1045 ///
1046 /// This function currently corresponds to the `(f128::sin(x),
1047 /// f128::cos(x))`. Note that this might change in the future.
1048 ///
1049 /// # Examples
1050 ///
1051 /// ```
1052 /// #![feature(f128)]
1053 /// # #![feature(cfg_target_has_reliable_f16_f128)]
1054 /// # #![expect(internal_features)]
1055 /// # #[cfg(not(miri))]
1056 /// # #[cfg(target_has_reliable_f128_math)] {
1057 ///
1058 /// let x = std::f128::consts::FRAC_PI_4;
1059 /// let f = x.sin_cos();
1060 ///
1061 /// let abs_difference_0 = (f.0 - x.sin()).abs();
1062 /// let abs_difference_1 = (f.1 - x.cos()).abs();
1063 ///
1064 /// assert!(abs_difference_0 <= f128::EPSILON);
1065 /// assert!(abs_difference_1 <= f128::EPSILON);
1066 /// # }
1067 /// ```
1068 #[inline]
1069 #[doc(alias = "sincos")]
1070 #[rustc_allow_incoherent_impl]
1071 #[unstable(feature = "f128", issue = "116909")]
1072 pub fn sin_cos(self) -> (f128, f128) {
1073 (self.sin(), self.cos())
1074 }
1075
1076 /// Returns `e^(self) - 1` in a way that is accurate even if the
1077 /// number is close to zero.
1078 ///
1079 /// # Unspecified precision
1080 ///
1081 /// The precision of this function is non-deterministic. This means it varies by platform,
1082 /// Rust version, and can even differ within the same execution from one invocation to the next.
1083 ///
1084 /// This function currently corresponds to the `expm1f128` from libc on Unix
1085 /// and Windows. Note that this might change in the future.
1086 ///
1087 /// # Examples
1088 ///
1089 /// ```
1090 /// #![feature(f128)]
1091 /// # #![feature(cfg_target_has_reliable_f16_f128)]
1092 /// # #![expect(internal_features)]
1093 /// # #[cfg(not(miri))]
1094 /// # #[cfg(target_has_reliable_f128_math)] {
1095 ///
1096 /// let x = 1e-8_f128;
1097 ///
1098 /// // for very small x, e^x is approximately 1 + x + x^2 / 2
1099 /// let approx = x + x * x / 2.0;
1100 /// let abs_difference = (x.exp_m1() - approx).abs();
1101 ///
1102 /// assert!(abs_difference < 1e-10);
1103 /// # }
1104 /// ```
1105 #[inline]
1106 #[rustc_allow_incoherent_impl]
1107 #[unstable(feature = "f128", issue = "116909")]
1108 #[must_use = "method returns a new number and does not mutate the original value"]
1109 pub fn exp_m1(self) -> f128 {
1110 cmath::expm1f128(self)
1111 }
1112
1113 /// Returns `ln(1+n)` (natural logarithm) more accurately than if
1114 /// the operations were performed separately.
1115 ///
1116 /// This returns NaN when `n < -1.0`, and negative infinity when `n == -1.0`.
1117 ///
1118 /// # Unspecified precision
1119 ///
1120 /// The precision of this function is non-deterministic. This means it varies by platform,
1121 /// Rust version, and can even differ within the same execution from one invocation to the next.
1122 ///
1123 /// This function currently corresponds to the `log1pf128` from libc on Unix
1124 /// and Windows. Note that this might change in the future.
1125 ///
1126 /// # Examples
1127 ///
1128 /// ```
1129 /// #![feature(f128)]
1130 /// # #![feature(cfg_target_has_reliable_f16_f128)]
1131 /// # #![expect(internal_features)]
1132 /// # #[cfg(not(miri))]
1133 /// # #[cfg(target_has_reliable_f128_math)] {
1134 ///
1135 /// let x = 1e-8_f128;
1136 ///
1137 /// // for very small x, ln(1 + x) is approximately x - x^2 / 2
1138 /// let approx = x - x * x / 2.0;
1139 /// let abs_difference = (x.ln_1p() - approx).abs();
1140 ///
1141 /// assert!(abs_difference < 1e-10);
1142 /// # }
1143 /// ```
1144 ///
1145 /// Out-of-range values:
1146 /// ```
1147 /// #![feature(f128)]
1148 /// # #![feature(cfg_target_has_reliable_f16_f128)]
1149 /// # #![expect(internal_features)]
1150 /// # #[cfg(not(miri))]
1151 /// # #[cfg(target_has_reliable_f128_math)] {
1152 ///
1153 /// assert_eq!((-1.0_f128).ln_1p(), f128::NEG_INFINITY);
1154 /// assert!((-2.0_f128).ln_1p().is_nan());
1155 /// # }
1156 /// ```
1157 #[inline]
1158 #[doc(alias = "log1p")]
1159 #[must_use = "method returns a new number and does not mutate the original value"]
1160 #[rustc_allow_incoherent_impl]
1161 #[unstable(feature = "f128", issue = "116909")]
1162 pub fn ln_1p(self) -> f128 {
1163 cmath::log1pf128(self)
1164 }
1165
1166 /// Hyperbolic sine function.
1167 ///
1168 /// # Unspecified precision
1169 ///
1170 /// The precision of this function is non-deterministic. This means it varies by platform,
1171 /// Rust version, and can even differ within the same execution from one invocation to the next.
1172 ///
1173 /// This function currently corresponds to the `sinhf128` from libc on Unix
1174 /// and Windows. Note that this might change in the future.
1175 ///
1176 /// # Examples
1177 ///
1178 /// ```
1179 /// #![feature(f128)]
1180 /// # #![feature(cfg_target_has_reliable_f16_f128)]
1181 /// # #![expect(internal_features)]
1182 /// # #[cfg(not(miri))]
1183 /// # #[cfg(target_has_reliable_f128_math)] {
1184 ///
1185 /// let e = std::f128::consts::E;
1186 /// let x = 1.0f128;
1187 ///
1188 /// let f = x.sinh();
1189 /// // Solving sinh() at 1 gives `(e^2-1)/(2e)`
1190 /// let g = ((e * e) - 1.0) / (2.0 * e);
1191 /// let abs_difference = (f - g).abs();
1192 ///
1193 /// assert!(abs_difference <= f128::EPSILON);
1194 /// # }
1195 /// ```
1196 #[inline]
1197 #[rustc_allow_incoherent_impl]
1198 #[unstable(feature = "f128", issue = "116909")]
1199 #[must_use = "method returns a new number and does not mutate the original value"]
1200 pub fn sinh(self) -> f128 {
1201 cmath::sinhf128(self)
1202 }
1203
1204 /// Hyperbolic cosine function.
1205 ///
1206 /// # Unspecified precision
1207 ///
1208 /// The precision of this function is non-deterministic. This means it varies by platform,
1209 /// Rust version, and can even differ within the same execution from one invocation to the next.
1210 ///
1211 /// This function currently corresponds to the `coshf128` from libc on Unix
1212 /// and Windows. Note that this might change in the future.
1213 ///
1214 /// # Examples
1215 ///
1216 /// ```
1217 /// #![feature(f128)]
1218 /// # #![feature(cfg_target_has_reliable_f16_f128)]
1219 /// # #![expect(internal_features)]
1220 /// # #[cfg(not(miri))]
1221 /// # #[cfg(target_has_reliable_f128_math)] {
1222 ///
1223 /// let e = std::f128::consts::E;
1224 /// let x = 1.0f128;
1225 /// let f = x.cosh();
1226 /// // Solving cosh() at 1 gives this result
1227 /// let g = ((e * e) + 1.0) / (2.0 * e);
1228 /// let abs_difference = (f - g).abs();
1229 ///
1230 /// // Same result
1231 /// assert!(abs_difference <= f128::EPSILON);
1232 /// # }
1233 /// ```
1234 #[inline]
1235 #[rustc_allow_incoherent_impl]
1236 #[unstable(feature = "f128", issue = "116909")]
1237 #[must_use = "method returns a new number and does not mutate the original value"]
1238 pub fn cosh(self) -> f128 {
1239 cmath::coshf128(self)
1240 }
1241
1242 /// Hyperbolic tangent function.
1243 ///
1244 /// # Unspecified precision
1245 ///
1246 /// The precision of this function is non-deterministic. This means it varies by platform,
1247 /// Rust version, and can even differ within the same execution from one invocation to the next.
1248 ///
1249 /// This function currently corresponds to the `tanhf128` from libc on Unix
1250 /// and Windows. Note that this might change in the future.
1251 ///
1252 /// # Examples
1253 ///
1254 /// ```
1255 /// #![feature(f128)]
1256 /// # #![feature(cfg_target_has_reliable_f16_f128)]
1257 /// # #![expect(internal_features)]
1258 /// # #[cfg(not(miri))]
1259 /// # #[cfg(target_has_reliable_f128_math)] {
1260 ///
1261 /// let e = std::f128::consts::E;
1262 /// let x = 1.0f128;
1263 ///
1264 /// let f = x.tanh();
1265 /// // Solving tanh() at 1 gives `(1 - e^(-2))/(1 + e^(-2))`
1266 /// let g = (1.0 - e.powi(-2)) / (1.0 + e.powi(-2));
1267 /// let abs_difference = (f - g).abs();
1268 ///
1269 /// assert!(abs_difference <= f128::EPSILON);
1270 /// # }
1271 /// ```
1272 #[inline]
1273 #[rustc_allow_incoherent_impl]
1274 #[unstable(feature = "f128", issue = "116909")]
1275 #[must_use = "method returns a new number and does not mutate the original value"]
1276 pub fn tanh(self) -> f128 {
1277 cmath::tanhf128(self)
1278 }
1279
1280 /// Inverse hyperbolic sine function.
1281 ///
1282 /// # Unspecified precision
1283 ///
1284 /// The precision of this function is non-deterministic. This means it varies by platform,
1285 /// Rust version, and can even differ within the same execution from one invocation to the next.
1286 ///
1287 /// # Examples
1288 ///
1289 /// ```
1290 /// #![feature(f128)]
1291 /// # #![feature(cfg_target_has_reliable_f16_f128)]
1292 /// # #![expect(internal_features)]
1293 /// # #[cfg(not(miri))]
1294 /// # #[cfg(target_has_reliable_f128_math)] {
1295 ///
1296 /// let x = 1.0f128;
1297 /// let f = x.sinh().asinh();
1298 ///
1299 /// let abs_difference = (f - x).abs();
1300 ///
1301 /// assert!(abs_difference <= f128::EPSILON);
1302 /// # }
1303 /// ```
1304 #[inline]
1305 #[doc(alias = "arcsinh")]
1306 #[rustc_allow_incoherent_impl]
1307 #[unstable(feature = "f128", issue = "116909")]
1308 #[must_use = "method returns a new number and does not mutate the original value"]
1309 pub fn asinh(self) -> f128 {
1310 let ax = self.abs();
1311 let ix = 1.0 / ax;
1312 (ax + (ax / (Self::hypot(1.0, ix) + ix))).ln_1p().copysign(self)
1313 }
1314
1315 /// Inverse hyperbolic cosine function.
1316 ///
1317 /// # Unspecified precision
1318 ///
1319 /// The precision of this function is non-deterministic. This means it varies by platform,
1320 /// Rust version, and can even differ within the same execution from one invocation to the next.
1321 ///
1322 /// # Examples
1323 ///
1324 /// ```
1325 /// #![feature(f128)]
1326 /// # #![feature(cfg_target_has_reliable_f16_f128)]
1327 /// # #![expect(internal_features)]
1328 /// # #[cfg(not(miri))]
1329 /// # #[cfg(target_has_reliable_f128_math)] {
1330 ///
1331 /// let x = 1.0f128;
1332 /// let f = x.cosh().acosh();
1333 ///
1334 /// let abs_difference = (f - x).abs();
1335 ///
1336 /// assert!(abs_difference <= f128::EPSILON);
1337 /// # }
1338 /// ```
1339 #[inline]
1340 #[doc(alias = "arccosh")]
1341 #[rustc_allow_incoherent_impl]
1342 #[unstable(feature = "f128", issue = "116909")]
1343 #[must_use = "method returns a new number and does not mutate the original value"]
1344 pub fn acosh(self) -> f128 {
1345 if self < 1.0 {
1346 Self::NAN
1347 } else {
1348 (self + ((self - 1.0).sqrt() * (self + 1.0).sqrt())).ln()
1349 }
1350 }
1351
1352 /// Inverse hyperbolic tangent function.
1353 ///
1354 /// # Unspecified precision
1355 ///
1356 /// The precision of this function is non-deterministic. This means it varies by platform,
1357 /// Rust version, and can even differ within the same execution from one invocation to the next.
1358 ///
1359 /// # Examples
1360 ///
1361 /// ```
1362 /// #![feature(f128)]
1363 /// # #![feature(cfg_target_has_reliable_f16_f128)]
1364 /// # #![expect(internal_features)]
1365 /// # #[cfg(not(miri))]
1366 /// # #[cfg(target_has_reliable_f128_math)] {
1367 ///
1368 /// let e = std::f128::consts::E;
1369 /// let f = e.tanh().atanh();
1370 ///
1371 /// let abs_difference = (f - e).abs();
1372 ///
1373 /// assert!(abs_difference <= 1e-5);
1374 /// # }
1375 /// ```
1376 #[inline]
1377 #[doc(alias = "arctanh")]
1378 #[rustc_allow_incoherent_impl]
1379 #[unstable(feature = "f128", issue = "116909")]
1380 #[must_use = "method returns a new number and does not mutate the original value"]
1381 pub fn atanh(self) -> f128 {
1382 0.5 * ((2.0 * self) / (1.0 - self)).ln_1p()
1383 }
1384
1385 /// Gamma function.
1386 ///
1387 /// # Unspecified precision
1388 ///
1389 /// The precision of this function is non-deterministic. This means it varies by platform,
1390 /// Rust version, and can even differ within the same execution from one invocation to the next.
1391 ///
1392 /// This function currently corresponds to the `tgammaf128` from libc on Unix
1393 /// and Windows. Note that this might change in the future.
1394 ///
1395 /// # Examples
1396 ///
1397 /// ```
1398 /// #![feature(f128)]
1399 /// #![feature(float_gamma)]
1400 /// # #![feature(cfg_target_has_reliable_f16_f128)]
1401 /// # #![expect(internal_features)]
1402 /// # #[cfg(not(miri))]
1403 /// # #[cfg(target_has_reliable_f128_math)] {
1404 ///
1405 /// let x = 5.0f128;
1406 ///
1407 /// let abs_difference = (x.gamma() - 24.0).abs();
1408 ///
1409 /// assert!(abs_difference <= f128::EPSILON);
1410 /// # }
1411 /// ```
1412 #[inline]
1413 #[rustc_allow_incoherent_impl]
1414 #[unstable(feature = "f128", issue = "116909")]
1415 // #[unstable(feature = "float_gamma", issue = "99842")]
1416 #[must_use = "method returns a new number and does not mutate the original value"]
1417 pub fn gamma(self) -> f128 {
1418 cmath::tgammaf128(self)
1419 }
1420
1421 /// Natural logarithm of the absolute value of the gamma function
1422 ///
1423 /// The integer part of the tuple indicates the sign of the gamma function.
1424 ///
1425 /// # Unspecified precision
1426 ///
1427 /// The precision of this function is non-deterministic. This means it varies by platform,
1428 /// Rust version, and can even differ within the same execution from one invocation to the next.
1429 ///
1430 /// This function currently corresponds to the `lgammaf128_r` from libc on Unix
1431 /// and Windows. Note that this might change in the future.
1432 ///
1433 /// # Examples
1434 ///
1435 /// ```
1436 /// #![feature(f128)]
1437 /// #![feature(float_gamma)]
1438 /// # #![feature(cfg_target_has_reliable_f16_f128)]
1439 /// # #![expect(internal_features)]
1440 /// # #[cfg(not(miri))]
1441 /// # #[cfg(target_has_reliable_f128_math)] {
1442 ///
1443 /// let x = 2.0f128;
1444 ///
1445 /// let abs_difference = (x.ln_gamma().0 - 0.0).abs();
1446 ///
1447 /// assert!(abs_difference <= f128::EPSILON);
1448 /// # }
1449 /// ```
1450 #[inline]
1451 #[rustc_allow_incoherent_impl]
1452 #[unstable(feature = "f128", issue = "116909")]
1453 // #[unstable(feature = "float_gamma", issue = "99842")]
1454 #[must_use = "method returns a new number and does not mutate the original value"]
1455 pub fn ln_gamma(self) -> (f128, i32) {
1456 let mut signgamp: i32 = 0;
1457 let x = cmath::lgammaf128_r(self, &mut signgamp);
1458 (x, signgamp)
1459 }
1460
1461 /// Error function.
1462 ///
1463 /// # Unspecified precision
1464 ///
1465 /// The precision of this function is non-deterministic. This means it varies by platform,
1466 /// Rust version, and can even differ within the same execution from one invocation to the next.
1467 ///
1468 /// This function currently corresponds to the `erff128` from libc on Unix
1469 /// and Windows. Note that this might change in the future.
1470 ///
1471 /// # Examples
1472 ///
1473 /// ```
1474 /// #![feature(f128)]
1475 /// #![feature(float_erf)]
1476 /// # #![feature(cfg_target_has_reliable_f16_f128)]
1477 /// # #![expect(internal_features)]
1478 /// # #[cfg(not(miri))]
1479 /// # #[cfg(target_has_reliable_f128_math)] {
1480 /// /// The error function relates what percent of a normal distribution lies
1481 /// /// within `x` standard deviations (scaled by `1/sqrt(2)`).
1482 /// fn within_standard_deviations(x: f128) -> f128 {
1483 /// (x * std::f128::consts::FRAC_1_SQRT_2).erf() * 100.0
1484 /// }
1485 ///
1486 /// // 68% of a normal distribution is within one standard deviation
1487 /// assert!((within_standard_deviations(1.0) - 68.269).abs() < 0.01);
1488 /// // 95% of a normal distribution is within two standard deviations
1489 /// assert!((within_standard_deviations(2.0) - 95.450).abs() < 0.01);
1490 /// // 99.7% of a normal distribution is within three standard deviations
1491 /// assert!((within_standard_deviations(3.0) - 99.730).abs() < 0.01);
1492 /// # }
1493 /// ```
1494 #[rustc_allow_incoherent_impl]
1495 #[must_use = "method returns a new number and does not mutate the original value"]
1496 #[unstable(feature = "f128", issue = "116909")]
1497 // #[unstable(feature = "float_erf", issue = "136321")]
1498 #[inline]
1499 pub fn erf(self) -> f128 {
1500 cmath::erff128(self)
1501 }
1502
1503 /// Complementary error function.
1504 ///
1505 /// # Unspecified precision
1506 ///
1507 /// The precision of this function is non-deterministic. This means it varies by platform,
1508 /// Rust version, and can even differ within the same execution from one invocation to the next.
1509 ///
1510 /// This function currently corresponds to the `erfcf128` from libc on Unix
1511 /// and Windows. Note that this might change in the future.
1512 ///
1513 /// # Examples
1514 ///
1515 /// ```
1516 /// #![feature(f128)]
1517 /// #![feature(float_erf)]
1518 /// # #![feature(cfg_target_has_reliable_f16_f128)]
1519 /// # #![expect(internal_features)]
1520 /// # #[cfg(not(miri))]
1521 /// # #[cfg(target_has_reliable_f128_math)] {
1522 /// let x: f128 = 0.123;
1523 ///
1524 /// let one = x.erf() + x.erfc();
1525 /// let abs_difference = (one - 1.0).abs();
1526 ///
1527 /// assert!(abs_difference <= f128::EPSILON);
1528 /// # }
1529 /// ```
1530 #[rustc_allow_incoherent_impl]
1531 #[must_use = "method returns a new number and does not mutate the original value"]
1532 #[unstable(feature = "f128", issue = "116909")]
1533 // #[unstable(feature = "float_erf", issue = "136321")]
1534 #[inline]
1535 pub fn erfc(self) -> f128 {
1536 cmath::erfcf128(self)
1537 }
1538}