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" )] |
11 | pub use core::f128::consts; |
12 | |
13 | #[cfg (not(test))] |
14 | use crate::intrinsics; |
15 | #[cfg (not(test))] |
16 | use crate::sys::cmath; |
17 | |
18 | #[cfg (not(test))] |
19 | impl 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 | } |
1078 | |