(index<- ) ./libstd/num/f64.rs
git branch: * master 5200215 auto merge of #14035 : alexcrichton/rust/experimental, r=huonw
modified: Fri May 9 13:02:28 2014
1 // Copyright 2012-2014 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 //! Operations and constants for 64-bits floats (`f64` type)
12
13 #![allow(missing_doc)]
14
15 use prelude::*;
16
17 use cast;
18 use from_str::FromStr;
19 use libc::{c_int};
20 use num::{FPCategory, FPNaN, FPInfinite , FPZero, FPSubnormal, FPNormal};
21 use num::{strconv};
22 use num;
23 use intrinsics;
24
25 pub use core::f64::{RADIX, MANTISSA_DIGITS, DIGITS, EPSILON, MIN_VALUE};
26 pub use core::f64::{MIN_POS_VALUE, MAX_VALUE, MIN_EXP, MAX_EXP, MIN_10_EXP};
27 pub use core::f64::{MAX_10_EXP, NAN, INFINITY, NEG_INFINITY};
28 pub use core::f64::consts;
29
30 #[allow(dead_code)]
31 mod cmath {
32 use libc::{c_double, c_int};
33
34 #[link_name = "m"]
35 extern {
36 pub fn acos(n: c_double) -> c_double;
37 pub fn asin(n: c_double) -> c_double;
38 pub fn atan(n: c_double) -> c_double;
39 pub fn atan2(a: c_double, b: c_double) -> c_double;
40 pub fn cbrt(n: c_double) -> c_double;
41 pub fn cosh(n: c_double) -> c_double;
42 pub fn erf(n: c_double) -> c_double;
43 pub fn erfc(n: c_double) -> c_double;
44 pub fn expm1(n: c_double) -> c_double;
45 pub fn fdim(a: c_double, b: c_double) -> c_double;
46 pub fn fmax(a: c_double, b: c_double) -> c_double;
47 pub fn fmin(a: c_double, b: c_double) -> c_double;
48 pub fn fmod(a: c_double, b: c_double) -> c_double;
49 pub fn nextafter(x: c_double, y: c_double) -> c_double;
50 pub fn frexp(n: c_double, value: &mut c_int) -> c_double;
51 pub fn hypot(x: c_double, y: c_double) -> c_double;
52 pub fn ldexp(x: c_double, n: c_int) -> c_double;
53 pub fn logb(n: c_double) -> c_double;
54 pub fn log1p(n: c_double) -> c_double;
55 pub fn ilogb(n: c_double) -> c_int;
56 pub fn modf(n: c_double, iptr: &mut c_double) -> c_double;
57 pub fn sinh(n: c_double) -> c_double;
58 pub fn tan(n: c_double) -> c_double;
59 pub fn tanh(n: c_double) -> c_double;
60 pub fn tgamma(n: c_double) -> c_double;
61
62 // These are commonly only available for doubles
63
64 pub fn j0(n: c_double) -> c_double;
65 pub fn j1(n: c_double) -> c_double;
66 pub fn jn(i: c_int, n: c_double) -> c_double;
67
68 pub fn y0(n: c_double) -> c_double;
69 pub fn y1(n: c_double) -> c_double;
70 pub fn yn(i: c_int, n: c_double) -> c_double;
71
72 #[cfg(unix)]
73 pub fn lgamma_r(n: c_double, sign: &mut c_int) -> c_double;
74 #[cfg(windows)]
75 #[link_name="__lgamma_r"]
76 pub fn lgamma_r(n: c_double, sign: &mut c_int) -> c_double;
77 }
78 }
79
80 impl Float for f64 {
81 #[inline]
82 fn nan() -> f64 { NAN }
83
84 #[inline]
85 fn infinity() -> f64 { INFINITY }
86
87 #[inline]
88 fn neg_infinity() -> f64 { NEG_INFINITY }
89
90 #[inline]
91 fn neg_zero() -> f64 { -0.0 }
92
93 /// Returns `true` if the number is NaN
94 #[inline]
95 fn is_nan(self) -> bool { self != self }
96
97 /// Returns `true` if the number is infinite
98 #[inline]
99 fn is_infinite(self) -> bool {
100 self == Float::infinity() || self == Float::neg_infinity()
101 }
102
103 /// Returns `true` if the number is neither infinite or NaN
104 #[inline]
105 fn is_finite(self) -> bool {
106 !(self.is_nan() || self.is_infinite())
107 }
108
109 /// Returns `true` if the number is neither zero, infinite, subnormal or NaN
110 #[inline]
111 fn is_normal(self) -> bool {
112 self.classify() == FPNormal
113 }
114
115 /// Returns the floating point category of the number. If only one property
116 /// is going to be tested, it is generally faster to use the specific
117 /// predicate instead.
118 fn classify(self) -> FPCategory {
119 static EXP_MASK: u64 = 0x7ff0000000000000;
120 static MAN_MASK: u64 = 0x000fffffffffffff;
121
122 let bits: u64 = unsafe { cast::transmute(self) };
123 match (bits & MAN_MASK, bits & EXP_MASK) {
124 (0, 0) => FPZero,
125 (_, 0) => FPSubnormal,
126 (0, EXP_MASK) => FPInfinite,
127 (_, EXP_MASK) => FPNaN,
128 _ => FPNormal,
129 }
130 }
131
132 #[inline]
133 fn mantissa_digits(_: Option<f64>) -> uint { MANTISSA_DIGITS }
134
135 #[inline]
136 fn digits(_: Option<f64>) -> uint { DIGITS }
137
138 #[inline]
139 fn epsilon() -> f64 { EPSILON }
140
141 #[inline]
142 fn min_exp(_: Option<f64>) -> int { MIN_EXP }
143
144 #[inline]
145 fn max_exp(_: Option<f64>) -> int { MAX_EXP }
146
147 #[inline]
148 fn min_10_exp(_: Option<f64>) -> int { MIN_10_EXP }
149
150 #[inline]
151 fn max_10_exp(_: Option<f64>) -> int { MAX_10_EXP }
152
153 #[inline]
154 fn min_pos_value(_: Option<f64>) -> f64 { MIN_POS_VALUE }
155
156 /// Constructs a floating point number by multiplying `x` by 2 raised to the
157 /// power of `exp`
158 #[inline]
159 fn ldexp(x: f64, exp: int) -> f64 {
160 unsafe { cmath::ldexp(x, exp as c_int) }
161 }
162
163 /// Breaks the number into a normalized fraction and a base-2 exponent,
164 /// satisfying:
165 ///
166 /// - `self = x * pow(2, exp)`
167 /// - `0.5 <= abs(x) < 1.0`
168 #[inline]
169 fn frexp(self) -> (f64, int) {
170 unsafe {
171 let mut exp = 0;
172 let x = cmath::frexp(self, &mut exp);
173 (x, exp as int)
174 }
175 }
176
177 /// Returns the mantissa, exponent and sign as integers.
178 fn integer_decode(self) -> (u64, i16, i8) {
179 let bits: u64 = unsafe { cast::transmute(self) };
180 let sign: i8 = if bits >> 63 == 0 { 1 } else { -1 };
181 let mut exponent: i16 = ((bits >> 52) & 0x7ff) as i16;
182 let mantissa = if exponent == 0 {
183 (bits & 0xfffffffffffff) << 1
184 } else {
185 (bits & 0xfffffffffffff) | 0x10000000000000
186 };
187 // Exponent bias + mantissa shift
188 exponent -= 1023 + 52;
189 (mantissa, exponent, sign)
190 }
191
192 /// Returns the next representable floating-point value in the direction of
193 /// `other`.
194 #[inline]
195 fn next_after(self, other: f64) -> f64 {
196 unsafe { cmath::nextafter(self, other) }
197 }
198
199 /// Round half-way cases toward `NEG_INFINITY`
200 #[inline]
201 fn floor(self) -> f64 {
202 unsafe { intrinsics::floorf64(self) }
203 }
204
205 /// Round half-way cases toward `INFINITY`
206 #[inline]
207 fn ceil(self) -> f64 {
208 unsafe { intrinsics::ceilf64(self) }
209 }
210
211 /// Round half-way cases away from `0.0`
212 #[inline]
213 fn round(self) -> f64 {
214 unsafe { intrinsics::roundf64(self) }
215 }
216
217 /// The integer part of the number (rounds towards `0.0`)
218 #[inline]
219 fn trunc(self) -> f64 {
220 unsafe { intrinsics::truncf64(self) }
221 }
222
223 /// The fractional part of the number, satisfying:
224 ///
225 /// ```rust
226 /// let x = 1.65f64;
227 /// assert!(x == x.trunc() + x.fract())
228 /// ```
229 #[inline]
230 fn fract(self) -> f64 { self - self.trunc() }
231
232 #[inline]
233 fn max(self, other: f64) -> f64 {
234 unsafe { cmath::fmax(self, other) }
235 }
236
237 #[inline]
238 fn min(self, other: f64) -> f64 {
239 unsafe { cmath::fmin(self, other) }
240 }
241
242 /// Fused multiply-add. Computes `(self * a) + b` with only one rounding
243 /// error. This produces a more accurate result with better performance than
244 /// a separate multiplication operation followed by an add.
245 #[inline]
246 fn mul_add(self, a: f64, b: f64) -> f64 {
247 unsafe { intrinsics::fmaf64(self, a, b) }
248 }
249
250 /// The reciprocal (multiplicative inverse) of the number
251 #[inline]
252 fn recip(self) -> f64 { 1.0 / self }
253
254 #[inline]
255 fn powf(self, n: f64) -> f64 {
256 unsafe { intrinsics::powf64(self, n) }
257 }
258
259 #[inline]
260 fn powi(self, n: i32) -> f64 {
261 unsafe { intrinsics::powif64(self, n) }
262 }
263
264 /// sqrt(2.0)
265 #[inline]
266 fn sqrt2() -> f64 { consts::SQRT2 }
267
268 /// 1.0 / sqrt(2.0)
269 #[inline]
270 fn frac_1_sqrt2() -> f64 { consts::FRAC_1_SQRT2 }
271
272 #[inline]
273 fn sqrt(self) -> f64 {
274 unsafe { intrinsics::sqrtf64(self) }
275 }
276
277 #[inline]
278 fn rsqrt(self) -> f64 { self.sqrt().recip() }
279
280 #[inline]
281 fn cbrt(self) -> f64 {
282 unsafe { cmath::cbrt(self) }
283 }
284
285 #[inline]
286 fn hypot(self, other: f64) -> f64 {
287 unsafe { cmath::hypot(self, other) }
288 }
289
290 /// Archimedes' constant
291 #[inline]
292 fn pi() -> f64 { consts::PI }
293
294 /// 2.0 * pi
295 #[inline]
296 fn two_pi() -> f64 { consts::PI_2 }
297
298 /// pi / 2.0
299 #[inline]
300 fn frac_pi_2() -> f64 { consts::FRAC_PI_2 }
301
302 /// pi / 3.0
303 #[inline]
304 fn frac_pi_3() -> f64 { consts::FRAC_PI_3 }
305
306 /// pi / 4.0
307 #[inline]
308 fn frac_pi_4() -> f64 { consts::FRAC_PI_4 }
309
310 /// pi / 6.0
311 #[inline]
312 fn frac_pi_6() -> f64 { consts::FRAC_PI_6 }
313
314 /// pi / 8.0
315 #[inline]
316 fn frac_pi_8() -> f64 { consts::FRAC_PI_8 }
317
318 /// 1.0 / pi
319 #[inline]
320 fn frac_1_pi() -> f64 { consts::FRAC_1_PI }
321
322 /// 2.0 / pi
323 #[inline]
324 fn frac_2_pi() -> f64 { consts::FRAC_2_PI }
325
326 /// 2.0 / sqrt(pi)
327 #[inline]
328 fn frac_2_sqrtpi() -> f64 { consts::FRAC_2_SQRTPI }
329
330 #[inline]
331 fn sin(self) -> f64 {
332 unsafe { intrinsics::sinf64(self) }
333 }
334
335 #[inline]
336 fn cos(self) -> f64 {
337 unsafe { intrinsics::cosf64(self) }
338 }
339
340 #[inline]
341 fn tan(self) -> f64 {
342 unsafe { cmath::tan(self) }
343 }
344
345 #[inline]
346 fn asin(self) -> f64 {
347 unsafe { cmath::asin(self) }
348 }
349
350 #[inline]
351 fn acos(self) -> f64 {
352 unsafe { cmath::acos(self) }
353 }
354
355 #[inline]
356 fn atan(self) -> f64 {
357 unsafe { cmath::atan(self) }
358 }
359
360 #[inline]
361 fn atan2(self, other: f64) -> f64 {
362 unsafe { cmath::atan2(self, other) }
363 }
364
365 /// Simultaneously computes the sine and cosine of the number
366 #[inline]
367 fn sin_cos(self) -> (f64, f64) {
368 (self.sin(), self.cos())
369 }
370
371 /// Euler's number
372 #[inline]
373 fn e() -> f64 { consts::E }
374
375 /// log2(e)
376 #[inline]
377 fn log2_e() -> f64 { consts::LOG2_E }
378
379 /// log10(e)
380 #[inline]
381 fn log10_e() -> f64 { consts::LOG10_E }
382
383 /// ln(2.0)
384 #[inline]
385 fn ln_2() -> f64 { consts::LN_2 }
386
387 /// ln(10.0)
388 #[inline]
389 fn ln_10() -> f64 { consts::LN_10 }
390
391 /// Returns the exponential of the number
392 #[inline]
393 fn exp(self) -> f64 {
394 unsafe { intrinsics::expf64(self) }
395 }
396
397 /// Returns 2 raised to the power of the number
398 #[inline]
399 fn exp2(self) -> f64 {
400 unsafe { intrinsics::exp2f64(self) }
401 }
402
403 /// Returns the exponential of the number, minus `1`, in a way that is
404 /// accurate even if the number is close to zero
405 #[inline]
406 fn exp_m1(self) -> f64 {
407 unsafe { cmath::expm1(self) }
408 }
409
410 /// Returns the natural logarithm of the number
411 #[inline]
412 fn ln(self) -> f64 {
413 unsafe { intrinsics::logf64(self) }
414 }
415
416 /// Returns the logarithm of the number with respect to an arbitrary base
417 #[inline]
418 fn log(self, base: f64) -> f64 { self.ln() / base.ln() }
419
420 /// Returns the base 2 logarithm of the number
421 #[inline]
422 fn log2(self) -> f64 {
423 unsafe { intrinsics::log2f64(self) }
424 }
425
426 /// Returns the base 10 logarithm of the number
427 #[inline]
428 fn log10(self) -> f64 {
429 unsafe { intrinsics::log10f64(self) }
430 }
431
432 /// Returns the natural logarithm of the number plus `1` (`ln(1+n)`) more
433 /// accurately than if the operations were performed separately
434 #[inline]
435 fn ln_1p(self) -> f64 {
436 unsafe { cmath::log1p(self) }
437 }
438
439 #[inline]
440 fn sinh(self) -> f64 {
441 unsafe { cmath::sinh(self) }
442 }
443
444 #[inline]
445 fn cosh(self) -> f64 {
446 unsafe { cmath::cosh(self) }
447 }
448
449 #[inline]
450 fn tanh(self) -> f64 {
451 unsafe { cmath::tanh(self) }
452 }
453
454 /// Inverse hyperbolic sine
455 ///
456 /// # Returns
457 ///
458 /// - on success, the inverse hyperbolic sine of `self` will be returned
459 /// - `self` if `self` is `0.0`, `-0.0`, `INFINITY`, or `NEG_INFINITY`
460 /// - `NAN` if `self` is `NAN`
461 #[inline]
462 fn asinh(self) -> f64 {
463 match self {
464 NEG_INFINITY => NEG_INFINITY,
465 x => (x + ((x * x) + 1.0).sqrt()).ln(),
466 }
467 }
468
469 /// Inverse hyperbolic cosine
470 ///
471 /// # Returns
472 ///
473 /// - on success, the inverse hyperbolic cosine of `self` will be returned
474 /// - `INFINITY` if `self` is `INFINITY`
475 /// - `NAN` if `self` is `NAN` or `self < 1.0` (including `NEG_INFINITY`)
476 #[inline]
477 fn acosh(self) -> f64 {
478 match self {
479 x if x < 1.0 => Float::nan(),
480 x => (x + ((x * x) - 1.0).sqrt()).ln(),
481 }
482 }
483
484 /// Inverse hyperbolic tangent
485 ///
486 /// # Returns
487 ///
488 /// - on success, the inverse hyperbolic tangent of `self` will be returned
489 /// - `self` if `self` is `0.0` or `-0.0`
490 /// - `INFINITY` if `self` is `1.0`
491 /// - `NEG_INFINITY` if `self` is `-1.0`
492 /// - `NAN` if the `self` is `NAN` or outside the domain of `-1.0 <= self <= 1.0`
493 /// (including `INFINITY` and `NEG_INFINITY`)
494 #[inline]
495 fn atanh(self) -> f64 {
496 0.5 * ((2.0 * self) / (1.0 - self)).ln_1p()
497 }
498
499 /// Converts to degrees, assuming the number is in radians
500 #[inline]
501 fn to_degrees(self) -> f64 { self * (180.0f64 / Float::pi()) }
502
503 /// Converts to radians, assuming the number is in degrees
504 #[inline]
505 fn to_radians(self) -> f64 {
506 let value: f64 = Float::pi();
507 self * (value / 180.0)
508 }
509 }
510
511 //
512 // Section: String Conversions
513 //
514
515 /// Converts a float to a string
516 ///
517 /// # Arguments
518 ///
519 /// * num - The float value
520 #[inline]
521 pub fn to_str(num: f64) -> ~str {
522 let (r, _) = strconv::float_to_str_common(
523 num, 10u, true, strconv::SignNeg, strconv::DigAll, strconv::ExpNone, false);
524 r
525 }
526
527 /// Converts a float to a string in hexadecimal format
528 ///
529 /// # Arguments
530 ///
531 /// * num - The float value
532 #[inline]
533 pub fn to_str_hex(num: f64) -> ~str {
534 let (r, _) = strconv::float_to_str_common(
535 num, 16u, true, strconv::SignNeg, strconv::DigAll, strconv::ExpNone, false);
536 r
537 }
538
539 /// Converts a float to a string in a given radix, and a flag indicating
540 /// whether it's a special value
541 ///
542 /// # Arguments
543 ///
544 /// * num - The float value
545 /// * radix - The base to use
546 #[inline]
547 pub fn to_str_radix_special(num: f64, rdx: uint) -> (~str, bool) {
548 strconv::float_to_str_common(num, rdx, true,
549 strconv::SignNeg, strconv::DigAll, strconv::ExpNone, false)
550 }
551
552 /// Converts a float to a string with exactly the number of
553 /// provided significant digits
554 ///
555 /// # Arguments
556 ///
557 /// * num - The float value
558 /// * digits - The number of significant digits
559 #[inline]
560 pub fn to_str_exact(num: f64, dig: uint) -> ~str {
561 let (r, _) = strconv::float_to_str_common(
562 num, 10u, true, strconv::SignNeg, strconv::DigExact(dig), strconv::ExpNone, false);
563 r
564 }
565
566 /// Converts a float to a string with a maximum number of
567 /// significant digits
568 ///
569 /// # Arguments
570 ///
571 /// * num - The float value
572 /// * digits - The number of significant digits
573 #[inline]
574 pub fn to_str_digits(num: f64, dig: uint) -> ~str {
575 let (r, _) = strconv::float_to_str_common(
576 num, 10u, true, strconv::SignNeg, strconv::DigMax(dig), strconv::ExpNone, false);
577 r
578 }
579
580 /// Converts a float to a string using the exponential notation with exactly the number of
581 /// provided digits after the decimal point in the significand
582 ///
583 /// # Arguments
584 ///
585 /// * num - The float value
586 /// * digits - The number of digits after the decimal point
587 /// * upper - Use `E` instead of `e` for the exponent sign
588 #[inline]
589 pub fn to_str_exp_exact(num: f64, dig: uint, upper: bool) -> ~str {
590 let (r, _) = strconv::float_to_str_common(
591 num, 10u, true, strconv::SignNeg, strconv::DigExact(dig), strconv::ExpDec, upper);
592 r
593 }
594
595 /// Converts a float to a string using the exponential notation with the maximum number of
596 /// digits after the decimal point in the significand
597 ///
598 /// # Arguments
599 ///
600 /// * num - The float value
601 /// * digits - The number of digits after the decimal point
602 /// * upper - Use `E` instead of `e` for the exponent sign
603 #[inline]
604 pub fn to_str_exp_digits(num: f64, dig: uint, upper: bool) -> ~str {
605 let (r, _) = strconv::float_to_str_common(
606 num, 10u, true, strconv::SignNeg, strconv::DigMax(dig), strconv::ExpDec, upper);
607 r
608 }
609
610 impl num::ToStrRadix for f64 {
611 /// Converts a float to a string in a given radix
612 ///
613 /// # Arguments
614 ///
615 /// * num - The float value
616 /// * radix - The base to use
617 ///
618 /// # Failure
619 ///
620 /// Fails if called on a special value like `inf`, `-inf` or `NAN` due to
621 /// possible misinterpretation of the result at higher bases. If those values
622 /// are expected, use `to_str_radix_special()` instead.
623 #[inline]
624 fn to_str_radix(&self, rdx: uint) -> ~str {
625 let (r, special) = strconv::float_to_str_common(
626 *self, rdx, true, strconv::SignNeg, strconv::DigAll, strconv::ExpNone, false);
627 if special { fail!("number has a special value, \
628 try to_str_radix_special() if those are expected") }
629 r
630 }
631 }
632
633 /// Convert a string in base 16 to a float.
634 /// Accepts an optional binary exponent.
635 ///
636 /// This function accepts strings such as
637 ///
638 /// * 'a4.fe'
639 /// * '+a4.fe', equivalent to 'a4.fe'
640 /// * '-a4.fe'
641 /// * '2b.aP128', or equivalently, '2b.ap128'
642 /// * '2b.aP-128'
643 /// * '.' (understood as 0)
644 /// * 'c.'
645 /// * '.c', or, equivalently, '0.c'
646 /// * '+inf', 'inf', '-inf', 'NaN'
647 ///
648 /// Leading and trailing whitespace represent an error.
649 ///
650 /// # Arguments
651 ///
652 /// * num - A string
653 ///
654 /// # Return value
655 ///
656 /// `None` if the string did not represent a valid number. Otherwise,
657 /// `Some(n)` where `n` is the floating-point number represented by `[num]`.
658 #[inline]
659 pub fn from_str_hex(num: &str) -> Option<f64> {
660 strconv::from_str_common(num, 16u, true, true, true,
661 strconv::ExpBin, false, false)
662 }
663
664 impl FromStr for f64 {
665 /// Convert a string in base 10 to a float.
666 /// Accepts an optional decimal exponent.
667 ///
668 /// This function accepts strings such as
669 ///
670 /// * '3.14'
671 /// * '+3.14', equivalent to '3.14'
672 /// * '-3.14'
673 /// * '2.5E10', or equivalently, '2.5e10'
674 /// * '2.5E-10'
675 /// * '.' (understood as 0)
676 /// * '5.'
677 /// * '.5', or, equivalently, '0.5'
678 /// * '+inf', 'inf', '-inf', 'NaN'
679 ///
680 /// Leading and trailing whitespace represent an error.
681 ///
682 /// # Arguments
683 ///
684 /// * num - A string
685 ///
686 /// # Return value
687 ///
688 /// `none` if the string did not represent a valid number. Otherwise,
689 /// `Some(n)` where `n` is the floating-point number represented by `num`.
690 #[inline]
691 fn from_str(val: &str) -> Option<f64> {
692 strconv::from_str_common(val, 10u, true, true, true,
693 strconv::ExpDec, false, false)
694 }
695 }
696
697 impl num::FromStrRadix for f64 {
698 /// Convert a string in a given base to a float.
699 ///
700 /// Due to possible conflicts, this function does **not** accept
701 /// the special values `inf`, `-inf`, `+inf` and `NaN`, **nor**
702 /// does it recognize exponents of any kind.
703 ///
704 /// Leading and trailing whitespace represent an error.
705 ///
706 /// # Arguments
707 ///
708 /// * num - A string
709 /// * radix - The base to use. Must lie in the range [2 .. 36]
710 ///
711 /// # Return value
712 ///
713 /// `None` if the string did not represent a valid number. Otherwise,
714 /// `Some(n)` where `n` is the floating-point number represented by `num`.
715 #[inline]
716 fn from_str_radix(val: &str, rdx: uint) -> Option<f64> {
717 strconv::from_str_common(val, rdx, true, true, false,
718 strconv::ExpNone, false, false)
719 }
720 }
721
722 #[cfg(test)]
723 mod tests {
724 use f64::*;
725 use num::*;
726 use num;
727
728 #[test]
729 fn test_min_nan() {
730 assert_eq!(NAN.min(2.0), 2.0);
731 assert_eq!(2.0f64.min(NAN), 2.0);
732 }
733
734 #[test]
735 fn test_max_nan() {
736 assert_eq!(NAN.max(2.0), 2.0);
737 assert_eq!(2.0f64.max(NAN), 2.0);
738 }
739
740 #[test]
741 fn test_num() {
742 num::test_num(10f64, 2f64);
743 }
744
745 #[test]
746 fn test_floor() {
747 assert_approx_eq!(1.0f64.floor(), 1.0f64);
748 assert_approx_eq!(1.3f64.floor(), 1.0f64);
749 assert_approx_eq!(1.5f64.floor(), 1.0f64);
750 assert_approx_eq!(1.7f64.floor(), 1.0f64);
751 assert_approx_eq!(0.0f64.floor(), 0.0f64);
752 assert_approx_eq!((-0.0f64).floor(), -0.0f64);
753 assert_approx_eq!((-1.0f64).floor(), -1.0f64);
754 assert_approx_eq!((-1.3f64).floor(), -2.0f64);
755 assert_approx_eq!((-1.5f64).floor(), -2.0f64);
756 assert_approx_eq!((-1.7f64).floor(), -2.0f64);
757 }
758
759 #[test]
760 fn test_ceil() {
761 assert_approx_eq!(1.0f64.ceil(), 1.0f64);
762 assert_approx_eq!(1.3f64.ceil(), 2.0f64);
763 assert_approx_eq!(1.5f64.ceil(), 2.0f64);
764 assert_approx_eq!(1.7f64.ceil(), 2.0f64);
765 assert_approx_eq!(0.0f64.ceil(), 0.0f64);
766 assert_approx_eq!((-0.0f64).ceil(), -0.0f64);
767 assert_approx_eq!((-1.0f64).ceil(), -1.0f64);
768 assert_approx_eq!((-1.3f64).ceil(), -1.0f64);
769 assert_approx_eq!((-1.5f64).ceil(), -1.0f64);
770 assert_approx_eq!((-1.7f64).ceil(), -1.0f64);
771 }
772
773 #[test]
774 fn test_round() {
775 assert_approx_eq!(1.0f64.round(), 1.0f64);
776 assert_approx_eq!(1.3f64.round(), 1.0f64);
777 assert_approx_eq!(1.5f64.round(), 2.0f64);
778 assert_approx_eq!(1.7f64.round(), 2.0f64);
779 assert_approx_eq!(0.0f64.round(), 0.0f64);
780 assert_approx_eq!((-0.0f64).round(), -0.0f64);
781 assert_approx_eq!((-1.0f64).round(), -1.0f64);
782 assert_approx_eq!((-1.3f64).round(), -1.0f64);
783 assert_approx_eq!((-1.5f64).round(), -2.0f64);
784 assert_approx_eq!((-1.7f64).round(), -2.0f64);
785 }
786
787 #[test]
788 fn test_trunc() {
789 assert_approx_eq!(1.0f64.trunc(), 1.0f64);
790 assert_approx_eq!(1.3f64.trunc(), 1.0f64);
791 assert_approx_eq!(1.5f64.trunc(), 1.0f64);
792 assert_approx_eq!(1.7f64.trunc(), 1.0f64);
793 assert_approx_eq!(0.0f64.trunc(), 0.0f64);
794 assert_approx_eq!((-0.0f64).trunc(), -0.0f64);
795 assert_approx_eq!((-1.0f64).trunc(), -1.0f64);
796 assert_approx_eq!((-1.3f64).trunc(), -1.0f64);
797 assert_approx_eq!((-1.5f64).trunc(), -1.0f64);
798 assert_approx_eq!((-1.7f64).trunc(), -1.0f64);
799 }
800
801 #[test]
802 fn test_fract() {
803 assert_approx_eq!(1.0f64.fract(), 0.0f64);
804 assert_approx_eq!(1.3f64.fract(), 0.3f64);
805 assert_approx_eq!(1.5f64.fract(), 0.5f64);
806 assert_approx_eq!(1.7f64.fract(), 0.7f64);
807 assert_approx_eq!(0.0f64.fract(), 0.0f64);
808 assert_approx_eq!((-0.0f64).fract(), -0.0f64);
809 assert_approx_eq!((-1.0f64).fract(), -0.0f64);
810 assert_approx_eq!((-1.3f64).fract(), -0.3f64);
811 assert_approx_eq!((-1.5f64).fract(), -0.5f64);
812 assert_approx_eq!((-1.7f64).fract(), -0.7f64);
813 }
814
815 #[test]
816 fn test_asinh() {
817 assert_eq!(0.0f64.asinh(), 0.0f64);
818 assert_eq!((-0.0f64).asinh(), -0.0f64);
819
820 let inf: f64 = Float::infinity();
821 let neg_inf: f64 = Float::neg_infinity();
822 let nan: f64 = Float::nan();
823 assert_eq!(inf.asinh(), inf);
824 assert_eq!(neg_inf.asinh(), neg_inf);
825 assert!(nan.asinh().is_nan());
826 assert_approx_eq!(2.0f64.asinh(), 1.443635475178810342493276740273105f64);
827 assert_approx_eq!((-2.0f64).asinh(), -1.443635475178810342493276740273105f64);
828 }
829
830 #[test]
831 fn test_acosh() {
832 assert_eq!(1.0f64.acosh(), 0.0f64);
833 assert!(0.999f64.acosh().is_nan());
834
835 let inf: f64 = Float::infinity();
836 let neg_inf: f64 = Float::neg_infinity();
837 let nan: f64 = Float::nan();
838 assert_eq!(inf.acosh(), inf);
839 assert!(neg_inf.acosh().is_nan());
840 assert!(nan.acosh().is_nan());
841 assert_approx_eq!(2.0f64.acosh(), 1.31695789692481670862504634730796844f64);
842 assert_approx_eq!(3.0f64.acosh(), 1.76274717403908605046521864995958461f64);
843 }
844
845 #[test]
846 fn test_atanh() {
847 assert_eq!(0.0f64.atanh(), 0.0f64);
848 assert_eq!((-0.0f64).atanh(), -0.0f64);
849
850 let inf: f64 = Float::infinity();
851 let neg_inf: f64 = Float::neg_infinity();
852 let nan: f64 = Float::nan();
853 assert_eq!(1.0f64.atanh(), inf);
854 assert_eq!((-1.0f64).atanh(), neg_inf);
855 assert!(2f64.atanh().atanh().is_nan());
856 assert!((-2f64).atanh().atanh().is_nan());
857 assert!(inf.atanh().is_nan());
858 assert!(neg_inf.atanh().is_nan());
859 assert!(nan.atanh().is_nan());
860 assert_approx_eq!(0.5f64.atanh(), 0.54930614433405484569762261846126285f64);
861 assert_approx_eq!((-0.5f64).atanh(), -0.54930614433405484569762261846126285f64);
862 }
863
864 #[test]
865 fn test_real_consts() {
866 let pi: f64 = Float::pi();
867 let two_pi: f64 = Float::two_pi();
868 let frac_pi_2: f64 = Float::frac_pi_2();
869 let frac_pi_3: f64 = Float::frac_pi_3();
870 let frac_pi_4: f64 = Float::frac_pi_4();
871 let frac_pi_6: f64 = Float::frac_pi_6();
872 let frac_pi_8: f64 = Float::frac_pi_8();
873 let frac_1_pi: f64 = Float::frac_1_pi();
874 let frac_2_pi: f64 = Float::frac_2_pi();
875 let frac_2_sqrtpi: f64 = Float::frac_2_sqrtpi();
876 let sqrt2: f64 = Float::sqrt2();
877 let frac_1_sqrt2: f64 = Float::frac_1_sqrt2();
878 let e: f64 = Float::e();
879 let log2_e: f64 = Float::log2_e();
880 let log10_e: f64 = Float::log10_e();
881 let ln_2: f64 = Float::ln_2();
882 let ln_10: f64 = Float::ln_10();
883
884 assert_approx_eq!(two_pi, 2.0 * pi);
885 assert_approx_eq!(frac_pi_2, pi / 2f64);
886 assert_approx_eq!(frac_pi_3, pi / 3f64);
887 assert_approx_eq!(frac_pi_4, pi / 4f64);
888 assert_approx_eq!(frac_pi_6, pi / 6f64);
889 assert_approx_eq!(frac_pi_8, pi / 8f64);
890 assert_approx_eq!(frac_1_pi, 1f64 / pi);
891 assert_approx_eq!(frac_2_pi, 2f64 / pi);
892 assert_approx_eq!(frac_2_sqrtpi, 2f64 / pi.sqrt());
893 assert_approx_eq!(sqrt2, 2f64.sqrt());
894 assert_approx_eq!(frac_1_sqrt2, 1f64 / 2f64.sqrt());
895 assert_approx_eq!(log2_e, e.log2());
896 assert_approx_eq!(log10_e, e.log10());
897 assert_approx_eq!(ln_2, 2f64.ln());
898 assert_approx_eq!(ln_10, 10f64.ln());
899 }
900
901 #[test]
902 pub fn test_abs() {
903 assert_eq!(INFINITY.abs(), INFINITY);
904 assert_eq!(1f64.abs(), 1f64);
905 assert_eq!(0f64.abs(), 0f64);
906 assert_eq!((-0f64).abs(), 0f64);
907 assert_eq!((-1f64).abs(), 1f64);
908 assert_eq!(NEG_INFINITY.abs(), INFINITY);
909 assert_eq!((1f64/NEG_INFINITY).abs(), 0f64);
910 assert!(NAN.abs().is_nan());
911 }
912
913 #[test]
914 fn test_abs_sub() {
915 assert_eq!((-1f64).abs_sub(&1f64), 0f64);
916 assert_eq!(1f64.abs_sub(&1f64), 0f64);
917 assert_eq!(1f64.abs_sub(&0f64), 1f64);
918 assert_eq!(1f64.abs_sub(&-1f64), 2f64);
919 assert_eq!(NEG_INFINITY.abs_sub(&0f64), 0f64);
920 assert_eq!(INFINITY.abs_sub(&1f64), INFINITY);
921 assert_eq!(0f64.abs_sub(&NEG_INFINITY), INFINITY);
922 assert_eq!(0f64.abs_sub(&INFINITY), 0f64);
923 }
924
925 #[test]
926 fn test_abs_sub_nowin() {
927 assert!(NAN.abs_sub(&-1f64).is_nan());
928 assert!(1f64.abs_sub(&NAN).is_nan());
929 }
930
931 #[test]
932 fn test_signum() {
933 assert_eq!(INFINITY.signum(), 1f64);
934 assert_eq!(1f64.signum(), 1f64);
935 assert_eq!(0f64.signum(), 1f64);
936 assert_eq!((-0f64).signum(), -1f64);
937 assert_eq!((-1f64).signum(), -1f64);
938 assert_eq!(NEG_INFINITY.signum(), -1f64);
939 assert_eq!((1f64/NEG_INFINITY).signum(), -1f64);
940 assert!(NAN.signum().is_nan());
941 }
942
943 #[test]
944 fn test_is_positive() {
945 assert!(INFINITY.is_positive());
946 assert!(1f64.is_positive());
947 assert!(0f64.is_positive());
948 assert!(!(-0f64).is_positive());
949 assert!(!(-1f64).is_positive());
950 assert!(!NEG_INFINITY.is_positive());
951 assert!(!(1f64/NEG_INFINITY).is_positive());
952 assert!(!NAN.is_positive());
953 }
954
955 #[test]
956 fn test_is_negative() {
957 assert!(!INFINITY.is_negative());
958 assert!(!1f64.is_negative());
959 assert!(!0f64.is_negative());
960 assert!((-0f64).is_negative());
961 assert!((-1f64).is_negative());
962 assert!(NEG_INFINITY.is_negative());
963 assert!((1f64/NEG_INFINITY).is_negative());
964 assert!(!NAN.is_negative());
965 }
966
967 #[test]
968 fn test_is_normal() {
969 let nan: f64 = Float::nan();
970 let inf: f64 = Float::infinity();
971 let neg_inf: f64 = Float::neg_infinity();
972 let zero: f64 = Zero::zero();
973 let neg_zero: f64 = Float::neg_zero();
974 assert!(!nan.is_normal());
975 assert!(!inf.is_normal());
976 assert!(!neg_inf.is_normal());
977 assert!(!zero.is_normal());
978 assert!(!neg_zero.is_normal());
979 assert!(1f64.is_normal());
980 assert!(1e-307f64.is_normal());
981 assert!(!1e-308f64.is_normal());
982 }
983
984 #[test]
985 fn test_classify() {
986 let nan: f64 = Float::nan();
987 let inf: f64 = Float::infinity();
988 let neg_inf: f64 = Float::neg_infinity();
989 let zero: f64 = Zero::zero();
990 let neg_zero: f64 = Float::neg_zero();
991 assert_eq!(nan.classify(), FPNaN);
992 assert_eq!(inf.classify(), FPInfinite);
993 assert_eq!(neg_inf.classify(), FPInfinite);
994 assert_eq!(zero.classify(), FPZero);
995 assert_eq!(neg_zero.classify(), FPZero);
996 assert_eq!(1e-307f64.classify(), FPNormal);
997 assert_eq!(1e-308f64.classify(), FPSubnormal);
998 }
999
1000 #[test]
1001 fn test_ldexp() {
1002 // We have to use from_str until base-2 exponents
1003 // are supported in floating-point literals
1004 let f1: f64 = from_str_hex("1p-123").unwrap();
1005 let f2: f64 = from_str_hex("1p-111").unwrap();
1006 assert_eq!(Float::ldexp(1f64, -123), f1);
1007 assert_eq!(Float::ldexp(1f64, -111), f2);
1008
1009 assert_eq!(Float::ldexp(0f64, -123), 0f64);
1010 assert_eq!(Float::ldexp(-0f64, -123), -0f64);
1011
1012 let inf: f64 = Float::infinity();
1013 let neg_inf: f64 = Float::neg_infinity();
1014 let nan: f64 = Float::nan();
1015 assert_eq!(Float::ldexp(inf, -123), inf);
1016 assert_eq!(Float::ldexp(neg_inf, -123), neg_inf);
1017 assert!(Float::ldexp(nan, -123).is_nan());
1018 }
1019
1020 #[test]
1021 fn test_frexp() {
1022 // We have to use from_str until base-2 exponents
1023 // are supported in floating-point literals
1024 let f1: f64 = from_str_hex("1p-123").unwrap();
1025 let f2: f64 = from_str_hex("1p-111").unwrap();
1026 let (x1, exp1) = f1.frexp();
1027 let (x2, exp2) = f2.frexp();
1028 assert_eq!((x1, exp1), (0.5f64, -122));
1029 assert_eq!((x2, exp2), (0.5f64, -110));
1030 assert_eq!(Float::ldexp(x1, exp1), f1);
1031 assert_eq!(Float::ldexp(x2, exp2), f2);
1032
1033 assert_eq!(0f64.frexp(), (0f64, 0));
1034 assert_eq!((-0f64).frexp(), (-0f64, 0));
1035 }
1036
1037 #[test] #[ignore(cfg(windows))] // FIXME #8755
1038 fn test_frexp_nowin() {
1039 let inf: f64 = Float::infinity();
1040 let neg_inf: f64 = Float::neg_infinity();
1041 let nan: f64 = Float::nan();
1042 assert_eq!(match inf.frexp() { (x, _) => x }, inf)
1043 assert_eq!(match neg_inf.frexp() { (x, _) => x }, neg_inf)
1044 assert!(match nan.frexp() { (x, _) => x.is_nan() })
1045 }
1046
1047 #[test]
1048 fn test_integer_decode() {
1049 assert_eq!(3.14159265359f64.integer_decode(), (7074237752028906u64, -51i16, 1i8));
1050 assert_eq!((-8573.5918555f64).integer_decode(), (4713381968463931u64, -39i16, -1i8));
1051 assert_eq!(2f64.powf(100.0).integer_decode(), (4503599627370496u64, 48i16, 1i8));
1052 assert_eq!(0f64.integer_decode(), (0u64, -1075i16, 1i8));
1053 assert_eq!((-0f64).integer_decode(), (0u64, -1075i16, -1i8));
1054 assert_eq!(INFINITY.integer_decode(), (4503599627370496u64, 972i16, 1i8));
1055 assert_eq!(NEG_INFINITY.integer_decode(), (4503599627370496, 972, -1));
1056 assert_eq!(NAN.integer_decode(), (6755399441055744u64, 972i16, 1i8));
1057 }
1058 }
libstd/num/f64.rs:603:10-603:10 -fn- definition:
pub fn to_str_exp_digits(num: f64, dig: uint, upper: bool) -> ~str {
let (r, _) = strconv::float_to_str_common(
num, 10u, true, strconv::SignNeg, strconv::DigMax(dig), strconv::ExpDec, upper);
references:- 2libstd/fmt/mod.rs:
1202: Some(i) => ::$ty::to_str_exp_exact(self.abs(), i, true),
1203: None => ::$ty::to_str_exp_digits(self.abs(), 6, true)
1204: };
libstd/num/f64.rs:588:10-588:10 -fn- definition:
pub fn to_str_exp_exact(num: f64, dig: uint, upper: bool) -> ~str {
let (r, _) = strconv::float_to_str_common(
num, 10u, true, strconv::SignNeg, strconv::DigExact(dig), strconv::ExpDec, upper);
references:- 2libstd/fmt/mod.rs:
1201: let s = match fmt.precision {
1202: Some(i) => ::$ty::to_str_exp_exact(self.abs(), i, true),
1203: None => ::$ty::to_str_exp_digits(self.abs(), 6, true)