std/num/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")]
8#![doc(test(attr(feature(cfg_target_has_reliable_f16_f128), expect(internal_features))))]
9
10#[unstable(feature = "f128", issue = "116909")]
11pub use core::f128::consts;
12
13#[cfg(not(test))]
14use crate::intrinsics;
15#[cfg(not(test))]
16use crate::sys::cmath;
17
18#[cfg(not(test))]
19impl f128 {
20 /// Raises a number to a floating point power.
21 ///
22 /// Note that this function is special in that it can return non-NaN results for NaN inputs. For
23 /// example, `f128::powf(f128::NAN, 0.0)` returns `1.0`. However, if an input is a *signaling*
24 /// NaN, then the result is non-deterministically either a NaN or the result that the
25 /// corresponding quiet NaN would produce.
26 ///
27 /// # Unspecified precision
28 ///
29 /// The precision of this function is non-deterministic. This means it varies by platform,
30 /// Rust version, and can even differ within the same execution from one invocation to the next.
31 ///
32 /// # Examples
33 ///
34 /// ```
35 /// #![feature(f128)]
36 /// # #[cfg(not(miri))]
37 /// # #[cfg(target_has_reliable_f128_math)] {
38 ///
39 /// let x = 2.0_f128;
40 /// let abs_difference = (x.powf(2.0) - (x * x)).abs();
41 /// assert!(abs_difference <= f128::EPSILON);
42 ///
43 /// assert_eq!(f128::powf(1.0, f128::NAN), 1.0);
44 /// assert_eq!(f128::powf(f128::NAN, 0.0), 1.0);
45 /// assert_eq!(f128::powf(0.0, 0.0), 1.0);
46 /// # }
47 /// ```
48 #[inline]
49 #[rustc_allow_incoherent_impl]
50 #[unstable(feature = "f128", issue = "116909")]
51 #[must_use = "method returns a new number and does not mutate the original value"]
52 pub fn powf(self, n: f128) -> f128 {
53 intrinsics::powf128(self, n)
54 }
55
56 /// Returns `e^(self)`, (the exponential function).
57 ///
58 /// # Unspecified precision
59 ///
60 /// The precision of this function is non-deterministic. This means it varies by platform,
61 /// Rust version, and can even differ within the same execution from one invocation to the next.
62 ///
63 /// # Examples
64 ///
65 /// ```
66 /// #![feature(f128)]
67 /// # #[cfg(not(miri))]
68 /// # #[cfg(target_has_reliable_f128_math)] {
69 ///
70 /// let one = 1.0f128;
71 /// // e^1
72 /// let e = one.exp();
73 ///
74 /// // ln(e) - 1 == 0
75 /// let abs_difference = (e.ln() - 1.0).abs();
76 ///
77 /// assert!(abs_difference <= f128::EPSILON);
78 /// # }
79 /// ```
80 #[inline]
81 #[rustc_allow_incoherent_impl]
82 #[unstable(feature = "f128", issue = "116909")]
83 #[must_use = "method returns a new number and does not mutate the original value"]
84 pub fn exp(self) -> f128 {
85 intrinsics::expf128(self)
86 }
87
88 /// Returns `2^(self)`.
89 ///
90 /// # Unspecified precision
91 ///
92 /// The precision of this function is non-deterministic. This means it varies by platform,
93 /// Rust version, and can even differ within the same execution from one invocation to the next.
94 ///
95 /// # Examples
96 ///
97 /// ```
98 /// #![feature(f128)]
99 /// # #[cfg(not(miri))]
100 /// # #[cfg(target_has_reliable_f128_math)] {
101 ///
102 /// let f = 2.0f128;
103 ///
104 /// // 2^2 - 4 == 0
105 /// let abs_difference = (f.exp2() - 4.0).abs();
106 ///
107 /// assert!(abs_difference <= f128::EPSILON);
108 /// # }
109 /// ```
110 #[inline]
111 #[rustc_allow_incoherent_impl]
112 #[unstable(feature = "f128", issue = "116909")]
113 #[must_use = "method returns a new number and does not mutate the original value"]
114 pub fn exp2(self) -> f128 {
115 intrinsics::exp2f128(self)
116 }
117
118 /// Returns the natural logarithm of the number.
119 ///
120 /// This returns NaN when the number is negative, and negative infinity when number is zero.
121 ///
122 /// # Unspecified precision
123 ///
124 /// The precision of this function is non-deterministic. This means it varies by platform,
125 /// Rust version, and can even differ within the same execution from one invocation to the next.
126 ///
127 /// # Examples
128 ///
129 /// ```
130 /// #![feature(f128)]
131 /// # #[cfg(not(miri))]
132 /// # #[cfg(target_has_reliable_f128_math)] {
133 ///
134 /// let one = 1.0f128;
135 /// // e^1
136 /// let e = one.exp();
137 ///
138 /// // ln(e) - 1 == 0
139 /// let abs_difference = (e.ln() - 1.0).abs();
140 ///
141 /// assert!(abs_difference <= f128::EPSILON);
142 /// # }
143 /// ```
144 ///
145 /// Non-positive values:
146 /// ```
147 /// #![feature(f128)]
148 /// # #[cfg(not(miri))]
149 /// # #[cfg(target_has_reliable_f128_math)] {
150 ///
151 /// assert_eq!(0_f128.ln(), f128::NEG_INFINITY);
152 /// assert!((-42_f128).ln().is_nan());
153 /// # }
154 /// ```
155 #[inline]
156 #[rustc_allow_incoherent_impl]
157 #[unstable(feature = "f128", issue = "116909")]
158 #[must_use = "method returns a new number and does not mutate the original value"]
159 pub fn ln(self) -> f128 {
160 intrinsics::logf128(self)
161 }
162
163 /// Returns the logarithm of the number with respect to an arbitrary base.
164 ///
165 /// This returns NaN when the number is negative, and negative infinity when number is zero.
166 ///
167 /// The result might not be correctly rounded owing to implementation details;
168 /// `self.log2()` can produce more accurate results for base 2, and
169 /// `self.log10()` can produce more accurate results for base 10.
170 ///
171 /// # Unspecified precision
172 ///
173 /// The precision of this function is non-deterministic. This means it varies by platform,
174 /// Rust version, and can even differ within the same execution from one invocation to the next.
175 ///
176 /// # Examples
177 ///
178 /// ```
179 /// #![feature(f128)]
180 /// # #[cfg(not(miri))]
181 /// # #[cfg(target_has_reliable_f128_math)] {
182 ///
183 /// let five = 5.0f128;
184 ///
185 /// // log5(5) - 1 == 0
186 /// let abs_difference = (five.log(5.0) - 1.0).abs();
187 ///
188 /// assert!(abs_difference <= f128::EPSILON);
189 /// # }
190 /// ```
191 ///
192 /// Non-positive values:
193 /// ```
194 /// #![feature(f128)]
195 /// # #[cfg(not(miri))]
196 /// # #[cfg(target_has_reliable_f128_math)] {
197 ///
198 /// assert_eq!(0_f128.log(10.0), f128::NEG_INFINITY);
199 /// assert!((-42_f128).log(10.0).is_nan());
200 /// # }
201 /// ```
202 #[inline]
203 #[rustc_allow_incoherent_impl]
204 #[unstable(feature = "f128", issue = "116909")]
205 #[must_use = "method returns a new number and does not mutate the original value"]
206 pub fn log(self, base: f128) -> f128 {
207 self.ln() / base.ln()
208 }
209
210 /// Returns the base 2 logarithm of the number.
211 ///
212 /// This returns NaN when the number is negative, and negative infinity when number is zero.
213 ///
214 /// # Unspecified precision
215 ///
216 /// The precision of this function is non-deterministic. This means it varies by platform,
217 /// Rust version, and can even differ within the same execution from one invocation to the next.
218 ///
219 /// # Examples
220 ///
221 /// ```
222 /// #![feature(f128)]
223 /// # #[cfg(not(miri))]
224 /// # #[cfg(target_has_reliable_f128_math)] {
225 ///
226 /// let two = 2.0f128;
227 ///
228 /// // log2(2) - 1 == 0
229 /// let abs_difference = (two.log2() - 1.0).abs();
230 ///
231 /// assert!(abs_difference <= f128::EPSILON);
232 /// # }
233 /// ```
234 ///
235 /// Non-positive values:
236 /// ```
237 /// #![feature(f128)]
238 /// # #[cfg(not(miri))]
239 /// # #[cfg(target_has_reliable_f128_math)] {
240 ///
241 /// assert_eq!(0_f128.log2(), f128::NEG_INFINITY);
242 /// assert!((-42_f128).log2().is_nan());
243 /// # }
244 /// ```
245 #[inline]
246 #[rustc_allow_incoherent_impl]
247 #[unstable(feature = "f128", issue = "116909")]
248 #[must_use = "method returns a new number and does not mutate the original value"]
249 pub fn log2(self) -> f128 {
250 intrinsics::log2f128(self)
251 }
252
253 /// Returns the base 10 logarithm of the number.
254 ///
255 /// This returns NaN when the number is negative, and negative infinity when number is zero.
256 ///
257 /// # Unspecified precision
258 ///
259 /// The precision of this function is non-deterministic. This means it varies by platform,
260 /// Rust version, and can even differ within the same execution from one invocation to the next.
261 ///
262 /// # Examples
263 ///
264 /// ```
265 /// #![feature(f128)]
266 /// # #[cfg(not(miri))]
267 /// # #[cfg(target_has_reliable_f128_math)] {
268 ///
269 /// let ten = 10.0f128;
270 ///
271 /// // log10(10) - 1 == 0
272 /// let abs_difference = (ten.log10() - 1.0).abs();
273 ///
274 /// assert!(abs_difference <= f128::EPSILON);
275 /// # }
276 /// ```
277 ///
278 /// Non-positive values:
279 /// ```
280 /// #![feature(f128)]
281 /// # #[cfg(not(miri))]
282 /// # #[cfg(target_has_reliable_f128_math)] {
283 ///
284 /// assert_eq!(0_f128.log10(), f128::NEG_INFINITY);
285 /// assert!((-42_f128).log10().is_nan());
286 /// # }
287 /// ```
288 #[inline]
289 #[rustc_allow_incoherent_impl]
290 #[unstable(feature = "f128", issue = "116909")]
291 #[must_use = "method returns a new number and does not mutate the original value"]
292 pub fn log10(self) -> f128 {
293 intrinsics::log10f128(self)
294 }
295
296 /// Returns the cube root of a number.
297 ///
298 /// # Unspecified precision
299 ///
300 /// The precision of this function is non-deterministic. This means it varies by platform,
301 /// Rust version, and can even differ within the same execution from one invocation to the next.
302 ///
303 ///
304 /// This function currently corresponds to the `cbrtf128` from libc on Unix
305 /// and Windows. Note that this might change in the future.
306 ///
307 /// # Examples
308 ///
309 /// ```
310 /// #![feature(f128)]
311 /// # #[cfg(not(miri))]
312 /// # #[cfg(target_has_reliable_f128_math)] {
313 ///
314 /// let x = 8.0f128;
315 ///
316 /// // x^(1/3) - 2 == 0
317 /// let abs_difference = (x.cbrt() - 2.0).abs();
318 ///
319 /// assert!(abs_difference <= f128::EPSILON);
320 /// # }
321 /// ```
322 #[inline]
323 #[rustc_allow_incoherent_impl]
324 #[unstable(feature = "f128", issue = "116909")]
325 #[must_use = "method returns a new number and does not mutate the original value"]
326 pub fn cbrt(self) -> f128 {
327 cmath::cbrtf128(self)
328 }
329
330 /// Compute the distance between the origin and a point (`x`, `y`) on the
331 /// Euclidean plane. Equivalently, compute the length of the hypotenuse of a
332 /// right-angle triangle with other sides having length `x.abs()` and
333 /// `y.abs()`.
334 ///
335 /// # Unspecified precision
336 ///
337 /// The precision of this function is non-deterministic. This means it varies by platform,
338 /// Rust version, and can even differ within the same execution from one invocation to the next.
339 ///
340 ///
341 /// This function currently corresponds to the `hypotf128` from libc on Unix
342 /// and Windows. Note that this might change in the future.
343 ///
344 /// # Examples
345 ///
346 /// ```
347 /// #![feature(f128)]
348 /// # #[cfg(not(miri))]
349 /// # #[cfg(target_has_reliable_f128_math)] {
350 ///
351 /// let x = 2.0f128;
352 /// let y = 3.0f128;
353 ///
354 /// // sqrt(x^2 + y^2)
355 /// let abs_difference = (x.hypot(y) - (x.powi(2) + y.powi(2)).sqrt()).abs();
356 ///
357 /// assert!(abs_difference <= f128::EPSILON);
358 /// # }
359 /// ```
360 #[inline]
361 #[rustc_allow_incoherent_impl]
362 #[unstable(feature = "f128", issue = "116909")]
363 #[must_use = "method returns a new number and does not mutate the original value"]
364 pub fn hypot(self, other: f128) -> f128 {
365 cmath::hypotf128(self, other)
366 }
367
368 /// Computes the sine of a number (in radians).
369 ///
370 /// # Unspecified precision
371 ///
372 /// The precision of this function is non-deterministic. This means it varies by platform,
373 /// Rust version, and can even differ within the same execution from one invocation to the next.
374 ///
375 /// # Examples
376 ///
377 /// ```
378 /// #![feature(f128)]
379 /// # #[cfg(not(miri))]
380 /// # #[cfg(target_has_reliable_f128_math)] {
381 ///
382 /// let x = std::f128::consts::FRAC_PI_2;
383 ///
384 /// let abs_difference = (x.sin() - 1.0).abs();
385 ///
386 /// assert!(abs_difference <= f128::EPSILON);
387 /// # }
388 /// ```
389 #[inline]
390 #[rustc_allow_incoherent_impl]
391 #[unstable(feature = "f128", issue = "116909")]
392 #[must_use = "method returns a new number and does not mutate the original value"]
393 pub fn sin(self) -> f128 {
394 intrinsics::sinf128(self)
395 }
396
397 /// Computes the cosine of a number (in radians).
398 ///
399 /// # Unspecified precision
400 ///
401 /// The precision of this function is non-deterministic. This means it varies by platform,
402 /// Rust version, and can even differ within the same execution from one invocation to the next.
403 ///
404 /// # Examples
405 ///
406 /// ```
407 /// #![feature(f128)]
408 /// # #[cfg(not(miri))]
409 /// # #[cfg(target_has_reliable_f128_math)] {
410 ///
411 /// let x = 2.0 * std::f128::consts::PI;
412 ///
413 /// let abs_difference = (x.cos() - 1.0).abs();
414 ///
415 /// assert!(abs_difference <= f128::EPSILON);
416 /// # }
417 /// ```
418 #[inline]
419 #[rustc_allow_incoherent_impl]
420 #[unstable(feature = "f128", issue = "116909")]
421 #[must_use = "method returns a new number and does not mutate the original value"]
422 pub fn cos(self) -> f128 {
423 intrinsics::cosf128(self)
424 }
425
426 /// Computes the tangent of a number (in radians).
427 ///
428 /// # Unspecified precision
429 ///
430 /// The precision of this function is non-deterministic. This means it varies by platform,
431 /// Rust version, and can even differ within the same execution from one invocation to the next.
432 ///
433 /// This function currently corresponds to the `tanf128` from libc on Unix and
434 /// Windows. Note that this might change in the future.
435 ///
436 /// # Examples
437 ///
438 /// ```
439 /// #![feature(f128)]
440 /// # #[cfg(not(miri))]
441 /// # #[cfg(target_has_reliable_f128_math)] {
442 ///
443 /// let x = std::f128::consts::FRAC_PI_4;
444 /// let abs_difference = (x.tan() - 1.0).abs();
445 ///
446 /// assert!(abs_difference <= f128::EPSILON);
447 /// # }
448 /// ```
449 #[inline]
450 #[rustc_allow_incoherent_impl]
451 #[unstable(feature = "f128", issue = "116909")]
452 #[must_use = "method returns a new number and does not mutate the original value"]
453 pub fn tan(self) -> f128 {
454 cmath::tanf128(self)
455 }
456
457 /// Computes the arcsine of a number. Return value is in radians in
458 /// the range [-pi/2, pi/2] or NaN if the number is outside the range
459 /// [-1, 1].
460 ///
461 /// # Unspecified precision
462 ///
463 /// The precision of this function is non-deterministic. This means it varies by platform,
464 /// Rust version, and can even differ within the same execution from one invocation to the next.
465 ///
466 /// This function currently corresponds to the `asinf128` from libc on Unix
467 /// and Windows. Note that this might change in the future.
468 ///
469 /// # Examples
470 ///
471 /// ```
472 /// #![feature(f128)]
473 /// # #[cfg(not(miri))]
474 /// # #[cfg(target_has_reliable_f128_math)] {
475 ///
476 /// let f = std::f128::consts::FRAC_PI_4;
477 ///
478 /// // asin(sin(pi/2))
479 /// let abs_difference = (f.sin().asin() - f).abs();
480 ///
481 /// assert!(abs_difference <= f128::EPSILON);
482 /// # }
483 /// ```
484 #[inline]
485 #[doc(alias = "arcsin")]
486 #[rustc_allow_incoherent_impl]
487 #[unstable(feature = "f128", issue = "116909")]
488 #[must_use = "method returns a new number and does not mutate the original value"]
489 pub fn asin(self) -> f128 {
490 cmath::asinf128(self)
491 }
492
493 /// Computes the arccosine of a number. Return value is in radians in
494 /// the range [0, pi] or NaN if the number is outside the range
495 /// [-1, 1].
496 ///
497 /// # Unspecified precision
498 ///
499 /// The precision of this function is non-deterministic. This means it varies by platform,
500 /// Rust version, and can even differ within the same execution from one invocation to the next.
501 ///
502 /// This function currently corresponds to the `acosf128` from libc on Unix
503 /// and Windows. Note that this might change in the future.
504 ///
505 /// # Examples
506 ///
507 /// ```
508 /// #![feature(f128)]
509 /// # #[cfg(not(miri))]
510 /// # #[cfg(target_has_reliable_f128_math)] {
511 ///
512 /// let f = std::f128::consts::FRAC_PI_4;
513 ///
514 /// // acos(cos(pi/4))
515 /// let abs_difference = (f.cos().acos() - std::f128::consts::FRAC_PI_4).abs();
516 ///
517 /// assert!(abs_difference <= f128::EPSILON);
518 /// # }
519 /// ```
520 #[inline]
521 #[doc(alias = "arccos")]
522 #[rustc_allow_incoherent_impl]
523 #[unstable(feature = "f128", issue = "116909")]
524 #[must_use = "method returns a new number and does not mutate the original value"]
525 pub fn acos(self) -> f128 {
526 cmath::acosf128(self)
527 }
528
529 /// Computes the arctangent of a number. Return value is in radians in the
530 /// range [-pi/2, pi/2];
531 ///
532 /// # Unspecified precision
533 ///
534 /// The precision of this function is non-deterministic. This means it varies by platform,
535 /// Rust version, and can even differ within the same execution from one invocation to the next.
536 ///
537 /// This function currently corresponds to the `atanf128` from libc on Unix
538 /// and Windows. Note that this might change in the future.
539 ///
540 /// # Examples
541 ///
542 /// ```
543 /// #![feature(f128)]
544 /// # #[cfg(not(miri))]
545 /// # #[cfg(target_has_reliable_f128_math)] {
546 ///
547 /// let f = 1.0f128;
548 ///
549 /// // atan(tan(1))
550 /// let abs_difference = (f.tan().atan() - 1.0).abs();
551 ///
552 /// assert!(abs_difference <= f128::EPSILON);
553 /// # }
554 /// ```
555 #[inline]
556 #[doc(alias = "arctan")]
557 #[rustc_allow_incoherent_impl]
558 #[unstable(feature = "f128", issue = "116909")]
559 #[must_use = "method returns a new number and does not mutate the original value"]
560 pub fn atan(self) -> f128 {
561 cmath::atanf128(self)
562 }
563
564 /// Computes the four quadrant arctangent of `self` (`y`) and `other` (`x`) in radians.
565 ///
566 /// | `x` | `y` | Piecewise Definition | Range |
567 /// |---------|---------|----------------------|---------------|
568 /// | `>= +0` | `>= +0` | `arctan(y/x)` | `[+0, +pi/2]` |
569 /// | `>= +0` | `<= -0` | `arctan(y/x)` | `[-pi/2, -0]` |
570 /// | `<= -0` | `>= +0` | `arctan(y/x) + pi` | `[+pi/2, +pi]`|
571 /// | `<= -0` | `<= -0` | `arctan(y/x) - pi` | `[-pi, -pi/2]`|
572 ///
573 /// # Unspecified precision
574 ///
575 /// The precision of this function is non-deterministic. This means it varies by platform,
576 /// Rust version, and can even differ within the same execution from one invocation to the next.
577 ///
578 /// This function currently corresponds to the `atan2f128` from libc on Unix
579 /// and Windows. Note that this might change in the future.
580 ///
581 /// # Examples
582 ///
583 /// ```
584 /// #![feature(f128)]
585 /// # #[cfg(not(miri))]
586 /// # #[cfg(target_has_reliable_f128_math)] {
587 ///
588 /// // Positive angles measured counter-clockwise
589 /// // from positive x axis
590 /// // -pi/4 radians (45 deg clockwise)
591 /// let x1 = 3.0f128;
592 /// let y1 = -3.0f128;
593 ///
594 /// // 3pi/4 radians (135 deg counter-clockwise)
595 /// let x2 = -3.0f128;
596 /// let y2 = 3.0f128;
597 ///
598 /// let abs_difference_1 = (y1.atan2(x1) - (-std::f128::consts::FRAC_PI_4)).abs();
599 /// let abs_difference_2 = (y2.atan2(x2) - (3.0 * std::f128::consts::FRAC_PI_4)).abs();
600 ///
601 /// assert!(abs_difference_1 <= f128::EPSILON);
602 /// assert!(abs_difference_2 <= f128::EPSILON);
603 /// # }
604 /// ```
605 #[inline]
606 #[rustc_allow_incoherent_impl]
607 #[unstable(feature = "f128", issue = "116909")]
608 #[must_use = "method returns a new number and does not mutate the original value"]
609 pub fn atan2(self, other: f128) -> f128 {
610 cmath::atan2f128(self, other)
611 }
612
613 /// Simultaneously computes the sine and cosine of the number, `x`. Returns
614 /// `(sin(x), cos(x))`.
615 ///
616 /// # Unspecified precision
617 ///
618 /// The precision of this function is non-deterministic. This means it varies by platform,
619 /// Rust version, and can even differ within the same execution from one invocation to the next.
620 ///
621 /// This function currently corresponds to the `(f128::sin(x),
622 /// f128::cos(x))`. Note that this might change in the future.
623 ///
624 /// # Examples
625 ///
626 /// ```
627 /// #![feature(f128)]
628 /// # #[cfg(not(miri))]
629 /// # #[cfg(target_has_reliable_f128_math)] {
630 ///
631 /// let x = std::f128::consts::FRAC_PI_4;
632 /// let f = x.sin_cos();
633 ///
634 /// let abs_difference_0 = (f.0 - x.sin()).abs();
635 /// let abs_difference_1 = (f.1 - x.cos()).abs();
636 ///
637 /// assert!(abs_difference_0 <= f128::EPSILON);
638 /// assert!(abs_difference_1 <= f128::EPSILON);
639 /// # }
640 /// ```
641 #[inline]
642 #[doc(alias = "sincos")]
643 #[rustc_allow_incoherent_impl]
644 #[unstable(feature = "f128", issue = "116909")]
645 pub fn sin_cos(self) -> (f128, f128) {
646 (self.sin(), self.cos())
647 }
648
649 /// Returns `e^(self) - 1` in a way that is accurate even if the
650 /// number is close to zero.
651 ///
652 /// # Unspecified precision
653 ///
654 /// The precision of this function is non-deterministic. This means it varies by platform,
655 /// Rust version, and can even differ within the same execution from one invocation to the next.
656 ///
657 /// This function currently corresponds to the `expm1f128` from libc on Unix
658 /// and Windows. Note that this might change in the future.
659 ///
660 /// # Examples
661 ///
662 /// ```
663 /// #![feature(f128)]
664 /// # #[cfg(not(miri))]
665 /// # #[cfg(target_has_reliable_f128_math)] {
666 ///
667 /// let x = 1e-8_f128;
668 ///
669 /// // for very small x, e^x is approximately 1 + x + x^2 / 2
670 /// let approx = x + x * x / 2.0;
671 /// let abs_difference = (x.exp_m1() - approx).abs();
672 ///
673 /// assert!(abs_difference < 1e-10);
674 /// # }
675 /// ```
676 #[inline]
677 #[rustc_allow_incoherent_impl]
678 #[unstable(feature = "f128", issue = "116909")]
679 #[must_use = "method returns a new number and does not mutate the original value"]
680 pub fn exp_m1(self) -> f128 {
681 cmath::expm1f128(self)
682 }
683
684 /// Returns `ln(1+n)` (natural logarithm) more accurately than if
685 /// the operations were performed separately.
686 ///
687 /// This returns NaN when `n < -1.0`, and negative infinity when `n == -1.0`.
688 ///
689 /// # Unspecified precision
690 ///
691 /// The precision of this function is non-deterministic. This means it varies by platform,
692 /// Rust version, and can even differ within the same execution from one invocation to the next.
693 ///
694 /// This function currently corresponds to the `log1pf128` from libc on Unix
695 /// and Windows. Note that this might change in the future.
696 ///
697 /// # Examples
698 ///
699 /// ```
700 /// #![feature(f128)]
701 /// # #[cfg(not(miri))]
702 /// # #[cfg(target_has_reliable_f128_math)] {
703 ///
704 /// let x = 1e-8_f128;
705 ///
706 /// // for very small x, ln(1 + x) is approximately x - x^2 / 2
707 /// let approx = x - x * x / 2.0;
708 /// let abs_difference = (x.ln_1p() - approx).abs();
709 ///
710 /// assert!(abs_difference < 1e-10);
711 /// # }
712 /// ```
713 ///
714 /// Out-of-range values:
715 /// ```
716 /// #![feature(f128)]
717 /// # #[cfg(not(miri))]
718 /// # #[cfg(target_has_reliable_f128_math)] {
719 ///
720 /// assert_eq!((-1.0_f128).ln_1p(), f128::NEG_INFINITY);
721 /// assert!((-2.0_f128).ln_1p().is_nan());
722 /// # }
723 /// ```
724 #[inline]
725 #[doc(alias = "log1p")]
726 #[must_use = "method returns a new number and does not mutate the original value"]
727 #[rustc_allow_incoherent_impl]
728 #[unstable(feature = "f128", issue = "116909")]
729 pub fn ln_1p(self) -> f128 {
730 cmath::log1pf128(self)
731 }
732
733 /// Hyperbolic sine function.
734 ///
735 /// # Unspecified precision
736 ///
737 /// The precision of this function is non-deterministic. This means it varies by platform,
738 /// Rust version, and can even differ within the same execution from one invocation to the next.
739 ///
740 /// This function currently corresponds to the `sinhf128` from libc on Unix
741 /// and Windows. Note that this might change in the future.
742 ///
743 /// # Examples
744 ///
745 /// ```
746 /// #![feature(f128)]
747 /// # #[cfg(not(miri))]
748 /// # #[cfg(target_has_reliable_f128_math)] {
749 ///
750 /// let e = std::f128::consts::E;
751 /// let x = 1.0f128;
752 ///
753 /// let f = x.sinh();
754 /// // Solving sinh() at 1 gives `(e^2-1)/(2e)`
755 /// let g = ((e * e) - 1.0) / (2.0 * e);
756 /// let abs_difference = (f - g).abs();
757 ///
758 /// assert!(abs_difference <= f128::EPSILON);
759 /// # }
760 /// ```
761 #[inline]
762 #[rustc_allow_incoherent_impl]
763 #[unstable(feature = "f128", issue = "116909")]
764 #[must_use = "method returns a new number and does not mutate the original value"]
765 pub fn sinh(self) -> f128 {
766 cmath::sinhf128(self)
767 }
768
769 /// Hyperbolic cosine function.
770 ///
771 /// # Unspecified precision
772 ///
773 /// The precision of this function is non-deterministic. This means it varies by platform,
774 /// Rust version, and can even differ within the same execution from one invocation to the next.
775 ///
776 /// This function currently corresponds to the `coshf128` from libc on Unix
777 /// and Windows. Note that this might change in the future.
778 ///
779 /// # Examples
780 ///
781 /// ```
782 /// #![feature(f128)]
783 /// # #[cfg(not(miri))]
784 /// # #[cfg(target_has_reliable_f128_math)] {
785 ///
786 /// let e = std::f128::consts::E;
787 /// let x = 1.0f128;
788 /// let f = x.cosh();
789 /// // Solving cosh() at 1 gives this result
790 /// let g = ((e * e) + 1.0) / (2.0 * e);
791 /// let abs_difference = (f - g).abs();
792 ///
793 /// // Same result
794 /// assert!(abs_difference <= f128::EPSILON);
795 /// # }
796 /// ```
797 #[inline]
798 #[rustc_allow_incoherent_impl]
799 #[unstable(feature = "f128", issue = "116909")]
800 #[must_use = "method returns a new number and does not mutate the original value"]
801 pub fn cosh(self) -> f128 {
802 cmath::coshf128(self)
803 }
804
805 /// Hyperbolic tangent function.
806 ///
807 /// # Unspecified precision
808 ///
809 /// The precision of this function is non-deterministic. This means it varies by platform,
810 /// Rust version, and can even differ within the same execution from one invocation to the next.
811 ///
812 /// This function currently corresponds to the `tanhf128` from libc on Unix
813 /// and Windows. Note that this might change in the future.
814 ///
815 /// # Examples
816 ///
817 /// ```
818 /// #![feature(f128)]
819 /// # #[cfg(not(miri))]
820 /// # #[cfg(target_has_reliable_f128_math)] {
821 ///
822 /// let e = std::f128::consts::E;
823 /// let x = 1.0f128;
824 ///
825 /// let f = x.tanh();
826 /// // Solving tanh() at 1 gives `(1 - e^(-2))/(1 + e^(-2))`
827 /// let g = (1.0 - e.powi(-2)) / (1.0 + e.powi(-2));
828 /// let abs_difference = (f - g).abs();
829 ///
830 /// assert!(abs_difference <= f128::EPSILON);
831 /// # }
832 /// ```
833 #[inline]
834 #[rustc_allow_incoherent_impl]
835 #[unstable(feature = "f128", issue = "116909")]
836 #[must_use = "method returns a new number and does not mutate the original value"]
837 pub fn tanh(self) -> f128 {
838 cmath::tanhf128(self)
839 }
840
841 /// Inverse hyperbolic sine function.
842 ///
843 /// # Unspecified precision
844 ///
845 /// The precision of this function is non-deterministic. This means it varies by platform,
846 /// Rust version, and can even differ within the same execution from one invocation to the next.
847 ///
848 /// # Examples
849 ///
850 /// ```
851 /// #![feature(f128)]
852 /// # #[cfg(not(miri))]
853 /// # #[cfg(target_has_reliable_f128_math)] {
854 ///
855 /// let x = 1.0f128;
856 /// let f = x.sinh().asinh();
857 ///
858 /// let abs_difference = (f - x).abs();
859 ///
860 /// assert!(abs_difference <= f128::EPSILON);
861 /// # }
862 /// ```
863 #[inline]
864 #[doc(alias = "arcsinh")]
865 #[rustc_allow_incoherent_impl]
866 #[unstable(feature = "f128", issue = "116909")]
867 #[must_use = "method returns a new number and does not mutate the original value"]
868 pub fn asinh(self) -> f128 {
869 let ax = self.abs();
870 let ix = 1.0 / ax;
871 (ax + (ax / (Self::hypot(1.0, ix) + ix))).ln_1p().copysign(self)
872 }
873
874 /// Inverse hyperbolic cosine function.
875 ///
876 /// # Unspecified precision
877 ///
878 /// The precision of this function is non-deterministic. This means it varies by platform,
879 /// Rust version, and can even differ within the same execution from one invocation to the next.
880 ///
881 /// # Examples
882 ///
883 /// ```
884 /// #![feature(f128)]
885 /// # #[cfg(not(miri))]
886 /// # #[cfg(target_has_reliable_f128_math)] {
887 ///
888 /// let x = 1.0f128;
889 /// let f = x.cosh().acosh();
890 ///
891 /// let abs_difference = (f - x).abs();
892 ///
893 /// assert!(abs_difference <= f128::EPSILON);
894 /// # }
895 /// ```
896 #[inline]
897 #[doc(alias = "arccosh")]
898 #[rustc_allow_incoherent_impl]
899 #[unstable(feature = "f128", issue = "116909")]
900 #[must_use = "method returns a new number and does not mutate the original value"]
901 pub fn acosh(self) -> f128 {
902 if self < 1.0 {
903 Self::NAN
904 } else {
905 (self + ((self - 1.0).sqrt() * (self + 1.0).sqrt())).ln()
906 }
907 }
908
909 /// Inverse hyperbolic tangent function.
910 ///
911 /// # Unspecified precision
912 ///
913 /// The precision of this function is non-deterministic. This means it varies by platform,
914 /// Rust version, and can even differ within the same execution from one invocation to the next.
915 ///
916 /// # Examples
917 ///
918 /// ```
919 /// #![feature(f128)]
920 /// # #[cfg(not(miri))]
921 /// # #[cfg(target_has_reliable_f128_math)] {
922 ///
923 /// let x = std::f128::consts::FRAC_PI_6;
924 /// let f = x.tanh().atanh();
925 ///
926 /// let abs_difference = (f - x).abs();
927 ///
928 /// assert!(abs_difference <= 1e-5);
929 /// # }
930 /// ```
931 #[inline]
932 #[doc(alias = "arctanh")]
933 #[rustc_allow_incoherent_impl]
934 #[unstable(feature = "f128", issue = "116909")]
935 #[must_use = "method returns a new number and does not mutate the original value"]
936 pub fn atanh(self) -> f128 {
937 0.5 * ((2.0 * self) / (1.0 - self)).ln_1p()
938 }
939
940 /// Gamma function.
941 ///
942 /// # Unspecified precision
943 ///
944 /// The precision of this function is non-deterministic. This means it varies by platform,
945 /// Rust version, and can even differ within the same execution from one invocation to the next.
946 ///
947 /// This function currently corresponds to the `tgammaf128` from libc on Unix
948 /// and Windows. Note that this might change in the future.
949 ///
950 /// # Examples
951 ///
952 /// ```
953 /// #![feature(f128)]
954 /// #![feature(float_gamma)]
955 /// # #[cfg(not(miri))]
956 /// # #[cfg(target_has_reliable_f128_math)] {
957 ///
958 /// let x = 5.0f128;
959 ///
960 /// let abs_difference = (x.gamma() - 24.0).abs();
961 ///
962 /// assert!(abs_difference <= f128::EPSILON);
963 /// # }
964 /// ```
965 #[inline]
966 #[rustc_allow_incoherent_impl]
967 #[unstable(feature = "f128", issue = "116909")]
968 // #[unstable(feature = "float_gamma", issue = "99842")]
969 #[must_use = "method returns a new number and does not mutate the original value"]
970 pub fn gamma(self) -> f128 {
971 cmath::tgammaf128(self)
972 }
973
974 /// Natural logarithm of the absolute value of the gamma function
975 ///
976 /// The integer part of the tuple indicates the sign of the gamma function.
977 ///
978 /// # Unspecified precision
979 ///
980 /// The precision of this function is non-deterministic. This means it varies by platform,
981 /// Rust version, and can even differ within the same execution from one invocation to the next.
982 ///
983 /// This function currently corresponds to the `lgammaf128_r` from libc on Unix
984 /// and Windows. Note that this might change in the future.
985 ///
986 /// # Examples
987 ///
988 /// ```
989 /// #![feature(f128)]
990 /// #![feature(float_gamma)]
991 /// # #[cfg(not(miri))]
992 /// # #[cfg(target_has_reliable_f128_math)] {
993 ///
994 /// let x = 2.0f128;
995 ///
996 /// let abs_difference = (x.ln_gamma().0 - 0.0).abs();
997 ///
998 /// assert!(abs_difference <= f128::EPSILON);
999 /// # }
1000 /// ```
1001 #[inline]
1002 #[rustc_allow_incoherent_impl]
1003 #[unstable(feature = "f128", issue = "116909")]
1004 // #[unstable(feature = "float_gamma", issue = "99842")]
1005 #[must_use = "method returns a new number and does not mutate the original value"]
1006 pub fn ln_gamma(self) -> (f128, i32) {
1007 let mut signgamp: i32 = 0;
1008 let x = cmath::lgammaf128_r(self, &mut signgamp);
1009 (x, signgamp)
1010 }
1011
1012 /// Error function.
1013 ///
1014 /// # Unspecified precision
1015 ///
1016 /// The precision of this function is non-deterministic. This means it varies by platform,
1017 /// Rust version, and can even differ within the same execution from one invocation to the next.
1018 ///
1019 /// This function currently corresponds to the `erff128` from libc on Unix
1020 /// and Windows. Note that this might change in the future.
1021 ///
1022 /// # Examples
1023 ///
1024 /// ```
1025 /// #![feature(f128)]
1026 /// #![feature(float_erf)]
1027 /// # #[cfg(not(miri))]
1028 /// # #[cfg(target_has_reliable_f128_math)] {
1029 /// /// The error function relates what percent of a normal distribution lies
1030 /// /// within `x` standard deviations (scaled by `1/sqrt(2)`).
1031 /// fn within_standard_deviations(x: f128) -> f128 {
1032 /// (x * std::f128::consts::FRAC_1_SQRT_2).erf() * 100.0
1033 /// }
1034 ///
1035 /// // 68% of a normal distribution is within one standard deviation
1036 /// assert!((within_standard_deviations(1.0) - 68.269).abs() < 0.01);
1037 /// // 95% of a normal distribution is within two standard deviations
1038 /// assert!((within_standard_deviations(2.0) - 95.450).abs() < 0.01);
1039 /// // 99.7% of a normal distribution is within three standard deviations
1040 /// assert!((within_standard_deviations(3.0) - 99.730).abs() < 0.01);
1041 /// # }
1042 /// ```
1043 #[rustc_allow_incoherent_impl]
1044 #[must_use = "method returns a new number and does not mutate the original value"]
1045 #[unstable(feature = "f128", issue = "116909")]
1046 // #[unstable(feature = "float_erf", issue = "136321")]
1047 #[inline]
1048 pub fn erf(self) -> f128 {
1049 cmath::erff128(self)
1050 }
1051
1052 /// Complementary error function.
1053 ///
1054 /// # Unspecified precision
1055 ///
1056 /// The precision of this function is non-deterministic. This means it varies by platform,
1057 /// Rust version, and can even differ within the same execution from one invocation to the next.
1058 ///
1059 /// This function currently corresponds to the `erfcf128` from libc on Unix
1060 /// and Windows. Note that this might change in the future.
1061 ///
1062 /// # Examples
1063 ///
1064 /// ```
1065 /// #![feature(f128)]
1066 /// #![feature(float_erf)]
1067 /// # #[cfg(not(miri))]
1068 /// # #[cfg(target_has_reliable_f128_math)] {
1069 /// let x: f128 = 0.123;
1070 ///
1071 /// let one = x.erf() + x.erfc();
1072 /// let abs_difference = (one - 1.0).abs();
1073 ///
1074 /// assert!(abs_difference <= f128::EPSILON);
1075 /// # }
1076 /// ```
1077 #[rustc_allow_incoherent_impl]
1078 #[must_use = "method returns a new number and does not mutate the original value"]
1079 #[unstable(feature = "f128", issue = "116909")]
1080 // #[unstable(feature = "float_erf", issue = "136321")]
1081 #[inline]
1082 pub fn erfc(self) -> f128 {
1083 cmath::erfcf128(self)
1084 }
1085}