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