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