]> git.lizzy.rs Git - rust.git/blob - src/libstd/f64.rs
One must always remember to clean up after themselves
[rust.git] / src / libstd / f64.rs
1 // Copyright 2012-2015 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 //! This module provides constants which are specific to the implementation
12 //! of the `f64` floating point data type.
13 //!
14 //! *[See also the `f64` primitive type](../../std/primitive.f64.html).*
15 //!
16 //! Mathematically significant numbers are provided in the `consts` sub-module.
17
18 #![stable(feature = "rust1", since = "1.0.0")]
19 #![allow(missing_docs)]
20
21 #[cfg(not(test))]
22 #[cfg(stage0)]
23 use core::num::Float;
24 #[cfg(not(test))]
25 use intrinsics;
26 #[cfg(not(test))]
27 #[cfg(stage0)]
28 use num::FpCategory;
29 #[cfg(not(test))]
30 use sys::cmath;
31
32 #[stable(feature = "rust1", since = "1.0.0")]
33 pub use core::f64::{RADIX, MANTISSA_DIGITS, DIGITS, EPSILON};
34 #[stable(feature = "rust1", since = "1.0.0")]
35 pub use core::f64::{MIN_EXP, MAX_EXP, MIN_10_EXP};
36 #[stable(feature = "rust1", since = "1.0.0")]
37 pub use core::f64::{MAX_10_EXP, NAN, INFINITY, NEG_INFINITY};
38 #[stable(feature = "rust1", since = "1.0.0")]
39 pub use core::f64::{MIN, MIN_POSITIVE, MAX};
40 #[stable(feature = "rust1", since = "1.0.0")]
41 pub use core::f64::consts;
42
43 #[cfg(not(test))]
44 #[cfg_attr(stage0, lang = "f64")]
45 #[cfg_attr(not(stage0), lang = "f64_runtime")]
46 impl f64 {
47     #[cfg(stage0)]
48     f64_core_methods!();
49
50     /// Returns the largest integer less than or equal to a number.
51     ///
52     /// ```
53     /// let f = 3.99_f64;
54     /// let g = 3.0_f64;
55     ///
56     /// assert_eq!(f.floor(), 3.0);
57     /// assert_eq!(g.floor(), 3.0);
58     /// ```
59     #[stable(feature = "rust1", since = "1.0.0")]
60     #[inline]
61     pub fn floor(self) -> f64 {
62         unsafe { intrinsics::floorf64(self) }
63     }
64
65     /// Returns the smallest integer greater than or equal to a number.
66     ///
67     /// ```
68     /// let f = 3.01_f64;
69     /// let g = 4.0_f64;
70     ///
71     /// assert_eq!(f.ceil(), 4.0);
72     /// assert_eq!(g.ceil(), 4.0);
73     /// ```
74     #[stable(feature = "rust1", since = "1.0.0")]
75     #[inline]
76     pub fn ceil(self) -> f64 {
77         unsafe { intrinsics::ceilf64(self) }
78     }
79
80     /// Returns the nearest integer to a number. Round half-way cases away from
81     /// `0.0`.
82     ///
83     /// ```
84     /// let f = 3.3_f64;
85     /// let g = -3.3_f64;
86     ///
87     /// assert_eq!(f.round(), 3.0);
88     /// assert_eq!(g.round(), -3.0);
89     /// ```
90     #[stable(feature = "rust1", since = "1.0.0")]
91     #[inline]
92     pub fn round(self) -> f64 {
93         unsafe { intrinsics::roundf64(self) }
94     }
95
96     /// Returns the integer part of a number.
97     ///
98     /// ```
99     /// let f = 3.3_f64;
100     /// let g = -3.7_f64;
101     ///
102     /// assert_eq!(f.trunc(), 3.0);
103     /// assert_eq!(g.trunc(), -3.0);
104     /// ```
105     #[stable(feature = "rust1", since = "1.0.0")]
106     #[inline]
107     pub fn trunc(self) -> f64 {
108         unsafe { intrinsics::truncf64(self) }
109     }
110
111     /// Returns the fractional part of a number.
112     ///
113     /// ```
114     /// let x = 3.5_f64;
115     /// let y = -3.5_f64;
116     /// let abs_difference_x = (x.fract() - 0.5).abs();
117     /// let abs_difference_y = (y.fract() - (-0.5)).abs();
118     ///
119     /// assert!(abs_difference_x < 1e-10);
120     /// assert!(abs_difference_y < 1e-10);
121     /// ```
122     #[stable(feature = "rust1", since = "1.0.0")]
123     #[inline]
124     pub fn fract(self) -> f64 { self - self.trunc() }
125
126     /// Computes the absolute value of `self`. Returns `NAN` if the
127     /// number is `NAN`.
128     ///
129     /// ```
130     /// use std::f64;
131     ///
132     /// let x = 3.5_f64;
133     /// let y = -3.5_f64;
134     ///
135     /// let abs_difference_x = (x.abs() - x).abs();
136     /// let abs_difference_y = (y.abs() - (-y)).abs();
137     ///
138     /// assert!(abs_difference_x < 1e-10);
139     /// assert!(abs_difference_y < 1e-10);
140     ///
141     /// assert!(f64::NAN.abs().is_nan());
142     /// ```
143     #[stable(feature = "rust1", since = "1.0.0")]
144     #[inline]
145     pub fn abs(self) -> f64 {
146         unsafe { intrinsics::fabsf64(self) }
147     }
148
149     /// Returns a number that represents the sign of `self`.
150     ///
151     /// - `1.0` if the number is positive, `+0.0` or `INFINITY`
152     /// - `-1.0` if the number is negative, `-0.0` or `NEG_INFINITY`
153     /// - `NAN` if the number is `NAN`
154     ///
155     /// ```
156     /// use std::f64;
157     ///
158     /// let f = 3.5_f64;
159     ///
160     /// assert_eq!(f.signum(), 1.0);
161     /// assert_eq!(f64::NEG_INFINITY.signum(), -1.0);
162     ///
163     /// assert!(f64::NAN.signum().is_nan());
164     /// ```
165     #[stable(feature = "rust1", since = "1.0.0")]
166     #[inline]
167     pub fn signum(self) -> f64 {
168         if self.is_nan() {
169             NAN
170         } else {
171             unsafe { intrinsics::copysignf64(1.0, self) }
172         }
173     }
174
175     /// Fused multiply-add. Computes `(self * a) + b` with only one rounding
176     /// error, yielding a more accurate result than an unfused multiply-add.
177     ///
178     /// Using `mul_add` can be more performant than an unfused multiply-add if
179     /// the target architecture has a dedicated `fma` CPU instruction.
180     ///
181     /// ```
182     /// let m = 10.0_f64;
183     /// let x = 4.0_f64;
184     /// let b = 60.0_f64;
185     ///
186     /// // 100.0
187     /// let abs_difference = (m.mul_add(x, b) - (m*x + b)).abs();
188     ///
189     /// assert!(abs_difference < 1e-10);
190     /// ```
191     #[stable(feature = "rust1", since = "1.0.0")]
192     #[inline]
193     pub fn mul_add(self, a: f64, b: f64) -> f64 {
194         unsafe { intrinsics::fmaf64(self, a, b) }
195     }
196
197     /// Calculates Euclidean division, the matching method for `mod_euc`.
198     ///
199     /// This computes the integer `n` such that
200     /// `self = n * rhs + self.mod_euc(rhs)`.
201     /// In other words, the result is `self / rhs` rounded to the integer `n`
202     /// such that `self >= n * rhs`.
203     ///
204     /// ```
205     /// #![feature(euclidean_division)]
206     /// let a: f64 = 7.0;
207     /// let b = 4.0;
208     /// assert_eq!(a.div_euc(b), 1.0); // 7.0 > 4.0 * 1.0
209     /// assert_eq!((-a).div_euc(b), -2.0); // -7.0 >= 4.0 * -2.0
210     /// assert_eq!(a.div_euc(-b), -1.0); // 7.0 >= -4.0 * -1.0
211     /// assert_eq!((-a).div_euc(-b), 2.0); // -7.0 >= -4.0 * 2.0
212     /// ```
213     #[inline]
214     #[unstable(feature = "euclidean_division", issue = "49048")]
215     pub fn div_euc(self, rhs: f64) -> f64 {
216         let q = (self / rhs).trunc();
217         if self % rhs < 0.0 {
218             return if rhs > 0.0 { q - 1.0 } else { q + 1.0 }
219         }
220         q
221     }
222
223     /// Calculates the Euclidean modulo (self mod rhs), which is never negative.
224     ///
225     /// In particular, the result `n` satisfies `0 <= n < rhs.abs()`.
226     ///
227     /// ```
228     /// #![feature(euclidean_division)]
229     /// let a: f64 = 7.0;
230     /// let b = 4.0;
231     /// assert_eq!(a.mod_euc(b), 3.0);
232     /// assert_eq!((-a).mod_euc(b), 1.0);
233     /// assert_eq!(a.mod_euc(-b), 3.0);
234     /// assert_eq!((-a).mod_euc(-b), 1.0);
235     /// ```
236     #[inline]
237     #[unstable(feature = "euclidean_division", issue = "49048")]
238     pub fn mod_euc(self, rhs: f64) -> f64 {
239         let r = self % rhs;
240         if r < 0.0 {
241             r + rhs.abs()
242         } else {
243             r
244         }
245     }
246
247     /// Raises a number to an integer power.
248     ///
249     /// Using this function is generally faster than using `powf`
250     ///
251     /// ```
252     /// let x = 2.0_f64;
253     /// let abs_difference = (x.powi(2) - x*x).abs();
254     ///
255     /// assert!(abs_difference < 1e-10);
256     /// ```
257     #[stable(feature = "rust1", since = "1.0.0")]
258     #[inline]
259     pub fn powi(self, n: i32) -> f64 {
260         unsafe { intrinsics::powif64(self, n) }
261     }
262
263     /// Raises a number to a floating point power.
264     ///
265     /// ```
266     /// let x = 2.0_f64;
267     /// let abs_difference = (x.powf(2.0) - x*x).abs();
268     ///
269     /// assert!(abs_difference < 1e-10);
270     /// ```
271     #[stable(feature = "rust1", since = "1.0.0")]
272     #[inline]
273     pub fn powf(self, n: f64) -> f64 {
274         unsafe { intrinsics::powf64(self, n) }
275     }
276
277     /// Takes the square root of a number.
278     ///
279     /// Returns NaN if `self` is a negative number.
280     ///
281     /// ```
282     /// let positive = 4.0_f64;
283     /// let negative = -4.0_f64;
284     ///
285     /// let abs_difference = (positive.sqrt() - 2.0).abs();
286     ///
287     /// assert!(abs_difference < 1e-10);
288     /// assert!(negative.sqrt().is_nan());
289     /// ```
290     #[stable(feature = "rust1", since = "1.0.0")]
291     #[inline]
292     pub fn sqrt(self) -> f64 {
293         if self < 0.0 {
294             NAN
295         } else {
296             unsafe { intrinsics::sqrtf64(self) }
297         }
298     }
299
300     /// Returns `e^(self)`, (the exponential function).
301     ///
302     /// ```
303     /// let one = 1.0_f64;
304     /// // e^1
305     /// let e = one.exp();
306     ///
307     /// // ln(e) - 1 == 0
308     /// let abs_difference = (e.ln() - 1.0).abs();
309     ///
310     /// assert!(abs_difference < 1e-10);
311     /// ```
312     #[stable(feature = "rust1", since = "1.0.0")]
313     #[inline]
314     pub fn exp(self) -> f64 {
315         unsafe { intrinsics::expf64(self) }
316     }
317
318     /// Returns `2^(self)`.
319     ///
320     /// ```
321     /// let f = 2.0_f64;
322     ///
323     /// // 2^2 - 4 == 0
324     /// let abs_difference = (f.exp2() - 4.0).abs();
325     ///
326     /// assert!(abs_difference < 1e-10);
327     /// ```
328     #[stable(feature = "rust1", since = "1.0.0")]
329     #[inline]
330     pub fn exp2(self) -> f64 {
331         unsafe { intrinsics::exp2f64(self) }
332     }
333
334     /// Returns the natural logarithm of the number.
335     ///
336     /// ```
337     /// let one = 1.0_f64;
338     /// // e^1
339     /// let e = one.exp();
340     ///
341     /// // ln(e) - 1 == 0
342     /// let abs_difference = (e.ln() - 1.0).abs();
343     ///
344     /// assert!(abs_difference < 1e-10);
345     /// ```
346     #[stable(feature = "rust1", since = "1.0.0")]
347     #[inline]
348     pub fn ln(self) -> f64 {
349         self.log_wrapper(|n| { unsafe { intrinsics::logf64(n) } })
350     }
351
352     /// Returns the logarithm of the number with respect to an arbitrary base.
353     ///
354     /// The result may not be correctly rounded owing to implementation details;
355     /// `self.log2()` can produce more accurate results for base 2, and
356     /// `self.log10()` can produce more accurate results for base 10.
357     ///
358     /// ```
359     /// let five = 5.0_f64;
360     ///
361     /// // log5(5) - 1 == 0
362     /// let abs_difference = (five.log(5.0) - 1.0).abs();
363     ///
364     /// assert!(abs_difference < 1e-10);
365     /// ```
366     #[stable(feature = "rust1", since = "1.0.0")]
367     #[inline]
368     pub fn log(self, base: f64) -> f64 { self.ln() / base.ln() }
369
370     /// Returns the base 2 logarithm of the number.
371     ///
372     /// ```
373     /// let two = 2.0_f64;
374     ///
375     /// // log2(2) - 1 == 0
376     /// let abs_difference = (two.log2() - 1.0).abs();
377     ///
378     /// assert!(abs_difference < 1e-10);
379     /// ```
380     #[stable(feature = "rust1", since = "1.0.0")]
381     #[inline]
382     pub fn log2(self) -> f64 {
383         self.log_wrapper(|n| {
384             #[cfg(target_os = "android")]
385             return ::sys::android::log2f64(n);
386             #[cfg(not(target_os = "android"))]
387             return unsafe { intrinsics::log2f64(n) };
388         })
389     }
390
391     /// Returns the base 10 logarithm of the number.
392     ///
393     /// ```
394     /// let ten = 10.0_f64;
395     ///
396     /// // log10(10) - 1 == 0
397     /// let abs_difference = (ten.log10() - 1.0).abs();
398     ///
399     /// assert!(abs_difference < 1e-10);
400     /// ```
401     #[stable(feature = "rust1", since = "1.0.0")]
402     #[inline]
403     pub fn log10(self) -> f64 {
404         self.log_wrapper(|n| { unsafe { intrinsics::log10f64(n) } })
405     }
406
407     /// The positive difference of two numbers.
408     ///
409     /// * If `self <= other`: `0:0`
410     /// * Else: `self - other`
411     ///
412     /// ```
413     /// let x = 3.0_f64;
414     /// let y = -3.0_f64;
415     ///
416     /// let abs_difference_x = (x.abs_sub(1.0) - 2.0).abs();
417     /// let abs_difference_y = (y.abs_sub(1.0) - 0.0).abs();
418     ///
419     /// assert!(abs_difference_x < 1e-10);
420     /// assert!(abs_difference_y < 1e-10);
421     /// ```
422     #[stable(feature = "rust1", since = "1.0.0")]
423     #[inline]
424     #[rustc_deprecated(since = "1.10.0",
425                        reason = "you probably meant `(self - other).abs()`: \
426                                  this operation is `(self - other).max(0.0)` (also \
427                                  known as `fdim` in C). If you truly need the positive \
428                                  difference, consider using that expression or the C function \
429                                  `fdim`, depending on how you wish to handle NaN (please consider \
430                                  filing an issue describing your use-case too).")]
431      pub fn abs_sub(self, other: f64) -> f64 {
432          unsafe { cmath::fdim(self, other) }
433      }
434
435     /// Takes the cubic root of a number.
436     ///
437     /// ```
438     /// let x = 8.0_f64;
439     ///
440     /// // x^(1/3) - 2 == 0
441     /// let abs_difference = (x.cbrt() - 2.0).abs();
442     ///
443     /// assert!(abs_difference < 1e-10);
444     /// ```
445     #[stable(feature = "rust1", since = "1.0.0")]
446     #[inline]
447     pub fn cbrt(self) -> f64 {
448         unsafe { cmath::cbrt(self) }
449     }
450
451     /// Calculates the length of the hypotenuse of a right-angle triangle given
452     /// legs of length `x` and `y`.
453     ///
454     /// ```
455     /// let x = 2.0_f64;
456     /// let y = 3.0_f64;
457     ///
458     /// // sqrt(x^2 + y^2)
459     /// let abs_difference = (x.hypot(y) - (x.powi(2) + y.powi(2)).sqrt()).abs();
460     ///
461     /// assert!(abs_difference < 1e-10);
462     /// ```
463     #[stable(feature = "rust1", since = "1.0.0")]
464     #[inline]
465     pub fn hypot(self, other: f64) -> f64 {
466         unsafe { cmath::hypot(self, other) }
467     }
468
469     /// Computes the sine of a number (in radians).
470     ///
471     /// ```
472     /// use std::f64;
473     ///
474     /// let x = f64::consts::PI/2.0;
475     ///
476     /// let abs_difference = (x.sin() - 1.0).abs();
477     ///
478     /// assert!(abs_difference < 1e-10);
479     /// ```
480     #[stable(feature = "rust1", since = "1.0.0")]
481     #[inline]
482     pub fn sin(self) -> f64 {
483         unsafe { intrinsics::sinf64(self) }
484     }
485
486     /// Computes the cosine of a number (in radians).
487     ///
488     /// ```
489     /// use std::f64;
490     ///
491     /// let x = 2.0*f64::consts::PI;
492     ///
493     /// let abs_difference = (x.cos() - 1.0).abs();
494     ///
495     /// assert!(abs_difference < 1e-10);
496     /// ```
497     #[stable(feature = "rust1", since = "1.0.0")]
498     #[inline]
499     pub fn cos(self) -> f64 {
500         unsafe { intrinsics::cosf64(self) }
501     }
502
503     /// Computes the tangent of a number (in radians).
504     ///
505     /// ```
506     /// use std::f64;
507     ///
508     /// let x = f64::consts::PI/4.0;
509     /// let abs_difference = (x.tan() - 1.0).abs();
510     ///
511     /// assert!(abs_difference < 1e-14);
512     /// ```
513     #[stable(feature = "rust1", since = "1.0.0")]
514     #[inline]
515     pub fn tan(self) -> f64 {
516         unsafe { cmath::tan(self) }
517     }
518
519     /// Computes the arcsine of a number. Return value is in radians in
520     /// the range [-pi/2, pi/2] or NaN if the number is outside the range
521     /// [-1, 1].
522     ///
523     /// ```
524     /// use std::f64;
525     ///
526     /// let f = f64::consts::PI / 2.0;
527     ///
528     /// // asin(sin(pi/2))
529     /// let abs_difference = (f.sin().asin() - f64::consts::PI / 2.0).abs();
530     ///
531     /// assert!(abs_difference < 1e-10);
532     /// ```
533     #[stable(feature = "rust1", since = "1.0.0")]
534     #[inline]
535     pub fn asin(self) -> f64 {
536         unsafe { cmath::asin(self) }
537     }
538
539     /// Computes the arccosine of a number. Return value is in radians in
540     /// the range [0, pi] or NaN if the number is outside the range
541     /// [-1, 1].
542     ///
543     /// ```
544     /// use std::f64;
545     ///
546     /// let f = f64::consts::PI / 4.0;
547     ///
548     /// // acos(cos(pi/4))
549     /// let abs_difference = (f.cos().acos() - f64::consts::PI / 4.0).abs();
550     ///
551     /// assert!(abs_difference < 1e-10);
552     /// ```
553     #[stable(feature = "rust1", since = "1.0.0")]
554     #[inline]
555     pub fn acos(self) -> f64 {
556         unsafe { cmath::acos(self) }
557     }
558
559     /// Computes the arctangent of a number. Return value is in radians in the
560     /// range [-pi/2, pi/2];
561     ///
562     /// ```
563     /// let f = 1.0_f64;
564     ///
565     /// // atan(tan(1))
566     /// let abs_difference = (f.tan().atan() - 1.0).abs();
567     ///
568     /// assert!(abs_difference < 1e-10);
569     /// ```
570     #[stable(feature = "rust1", since = "1.0.0")]
571     #[inline]
572     pub fn atan(self) -> f64 {
573         unsafe { cmath::atan(self) }
574     }
575
576     /// Computes the four quadrant arctangent of `self` (`y`) and `other` (`x`) in radians.
577     ///
578     /// * `x = 0`, `y = 0`: `0`
579     /// * `x >= 0`: `arctan(y/x)` -> `[-pi/2, pi/2]`
580     /// * `y >= 0`: `arctan(y/x) + pi` -> `(pi/2, pi]`
581     /// * `y < 0`: `arctan(y/x) - pi` -> `(-pi, -pi/2)`
582     ///
583     /// ```
584     /// use std::f64;
585     ///
586     /// let pi = f64::consts::PI;
587     /// // Positive angles measured counter-clockwise
588     /// // from positive x axis
589     /// // -pi/4 radians (45 deg clockwise)
590     /// let x1 = 3.0_f64;
591     /// let y1 = -3.0_f64;
592     ///
593     /// // 3pi/4 radians (135 deg counter-clockwise)
594     /// let x2 = -3.0_f64;
595     /// let y2 = 3.0_f64;
596     ///
597     /// let abs_difference_1 = (y1.atan2(x1) - (-pi/4.0)).abs();
598     /// let abs_difference_2 = (y2.atan2(x2) - 3.0*pi/4.0).abs();
599     ///
600     /// assert!(abs_difference_1 < 1e-10);
601     /// assert!(abs_difference_2 < 1e-10);
602     /// ```
603     #[stable(feature = "rust1", since = "1.0.0")]
604     #[inline]
605     pub fn atan2(self, other: f64) -> f64 {
606         unsafe { cmath::atan2(self, other) }
607     }
608
609     /// Simultaneously computes the sine and cosine of the number, `x`. Returns
610     /// `(sin(x), cos(x))`.
611     ///
612     /// ```
613     /// use std::f64;
614     ///
615     /// let x = f64::consts::PI/4.0;
616     /// let f = x.sin_cos();
617     ///
618     /// let abs_difference_0 = (f.0 - x.sin()).abs();
619     /// let abs_difference_1 = (f.1 - x.cos()).abs();
620     ///
621     /// assert!(abs_difference_0 < 1e-10);
622     /// assert!(abs_difference_1 < 1e-10);
623     /// ```
624     #[stable(feature = "rust1", since = "1.0.0")]
625     #[inline]
626     pub fn sin_cos(self) -> (f64, f64) {
627         (self.sin(), self.cos())
628     }
629
630     /// Returns `e^(self) - 1` in a way that is accurate even if the
631     /// number is close to zero.
632     ///
633     /// ```
634     /// let x = 7.0_f64;
635     ///
636     /// // e^(ln(7)) - 1
637     /// let abs_difference = (x.ln().exp_m1() - 6.0).abs();
638     ///
639     /// assert!(abs_difference < 1e-10);
640     /// ```
641     #[stable(feature = "rust1", since = "1.0.0")]
642     #[inline]
643     pub fn exp_m1(self) -> f64 {
644         unsafe { cmath::expm1(self) }
645     }
646
647     /// Returns `ln(1+n)` (natural logarithm) more accurately than if
648     /// the operations were performed separately.
649     ///
650     /// ```
651     /// use std::f64;
652     ///
653     /// let x = f64::consts::E - 1.0;
654     ///
655     /// // ln(1 + (e - 1)) == ln(e) == 1
656     /// let abs_difference = (x.ln_1p() - 1.0).abs();
657     ///
658     /// assert!(abs_difference < 1e-10);
659     /// ```
660     #[stable(feature = "rust1", since = "1.0.0")]
661     #[inline]
662     pub fn ln_1p(self) -> f64 {
663         unsafe { cmath::log1p(self) }
664     }
665
666     /// Hyperbolic sine function.
667     ///
668     /// ```
669     /// use std::f64;
670     ///
671     /// let e = f64::consts::E;
672     /// let x = 1.0_f64;
673     ///
674     /// let f = x.sinh();
675     /// // Solving sinh() at 1 gives `(e^2-1)/(2e)`
676     /// let g = (e*e - 1.0)/(2.0*e);
677     /// let abs_difference = (f - g).abs();
678     ///
679     /// assert!(abs_difference < 1e-10);
680     /// ```
681     #[stable(feature = "rust1", since = "1.0.0")]
682     #[inline]
683     pub fn sinh(self) -> f64 {
684         unsafe { cmath::sinh(self) }
685     }
686
687     /// Hyperbolic cosine function.
688     ///
689     /// ```
690     /// use std::f64;
691     ///
692     /// let e = f64::consts::E;
693     /// let x = 1.0_f64;
694     /// let f = x.cosh();
695     /// // Solving cosh() at 1 gives this result
696     /// let g = (e*e + 1.0)/(2.0*e);
697     /// let abs_difference = (f - g).abs();
698     ///
699     /// // Same result
700     /// assert!(abs_difference < 1.0e-10);
701     /// ```
702     #[stable(feature = "rust1", since = "1.0.0")]
703     #[inline]
704     pub fn cosh(self) -> f64 {
705         unsafe { cmath::cosh(self) }
706     }
707
708     /// Hyperbolic tangent function.
709     ///
710     /// ```
711     /// use std::f64;
712     ///
713     /// let e = f64::consts::E;
714     /// let x = 1.0_f64;
715     ///
716     /// let f = x.tanh();
717     /// // Solving tanh() at 1 gives `(1 - e^(-2))/(1 + e^(-2))`
718     /// let g = (1.0 - e.powi(-2))/(1.0 + e.powi(-2));
719     /// let abs_difference = (f - g).abs();
720     ///
721     /// assert!(abs_difference < 1.0e-10);
722     /// ```
723     #[stable(feature = "rust1", since = "1.0.0")]
724     #[inline]
725     pub fn tanh(self) -> f64 {
726         unsafe { cmath::tanh(self) }
727     }
728
729     /// Inverse hyperbolic sine function.
730     ///
731     /// ```
732     /// let x = 1.0_f64;
733     /// let f = x.sinh().asinh();
734     ///
735     /// let abs_difference = (f - x).abs();
736     ///
737     /// assert!(abs_difference < 1.0e-10);
738     /// ```
739     #[stable(feature = "rust1", since = "1.0.0")]
740     #[inline]
741     pub fn asinh(self) -> f64 {
742         if self == NEG_INFINITY {
743             NEG_INFINITY
744         } else {
745             (self + ((self * self) + 1.0).sqrt()).ln()
746         }
747     }
748
749     /// Inverse hyperbolic cosine function.
750     ///
751     /// ```
752     /// let x = 1.0_f64;
753     /// let f = x.cosh().acosh();
754     ///
755     /// let abs_difference = (f - x).abs();
756     ///
757     /// assert!(abs_difference < 1.0e-10);
758     /// ```
759     #[stable(feature = "rust1", since = "1.0.0")]
760     #[inline]
761     pub fn acosh(self) -> f64 {
762         match self {
763             x if x < 1.0 => NAN,
764             x => (x + ((x * x) - 1.0).sqrt()).ln(),
765         }
766     }
767
768     /// Inverse hyperbolic tangent function.
769     ///
770     /// ```
771     /// use std::f64;
772     ///
773     /// let e = f64::consts::E;
774     /// let f = e.tanh().atanh();
775     ///
776     /// let abs_difference = (f - e).abs();
777     ///
778     /// assert!(abs_difference < 1.0e-10);
779     /// ```
780     #[stable(feature = "rust1", since = "1.0.0")]
781     #[inline]
782     pub fn atanh(self) -> f64 {
783         0.5 * ((2.0 * self) / (1.0 - self)).ln_1p()
784     }
785
786     // Solaris/Illumos requires a wrapper around log, log2, and log10 functions
787     // because of their non-standard behavior (e.g. log(-n) returns -Inf instead
788     // of expected NaN).
789     fn log_wrapper<F: Fn(f64) -> f64>(self, log_fn: F) -> f64 {
790         if !cfg!(target_os = "solaris") {
791             log_fn(self)
792         } else {
793             if self.is_finite() {
794                 if self > 0.0 {
795                     log_fn(self)
796                 } else if self == 0.0 {
797                     NEG_INFINITY // log(0) = -Inf
798                 } else {
799                     NAN // log(-n) = NaN
800                 }
801             } else if self.is_nan() {
802                 self // log(NaN) = NaN
803             } else if self > 0.0 {
804                 self // log(Inf) = Inf
805             } else {
806                 NAN // log(-Inf) = NaN
807             }
808         }
809     }
810 }
811
812 #[cfg(test)]
813 mod tests {
814     use f64;
815     use f64::*;
816     use num::*;
817     use num::FpCategory as Fp;
818
819     #[test]
820     fn test_num_f64() {
821         test_num(10f64, 2f64);
822     }
823
824     #[test]
825     fn test_min_nan() {
826         assert_eq!(NAN.min(2.0), 2.0);
827         assert_eq!(2.0f64.min(NAN), 2.0);
828     }
829
830     #[test]
831     fn test_max_nan() {
832         assert_eq!(NAN.max(2.0), 2.0);
833         assert_eq!(2.0f64.max(NAN), 2.0);
834     }
835
836     #[test]
837     fn test_nan() {
838         let nan: f64 = NAN;
839         assert!(nan.is_nan());
840         assert!(!nan.is_infinite());
841         assert!(!nan.is_finite());
842         assert!(!nan.is_normal());
843         assert!(nan.is_sign_positive());
844         assert!(!nan.is_sign_negative());
845         assert_eq!(Fp::Nan, nan.classify());
846     }
847
848     #[test]
849     fn test_infinity() {
850         let inf: f64 = INFINITY;
851         assert!(inf.is_infinite());
852         assert!(!inf.is_finite());
853         assert!(inf.is_sign_positive());
854         assert!(!inf.is_sign_negative());
855         assert!(!inf.is_nan());
856         assert!(!inf.is_normal());
857         assert_eq!(Fp::Infinite, inf.classify());
858     }
859
860     #[test]
861     fn test_neg_infinity() {
862         let neg_inf: f64 = NEG_INFINITY;
863         assert!(neg_inf.is_infinite());
864         assert!(!neg_inf.is_finite());
865         assert!(!neg_inf.is_sign_positive());
866         assert!(neg_inf.is_sign_negative());
867         assert!(!neg_inf.is_nan());
868         assert!(!neg_inf.is_normal());
869         assert_eq!(Fp::Infinite, neg_inf.classify());
870     }
871
872     #[test]
873     fn test_zero() {
874         let zero: f64 = 0.0f64;
875         assert_eq!(0.0, zero);
876         assert!(!zero.is_infinite());
877         assert!(zero.is_finite());
878         assert!(zero.is_sign_positive());
879         assert!(!zero.is_sign_negative());
880         assert!(!zero.is_nan());
881         assert!(!zero.is_normal());
882         assert_eq!(Fp::Zero, zero.classify());
883     }
884
885     #[test]
886     fn test_neg_zero() {
887         let neg_zero: f64 = -0.0;
888         assert_eq!(0.0, neg_zero);
889         assert!(!neg_zero.is_infinite());
890         assert!(neg_zero.is_finite());
891         assert!(!neg_zero.is_sign_positive());
892         assert!(neg_zero.is_sign_negative());
893         assert!(!neg_zero.is_nan());
894         assert!(!neg_zero.is_normal());
895         assert_eq!(Fp::Zero, neg_zero.classify());
896     }
897
898     #[cfg_attr(all(target_arch = "wasm32", target_os = "emscripten"), ignore)] // issue 42630
899     #[test]
900     fn test_one() {
901         let one: f64 = 1.0f64;
902         assert_eq!(1.0, one);
903         assert!(!one.is_infinite());
904         assert!(one.is_finite());
905         assert!(one.is_sign_positive());
906         assert!(!one.is_sign_negative());
907         assert!(!one.is_nan());
908         assert!(one.is_normal());
909         assert_eq!(Fp::Normal, one.classify());
910     }
911
912     #[test]
913     fn test_is_nan() {
914         let nan: f64 = NAN;
915         let inf: f64 = INFINITY;
916         let neg_inf: f64 = NEG_INFINITY;
917         assert!(nan.is_nan());
918         assert!(!0.0f64.is_nan());
919         assert!(!5.3f64.is_nan());
920         assert!(!(-10.732f64).is_nan());
921         assert!(!inf.is_nan());
922         assert!(!neg_inf.is_nan());
923     }
924
925     #[test]
926     fn test_is_infinite() {
927         let nan: f64 = NAN;
928         let inf: f64 = INFINITY;
929         let neg_inf: f64 = NEG_INFINITY;
930         assert!(!nan.is_infinite());
931         assert!(inf.is_infinite());
932         assert!(neg_inf.is_infinite());
933         assert!(!0.0f64.is_infinite());
934         assert!(!42.8f64.is_infinite());
935         assert!(!(-109.2f64).is_infinite());
936     }
937
938     #[test]
939     fn test_is_finite() {
940         let nan: f64 = NAN;
941         let inf: f64 = INFINITY;
942         let neg_inf: f64 = NEG_INFINITY;
943         assert!(!nan.is_finite());
944         assert!(!inf.is_finite());
945         assert!(!neg_inf.is_finite());
946         assert!(0.0f64.is_finite());
947         assert!(42.8f64.is_finite());
948         assert!((-109.2f64).is_finite());
949     }
950
951     #[cfg_attr(all(target_arch = "wasm32", target_os = "emscripten"), ignore)] // issue 42630
952     #[test]
953     fn test_is_normal() {
954         let nan: f64 = NAN;
955         let inf: f64 = INFINITY;
956         let neg_inf: f64 = NEG_INFINITY;
957         let zero: f64 = 0.0f64;
958         let neg_zero: f64 = -0.0;
959         assert!(!nan.is_normal());
960         assert!(!inf.is_normal());
961         assert!(!neg_inf.is_normal());
962         assert!(!zero.is_normal());
963         assert!(!neg_zero.is_normal());
964         assert!(1f64.is_normal());
965         assert!(1e-307f64.is_normal());
966         assert!(!1e-308f64.is_normal());
967     }
968
969     #[cfg_attr(all(target_arch = "wasm32", target_os = "emscripten"), ignore)] // issue 42630
970     #[test]
971     fn test_classify() {
972         let nan: f64 = NAN;
973         let inf: f64 = INFINITY;
974         let neg_inf: f64 = NEG_INFINITY;
975         let zero: f64 = 0.0f64;
976         let neg_zero: f64 = -0.0;
977         assert_eq!(nan.classify(), Fp::Nan);
978         assert_eq!(inf.classify(), Fp::Infinite);
979         assert_eq!(neg_inf.classify(), Fp::Infinite);
980         assert_eq!(zero.classify(), Fp::Zero);
981         assert_eq!(neg_zero.classify(), Fp::Zero);
982         assert_eq!(1e-307f64.classify(), Fp::Normal);
983         assert_eq!(1e-308f64.classify(), Fp::Subnormal);
984     }
985
986     #[test]
987     fn test_floor() {
988         assert_approx_eq!(1.0f64.floor(), 1.0f64);
989         assert_approx_eq!(1.3f64.floor(), 1.0f64);
990         assert_approx_eq!(1.5f64.floor(), 1.0f64);
991         assert_approx_eq!(1.7f64.floor(), 1.0f64);
992         assert_approx_eq!(0.0f64.floor(), 0.0f64);
993         assert_approx_eq!((-0.0f64).floor(), -0.0f64);
994         assert_approx_eq!((-1.0f64).floor(), -1.0f64);
995         assert_approx_eq!((-1.3f64).floor(), -2.0f64);
996         assert_approx_eq!((-1.5f64).floor(), -2.0f64);
997         assert_approx_eq!((-1.7f64).floor(), -2.0f64);
998     }
999
1000     #[test]
1001     fn test_ceil() {
1002         assert_approx_eq!(1.0f64.ceil(), 1.0f64);
1003         assert_approx_eq!(1.3f64.ceil(), 2.0f64);
1004         assert_approx_eq!(1.5f64.ceil(), 2.0f64);
1005         assert_approx_eq!(1.7f64.ceil(), 2.0f64);
1006         assert_approx_eq!(0.0f64.ceil(), 0.0f64);
1007         assert_approx_eq!((-0.0f64).ceil(), -0.0f64);
1008         assert_approx_eq!((-1.0f64).ceil(), -1.0f64);
1009         assert_approx_eq!((-1.3f64).ceil(), -1.0f64);
1010         assert_approx_eq!((-1.5f64).ceil(), -1.0f64);
1011         assert_approx_eq!((-1.7f64).ceil(), -1.0f64);
1012     }
1013
1014     #[test]
1015     fn test_round() {
1016         assert_approx_eq!(1.0f64.round(), 1.0f64);
1017         assert_approx_eq!(1.3f64.round(), 1.0f64);
1018         assert_approx_eq!(1.5f64.round(), 2.0f64);
1019         assert_approx_eq!(1.7f64.round(), 2.0f64);
1020         assert_approx_eq!(0.0f64.round(), 0.0f64);
1021         assert_approx_eq!((-0.0f64).round(), -0.0f64);
1022         assert_approx_eq!((-1.0f64).round(), -1.0f64);
1023         assert_approx_eq!((-1.3f64).round(), -1.0f64);
1024         assert_approx_eq!((-1.5f64).round(), -2.0f64);
1025         assert_approx_eq!((-1.7f64).round(), -2.0f64);
1026     }
1027
1028     #[test]
1029     fn test_trunc() {
1030         assert_approx_eq!(1.0f64.trunc(), 1.0f64);
1031         assert_approx_eq!(1.3f64.trunc(), 1.0f64);
1032         assert_approx_eq!(1.5f64.trunc(), 1.0f64);
1033         assert_approx_eq!(1.7f64.trunc(), 1.0f64);
1034         assert_approx_eq!(0.0f64.trunc(), 0.0f64);
1035         assert_approx_eq!((-0.0f64).trunc(), -0.0f64);
1036         assert_approx_eq!((-1.0f64).trunc(), -1.0f64);
1037         assert_approx_eq!((-1.3f64).trunc(), -1.0f64);
1038         assert_approx_eq!((-1.5f64).trunc(), -1.0f64);
1039         assert_approx_eq!((-1.7f64).trunc(), -1.0f64);
1040     }
1041
1042     #[test]
1043     fn test_fract() {
1044         assert_approx_eq!(1.0f64.fract(), 0.0f64);
1045         assert_approx_eq!(1.3f64.fract(), 0.3f64);
1046         assert_approx_eq!(1.5f64.fract(), 0.5f64);
1047         assert_approx_eq!(1.7f64.fract(), 0.7f64);
1048         assert_approx_eq!(0.0f64.fract(), 0.0f64);
1049         assert_approx_eq!((-0.0f64).fract(), -0.0f64);
1050         assert_approx_eq!((-1.0f64).fract(), -0.0f64);
1051         assert_approx_eq!((-1.3f64).fract(), -0.3f64);
1052         assert_approx_eq!((-1.5f64).fract(), -0.5f64);
1053         assert_approx_eq!((-1.7f64).fract(), -0.7f64);
1054     }
1055
1056     #[test]
1057     fn test_abs() {
1058         assert_eq!(INFINITY.abs(), INFINITY);
1059         assert_eq!(1f64.abs(), 1f64);
1060         assert_eq!(0f64.abs(), 0f64);
1061         assert_eq!((-0f64).abs(), 0f64);
1062         assert_eq!((-1f64).abs(), 1f64);
1063         assert_eq!(NEG_INFINITY.abs(), INFINITY);
1064         assert_eq!((1f64/NEG_INFINITY).abs(), 0f64);
1065         assert!(NAN.abs().is_nan());
1066     }
1067
1068     #[test]
1069     fn test_signum() {
1070         assert_eq!(INFINITY.signum(), 1f64);
1071         assert_eq!(1f64.signum(), 1f64);
1072         assert_eq!(0f64.signum(), 1f64);
1073         assert_eq!((-0f64).signum(), -1f64);
1074         assert_eq!((-1f64).signum(), -1f64);
1075         assert_eq!(NEG_INFINITY.signum(), -1f64);
1076         assert_eq!((1f64/NEG_INFINITY).signum(), -1f64);
1077         assert!(NAN.signum().is_nan());
1078     }
1079
1080     #[test]
1081     fn test_is_sign_positive() {
1082         assert!(INFINITY.is_sign_positive());
1083         assert!(1f64.is_sign_positive());
1084         assert!(0f64.is_sign_positive());
1085         assert!(!(-0f64).is_sign_positive());
1086         assert!(!(-1f64).is_sign_positive());
1087         assert!(!NEG_INFINITY.is_sign_positive());
1088         assert!(!(1f64/NEG_INFINITY).is_sign_positive());
1089         assert!(NAN.is_sign_positive());
1090         assert!(!(-NAN).is_sign_positive());
1091     }
1092
1093     #[test]
1094     fn test_is_sign_negative() {
1095         assert!(!INFINITY.is_sign_negative());
1096         assert!(!1f64.is_sign_negative());
1097         assert!(!0f64.is_sign_negative());
1098         assert!((-0f64).is_sign_negative());
1099         assert!((-1f64).is_sign_negative());
1100         assert!(NEG_INFINITY.is_sign_negative());
1101         assert!((1f64/NEG_INFINITY).is_sign_negative());
1102         assert!(!NAN.is_sign_negative());
1103         assert!((-NAN).is_sign_negative());
1104     }
1105
1106     #[test]
1107     fn test_mul_add() {
1108         let nan: f64 = NAN;
1109         let inf: f64 = INFINITY;
1110         let neg_inf: f64 = NEG_INFINITY;
1111         assert_approx_eq!(12.3f64.mul_add(4.5, 6.7), 62.05);
1112         assert_approx_eq!((-12.3f64).mul_add(-4.5, -6.7), 48.65);
1113         assert_approx_eq!(0.0f64.mul_add(8.9, 1.2), 1.2);
1114         assert_approx_eq!(3.4f64.mul_add(-0.0, 5.6), 5.6);
1115         assert!(nan.mul_add(7.8, 9.0).is_nan());
1116         assert_eq!(inf.mul_add(7.8, 9.0), inf);
1117         assert_eq!(neg_inf.mul_add(7.8, 9.0), neg_inf);
1118         assert_eq!(8.9f64.mul_add(inf, 3.2), inf);
1119         assert_eq!((-3.2f64).mul_add(2.4, neg_inf), neg_inf);
1120     }
1121
1122     #[test]
1123     fn test_recip() {
1124         let nan: f64 = NAN;
1125         let inf: f64 = INFINITY;
1126         let neg_inf: f64 = NEG_INFINITY;
1127         assert_eq!(1.0f64.recip(), 1.0);
1128         assert_eq!(2.0f64.recip(), 0.5);
1129         assert_eq!((-0.4f64).recip(), -2.5);
1130         assert_eq!(0.0f64.recip(), inf);
1131         assert!(nan.recip().is_nan());
1132         assert_eq!(inf.recip(), 0.0);
1133         assert_eq!(neg_inf.recip(), 0.0);
1134     }
1135
1136     #[test]
1137     fn test_powi() {
1138         let nan: f64 = NAN;
1139         let inf: f64 = INFINITY;
1140         let neg_inf: f64 = NEG_INFINITY;
1141         assert_eq!(1.0f64.powi(1), 1.0);
1142         assert_approx_eq!((-3.1f64).powi(2), 9.61);
1143         assert_approx_eq!(5.9f64.powi(-2), 0.028727);
1144         assert_eq!(8.3f64.powi(0), 1.0);
1145         assert!(nan.powi(2).is_nan());
1146         assert_eq!(inf.powi(3), inf);
1147         assert_eq!(neg_inf.powi(2), inf);
1148     }
1149
1150     #[test]
1151     fn test_powf() {
1152         let nan: f64 = NAN;
1153         let inf: f64 = INFINITY;
1154         let neg_inf: f64 = NEG_INFINITY;
1155         assert_eq!(1.0f64.powf(1.0), 1.0);
1156         assert_approx_eq!(3.4f64.powf(4.5), 246.408183);
1157         assert_approx_eq!(2.7f64.powf(-3.2), 0.041652);
1158         assert_approx_eq!((-3.1f64).powf(2.0), 9.61);
1159         assert_approx_eq!(5.9f64.powf(-2.0), 0.028727);
1160         assert_eq!(8.3f64.powf(0.0), 1.0);
1161         assert!(nan.powf(2.0).is_nan());
1162         assert_eq!(inf.powf(2.0), inf);
1163         assert_eq!(neg_inf.powf(3.0), neg_inf);
1164     }
1165
1166     #[test]
1167     fn test_sqrt_domain() {
1168         assert!(NAN.sqrt().is_nan());
1169         assert!(NEG_INFINITY.sqrt().is_nan());
1170         assert!((-1.0f64).sqrt().is_nan());
1171         assert_eq!((-0.0f64).sqrt(), -0.0);
1172         assert_eq!(0.0f64.sqrt(), 0.0);
1173         assert_eq!(1.0f64.sqrt(), 1.0);
1174         assert_eq!(INFINITY.sqrt(), INFINITY);
1175     }
1176
1177     #[test]
1178     fn test_exp() {
1179         assert_eq!(1.0, 0.0f64.exp());
1180         assert_approx_eq!(2.718282, 1.0f64.exp());
1181         assert_approx_eq!(148.413159, 5.0f64.exp());
1182
1183         let inf: f64 = INFINITY;
1184         let neg_inf: f64 = NEG_INFINITY;
1185         let nan: f64 = NAN;
1186         assert_eq!(inf, inf.exp());
1187         assert_eq!(0.0, neg_inf.exp());
1188         assert!(nan.exp().is_nan());
1189     }
1190
1191     #[test]
1192     fn test_exp2() {
1193         assert_eq!(32.0, 5.0f64.exp2());
1194         assert_eq!(1.0, 0.0f64.exp2());
1195
1196         let inf: f64 = INFINITY;
1197         let neg_inf: f64 = NEG_INFINITY;
1198         let nan: f64 = NAN;
1199         assert_eq!(inf, inf.exp2());
1200         assert_eq!(0.0, neg_inf.exp2());
1201         assert!(nan.exp2().is_nan());
1202     }
1203
1204     #[test]
1205     fn test_ln() {
1206         let nan: f64 = NAN;
1207         let inf: f64 = INFINITY;
1208         let neg_inf: f64 = NEG_INFINITY;
1209         assert_approx_eq!(1.0f64.exp().ln(), 1.0);
1210         assert!(nan.ln().is_nan());
1211         assert_eq!(inf.ln(), inf);
1212         assert!(neg_inf.ln().is_nan());
1213         assert!((-2.3f64).ln().is_nan());
1214         assert_eq!((-0.0f64).ln(), neg_inf);
1215         assert_eq!(0.0f64.ln(), neg_inf);
1216         assert_approx_eq!(4.0f64.ln(), 1.386294);
1217     }
1218
1219     #[test]
1220     fn test_log() {
1221         let nan: f64 = NAN;
1222         let inf: f64 = INFINITY;
1223         let neg_inf: f64 = NEG_INFINITY;
1224         assert_eq!(10.0f64.log(10.0), 1.0);
1225         assert_approx_eq!(2.3f64.log(3.5), 0.664858);
1226         assert_eq!(1.0f64.exp().log(1.0f64.exp()), 1.0);
1227         assert!(1.0f64.log(1.0).is_nan());
1228         assert!(1.0f64.log(-13.9).is_nan());
1229         assert!(nan.log(2.3).is_nan());
1230         assert_eq!(inf.log(10.0), inf);
1231         assert!(neg_inf.log(8.8).is_nan());
1232         assert!((-2.3f64).log(0.1).is_nan());
1233         assert_eq!((-0.0f64).log(2.0), neg_inf);
1234         assert_eq!(0.0f64.log(7.0), neg_inf);
1235     }
1236
1237     #[test]
1238     fn test_log2() {
1239         let nan: f64 = NAN;
1240         let inf: f64 = INFINITY;
1241         let neg_inf: f64 = NEG_INFINITY;
1242         assert_approx_eq!(10.0f64.log2(), 3.321928);
1243         assert_approx_eq!(2.3f64.log2(), 1.201634);
1244         assert_approx_eq!(1.0f64.exp().log2(), 1.442695);
1245         assert!(nan.log2().is_nan());
1246         assert_eq!(inf.log2(), inf);
1247         assert!(neg_inf.log2().is_nan());
1248         assert!((-2.3f64).log2().is_nan());
1249         assert_eq!((-0.0f64).log2(), neg_inf);
1250         assert_eq!(0.0f64.log2(), neg_inf);
1251     }
1252
1253     #[test]
1254     fn test_log10() {
1255         let nan: f64 = NAN;
1256         let inf: f64 = INFINITY;
1257         let neg_inf: f64 = NEG_INFINITY;
1258         assert_eq!(10.0f64.log10(), 1.0);
1259         assert_approx_eq!(2.3f64.log10(), 0.361728);
1260         assert_approx_eq!(1.0f64.exp().log10(), 0.434294);
1261         assert_eq!(1.0f64.log10(), 0.0);
1262         assert!(nan.log10().is_nan());
1263         assert_eq!(inf.log10(), inf);
1264         assert!(neg_inf.log10().is_nan());
1265         assert!((-2.3f64).log10().is_nan());
1266         assert_eq!((-0.0f64).log10(), neg_inf);
1267         assert_eq!(0.0f64.log10(), neg_inf);
1268     }
1269
1270     #[test]
1271     fn test_to_degrees() {
1272         let pi: f64 = consts::PI;
1273         let nan: f64 = NAN;
1274         let inf: f64 = INFINITY;
1275         let neg_inf: f64 = NEG_INFINITY;
1276         assert_eq!(0.0f64.to_degrees(), 0.0);
1277         assert_approx_eq!((-5.8f64).to_degrees(), -332.315521);
1278         assert_eq!(pi.to_degrees(), 180.0);
1279         assert!(nan.to_degrees().is_nan());
1280         assert_eq!(inf.to_degrees(), inf);
1281         assert_eq!(neg_inf.to_degrees(), neg_inf);
1282     }
1283
1284     #[test]
1285     fn test_to_radians() {
1286         let pi: f64 = consts::PI;
1287         let nan: f64 = NAN;
1288         let inf: f64 = INFINITY;
1289         let neg_inf: f64 = NEG_INFINITY;
1290         assert_eq!(0.0f64.to_radians(), 0.0);
1291         assert_approx_eq!(154.6f64.to_radians(), 2.698279);
1292         assert_approx_eq!((-332.31f64).to_radians(), -5.799903);
1293         assert_eq!(180.0f64.to_radians(), pi);
1294         assert!(nan.to_radians().is_nan());
1295         assert_eq!(inf.to_radians(), inf);
1296         assert_eq!(neg_inf.to_radians(), neg_inf);
1297     }
1298
1299     #[test]
1300     fn test_asinh() {
1301         assert_eq!(0.0f64.asinh(), 0.0f64);
1302         assert_eq!((-0.0f64).asinh(), -0.0f64);
1303
1304         let inf: f64 = INFINITY;
1305         let neg_inf: f64 = NEG_INFINITY;
1306         let nan: f64 = NAN;
1307         assert_eq!(inf.asinh(), inf);
1308         assert_eq!(neg_inf.asinh(), neg_inf);
1309         assert!(nan.asinh().is_nan());
1310         assert_approx_eq!(2.0f64.asinh(), 1.443635475178810342493276740273105f64);
1311         assert_approx_eq!((-2.0f64).asinh(), -1.443635475178810342493276740273105f64);
1312     }
1313
1314     #[test]
1315     fn test_acosh() {
1316         assert_eq!(1.0f64.acosh(), 0.0f64);
1317         assert!(0.999f64.acosh().is_nan());
1318
1319         let inf: f64 = INFINITY;
1320         let neg_inf: f64 = NEG_INFINITY;
1321         let nan: f64 = NAN;
1322         assert_eq!(inf.acosh(), inf);
1323         assert!(neg_inf.acosh().is_nan());
1324         assert!(nan.acosh().is_nan());
1325         assert_approx_eq!(2.0f64.acosh(), 1.31695789692481670862504634730796844f64);
1326         assert_approx_eq!(3.0f64.acosh(), 1.76274717403908605046521864995958461f64);
1327     }
1328
1329     #[test]
1330     fn test_atanh() {
1331         assert_eq!(0.0f64.atanh(), 0.0f64);
1332         assert_eq!((-0.0f64).atanh(), -0.0f64);
1333
1334         let inf: f64 = INFINITY;
1335         let neg_inf: f64 = NEG_INFINITY;
1336         let nan: f64 = NAN;
1337         assert_eq!(1.0f64.atanh(), inf);
1338         assert_eq!((-1.0f64).atanh(), neg_inf);
1339         assert!(2f64.atanh().atanh().is_nan());
1340         assert!((-2f64).atanh().atanh().is_nan());
1341         assert!(inf.atanh().is_nan());
1342         assert!(neg_inf.atanh().is_nan());
1343         assert!(nan.atanh().is_nan());
1344         assert_approx_eq!(0.5f64.atanh(), 0.54930614433405484569762261846126285f64);
1345         assert_approx_eq!((-0.5f64).atanh(), -0.54930614433405484569762261846126285f64);
1346     }
1347
1348     #[test]
1349     fn test_real_consts() {
1350         use super::consts;
1351         let pi: f64 = consts::PI;
1352         let frac_pi_2: f64 = consts::FRAC_PI_2;
1353         let frac_pi_3: f64 = consts::FRAC_PI_3;
1354         let frac_pi_4: f64 = consts::FRAC_PI_4;
1355         let frac_pi_6: f64 = consts::FRAC_PI_6;
1356         let frac_pi_8: f64 = consts::FRAC_PI_8;
1357         let frac_1_pi: f64 = consts::FRAC_1_PI;
1358         let frac_2_pi: f64 = consts::FRAC_2_PI;
1359         let frac_2_sqrtpi: f64 = consts::FRAC_2_SQRT_PI;
1360         let sqrt2: f64 = consts::SQRT_2;
1361         let frac_1_sqrt2: f64 = consts::FRAC_1_SQRT_2;
1362         let e: f64 = consts::E;
1363         let log2_e: f64 = consts::LOG2_E;
1364         let log10_e: f64 = consts::LOG10_E;
1365         let ln_2: f64 = consts::LN_2;
1366         let ln_10: f64 = consts::LN_10;
1367
1368         assert_approx_eq!(frac_pi_2, pi / 2f64);
1369         assert_approx_eq!(frac_pi_3, pi / 3f64);
1370         assert_approx_eq!(frac_pi_4, pi / 4f64);
1371         assert_approx_eq!(frac_pi_6, pi / 6f64);
1372         assert_approx_eq!(frac_pi_8, pi / 8f64);
1373         assert_approx_eq!(frac_1_pi, 1f64 / pi);
1374         assert_approx_eq!(frac_2_pi, 2f64 / pi);
1375         assert_approx_eq!(frac_2_sqrtpi, 2f64 / pi.sqrt());
1376         assert_approx_eq!(sqrt2, 2f64.sqrt());
1377         assert_approx_eq!(frac_1_sqrt2, 1f64 / 2f64.sqrt());
1378         assert_approx_eq!(log2_e, e.log2());
1379         assert_approx_eq!(log10_e, e.log10());
1380         assert_approx_eq!(ln_2, 2f64.ln());
1381         assert_approx_eq!(ln_10, 10f64.ln());
1382     }
1383
1384     #[test]
1385     fn test_float_bits_conv() {
1386         assert_eq!((1f64).to_bits(), 0x3ff0000000000000);
1387         assert_eq!((12.5f64).to_bits(), 0x4029000000000000);
1388         assert_eq!((1337f64).to_bits(), 0x4094e40000000000);
1389         assert_eq!((-14.25f64).to_bits(), 0xc02c800000000000);
1390         assert_approx_eq!(f64::from_bits(0x3ff0000000000000), 1.0);
1391         assert_approx_eq!(f64::from_bits(0x4029000000000000), 12.5);
1392         assert_approx_eq!(f64::from_bits(0x4094e40000000000), 1337.0);
1393         assert_approx_eq!(f64::from_bits(0xc02c800000000000), -14.25);
1394
1395         // Check that NaNs roundtrip their bits regardless of signalingness
1396         // 0xA is 0b1010; 0x5 is 0b0101 -- so these two together clobbers all the mantissa bits
1397         let masked_nan1 = f64::NAN.to_bits() ^ 0x000A_AAAA_AAAA_AAAA;
1398         let masked_nan2 = f64::NAN.to_bits() ^ 0x0005_5555_5555_5555;
1399         assert!(f64::from_bits(masked_nan1).is_nan());
1400         assert!(f64::from_bits(masked_nan2).is_nan());
1401
1402         assert_eq!(f64::from_bits(masked_nan1).to_bits(), masked_nan1);
1403         assert_eq!(f64::from_bits(masked_nan2).to_bits(), masked_nan2);
1404     }
1405 }