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