1 // Copyright 2012 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.
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.
11 //! Operations and constants for `float`
13 // Even though this module exports everything defined in it,
14 // because it contains re-exports, we also have to explicitly
15 // export locally defined things. That's a bit annoying.
18 // export when m_float == c_double
21 // PORT this must match in width according to architecture
25 use num::{Zero, One, strconv};
28 pub use f64::{add, sub, mul, div, rem, lt, le, eq, ne, ge, gt};
29 pub use f64::logarithm;
30 pub use f64::{acos, asin, atan2, cbrt, ceil, copysign, cosh, floor};
31 pub use f64::{erf, erfc, exp, expm1, exp2, abs_sub};
32 pub use f64::{mul_add, fmax, fmin, next_after, frexp, hypot, ldexp};
33 pub use f64::{lgamma, ln, log_radix, ln1p, log10, log2, ilog_radix};
34 pub use f64::{modf, pow, powi, round, sinh, tanh, tgamma, trunc};
35 pub use f64::{j0, j1, jn, y0, y1, yn};
37 pub static NaN: float = 0.0/0.0;
39 pub static infinity: float = 1.0/0.0;
41 pub static neg_infinity: float = -1.0/0.0;
45 // FIXME (requires Issue #1433 to fix): replace with mathematical
46 // staticants from cmath.
47 /// Archimedes' staticant
48 pub static pi: float = 3.14159265358979323846264338327950288;
51 pub static frac_pi_2: float = 1.57079632679489661923132169163975144;
54 pub static frac_pi_4: float = 0.785398163397448309615660845819875721;
57 pub static frac_1_pi: float = 0.318309886183790671537767526745028724;
60 pub static frac_2_pi: float = 0.636619772367581343075535053490057448;
63 pub static frac_2_sqrtpi: float = 1.12837916709551257389615890312154517;
66 pub static sqrt2: float = 1.41421356237309504880168872420969808;
69 pub static frac_1_sqrt2: float = 0.707106781186547524400844362104849039;
72 pub static e: float = 2.71828182845904523536028747135266250;
75 pub static log2_e: float = 1.44269504088896340735992468100189214;
78 pub static log10_e: float = 0.434294481903251827651128918916605082;
81 pub static ln_2: float = 0.693147180559945309417232121458176568;
84 pub static ln_10: float = 2.30258509299404568401799145468436421;
88 // Section: String Conversions
92 /// Converts a float to a string
96 /// * num - The float value
99 pub fn to_str(num: float) -> ~str {
100 let (r, _) = strconv::to_str_common(
101 &num, 10u, true, strconv::SignNeg, strconv::DigAll);
106 /// Converts a float to a string in hexadecimal format
110 /// * num - The float value
113 pub fn to_str_hex(num: float) -> ~str {
114 let (r, _) = strconv::to_str_common(
115 &num, 16u, true, strconv::SignNeg, strconv::DigAll);
120 /// Converts a float to a string in a given radix
124 /// * num - The float value
125 /// * radix - The base to use
129 /// Fails if called on a special value like `inf`, `-inf` or `NaN` due to
130 /// possible misinterpretation of the result at higher bases. If those values
131 /// are expected, use `to_str_radix_special()` instead.
134 pub fn to_str_radix(num: float, radix: uint) -> ~str {
135 let (r, special) = strconv::to_str_common(
136 &num, radix, true, strconv::SignNeg, strconv::DigAll);
137 if special { fail!(~"number has a special value, \
138 try to_str_radix_special() if those are expected") }
143 /// Converts a float to a string in a given radix, and a flag indicating
144 /// whether it's a special value
148 /// * num - The float value
149 /// * radix - The base to use
152 pub fn to_str_radix_special(num: float, radix: uint) -> (~str, bool) {
153 strconv::to_str_common(&num, radix, true,
154 strconv::SignNeg, strconv::DigAll)
158 /// Converts a float to a string with exactly the number of
159 /// provided significant digits
163 /// * num - The float value
164 /// * digits - The number of significant digits
167 pub fn to_str_exact(num: float, digits: uint) -> ~str {
168 let (r, _) = strconv::to_str_common(
169 &num, 10u, true, strconv::SignNeg, strconv::DigExact(digits));
174 /// Converts a float to a string with a maximum number of
175 /// significant digits
179 /// * num - The float value
180 /// * digits - The number of significant digits
183 pub fn to_str_digits(num: float, digits: uint) -> ~str {
184 let (r, _) = strconv::to_str_common(
185 &num, 10u, true, strconv::SignNeg, strconv::DigMax(digits));
189 impl to_str::ToStr for float {
191 fn to_str(&self) -> ~str { to_str_digits(*self, 8) }
194 impl num::ToStrRadix for float {
196 fn to_str_radix(&self, radix: uint) -> ~str {
197 to_str_radix(*self, radix)
202 /// Convert a string in base 10 to a float.
203 /// Accepts a optional decimal exponent.
205 /// This function accepts strings such as
208 /// * '+3.14', equivalent to '3.14'
210 /// * '2.5E10', or equivalently, '2.5e10'
212 /// * '.' (understood as 0)
214 /// * '.5', or, equivalently, '0.5'
215 /// * '+inf', 'inf', '-inf', 'NaN'
217 /// Leading and trailing whitespace represent an error.
225 /// `none` if the string did not represent a valid number. Otherwise,
226 /// `Some(n)` where `n` is the floating-point number represented by `num`.
229 pub fn from_str(num: &str) -> Option<float> {
230 strconv::from_str_common(num, 10u, true, true, true,
231 strconv::ExpDec, false, false)
235 /// Convert a string in base 16 to a float.
236 /// Accepts a optional binary exponent.
238 /// This function accepts strings such as
241 /// * '+a4.fe', equivalent to 'a4.fe'
243 /// * '2b.aP128', or equivalently, '2b.ap128'
245 /// * '.' (understood as 0)
247 /// * '.c', or, equivalently, '0.c'
248 /// * '+inf', 'inf', '-inf', 'NaN'
250 /// Leading and trailing whitespace represent an error.
258 /// `none` if the string did not represent a valid number. Otherwise,
259 /// `Some(n)` where `n` is the floating-point number represented by `[num]`.
262 pub fn from_str_hex(num: &str) -> Option<float> {
263 strconv::from_str_common(num, 16u, true, true, true,
264 strconv::ExpBin, false, false)
268 /// Convert a string in an given base to a float.
270 /// Due to possible conflicts, this function does **not** accept
271 /// the special values `inf`, `-inf`, `+inf` and `NaN`, **nor**
272 /// does it recognize exponents of any kind.
274 /// Leading and trailing whitespace represent an error.
279 /// * radix - The base to use. Must lie in the range [2 .. 36]
283 /// `none` if the string did not represent a valid number. Otherwise,
284 /// `Some(n)` where `n` is the floating-point number represented by `num`.
287 pub fn from_str_radix(num: &str, radix: uint) -> Option<float> {
288 strconv::from_str_common(num, radix, true, true, false,
289 strconv::ExpNone, false, false)
292 impl from_str::FromStr for float {
294 fn from_str(val: &str) -> Option<float> { from_str(val) }
297 impl num::FromStrRadix for float {
299 fn from_str_radix(val: &str, radix: uint) -> Option<float> {
300 from_str_radix(val, radix)
305 // Section: Arithmetics
309 /// Compute the exponentiation of an integer by another integer as a float
314 /// * pow - The exponent
318 /// `NaN` if both `x` and `pow` are `0u`, otherwise `x^pow`
320 pub fn pow_with_uint(base: uint, pow: uint) -> float {
327 let mut my_pow = pow;
329 let mut multiplier = base as float;
330 while (my_pow > 0u) {
331 if my_pow % 2u == 1u {
332 total = total * multiplier;
335 multiplier *= multiplier;
341 pub fn abs(x: float) -> float {
342 f64::abs(x as f64) as float
345 pub fn sqrt(x: float) -> float {
346 f64::sqrt(x as f64) as float
349 pub fn atan(x: float) -> float {
350 f64::atan(x as f64) as float
353 pub fn sin(x: float) -> float {
354 f64::sin(x as f64) as float
357 pub fn cos(x: float) -> float {
358 f64::cos(x as f64) as float
361 pub fn tan(x: float) -> float {
362 f64::tan(x as f64) as float
365 impl Num for float {}
370 fn eq(&self, other: &float) -> bool { (*self) == (*other) }
372 fn ne(&self, other: &float) -> bool { (*self) != (*other) }
378 fn lt(&self, other: &float) -> bool { (*self) < (*other) }
380 fn le(&self, other: &float) -> bool { (*self) <= (*other) }
382 fn ge(&self, other: &float) -> bool { (*self) >= (*other) }
384 fn gt(&self, other: &float) -> bool { (*self) > (*other) }
387 impl Orderable for float {
388 /// Returns `NaN` if either of the numbers are `NaN`.
390 fn min(&self, other: &float) -> float {
391 (*self as f64).min(&(*other as f64)) as float
394 /// Returns `NaN` if either of the numbers are `NaN`.
396 fn max(&self, other: &float) -> float {
397 (*self as f64).max(&(*other as f64)) as float
400 /// Returns the number constrained within the range `mn <= self <= mx`.
401 /// If any of the numbers are `NaN` then `NaN` is returned.
403 fn clamp(&self, mn: &float, mx: &float) -> float {
404 (*self as f64).clamp(&(*mn as f64), &(*mx as f64)) as float
408 impl Zero for float {
410 fn zero() -> float { 0.0 }
412 /// Returns true if the number is equal to either `0.0` or `-0.0`
414 fn is_zero(&self) -> bool { *self == 0.0 || *self == -0.0 }
419 fn one() -> float { 1.0 }
422 impl Round for float {
423 /// Round half-way cases toward `neg_infinity`
425 fn floor(&self) -> float { floor(*self as f64) as float }
427 /// Round half-way cases toward `infinity`
429 fn ceil(&self) -> float { ceil(*self as f64) as float }
431 /// Round half-way cases away from `0.0`
433 fn round(&self) -> float { round(*self as f64) as float }
435 /// The integer part of the number (rounds towards `0.0`)
437 fn trunc(&self) -> float { trunc(*self as f64) as float }
440 /// The fractional part of the number, satisfying:
443 /// assert!(x == trunc(x) + fract(x))
447 fn fract(&self) -> float { *self - self.trunc() }
450 impl Fractional for float {
451 /// The reciprocal (multiplicative inverse) of the number
453 fn recip(&self) -> float { 1.0 / *self }
456 impl Algebraic for float {
458 fn pow(&self, n: float) -> float {
459 (*self as f64).pow(n as f64) as float
463 fn sqrt(&self) -> float {
464 (*self as f64).sqrt() as float
468 fn rsqrt(&self) -> float {
469 (*self as f64).rsqrt() as float
473 fn cbrt(&self) -> float {
474 (*self as f64).cbrt() as float
478 fn hypot(&self, other: float) -> float {
479 (*self as f64).hypot(other as f64) as float
483 impl Trigonometric for float {
485 fn sin(&self) -> float {
486 (*self as f64).sin() as float
490 fn cos(&self) -> float {
491 (*self as f64).cos() as float
495 fn tan(&self) -> float {
496 (*self as f64).tan() as float
500 fn asin(&self) -> float {
501 (*self as f64).asin() as float
505 fn acos(&self) -> float {
506 (*self as f64).acos() as float
510 fn atan(&self) -> float {
511 (*self as f64).atan() as float
515 fn atan2(&self, other: float) -> float {
516 (*self as f64).atan2(other as f64) as float
520 impl Exponential for float {
522 fn exp(&self) -> float {
523 (*self as f64).exp() as float
527 fn exp2(&self) -> float {
528 (*self as f64).exp2() as float
532 fn expm1(&self) -> float {
533 (*self as f64).expm1() as float
537 fn log(&self) -> float {
538 (*self as f64).log() as float
542 fn log2(&self) -> float {
543 (*self as f64).log2() as float
547 fn log10(&self) -> float {
548 (*self as f64).log10() as float
552 impl Hyperbolic for float {
554 fn sinh(&self) -> float {
555 (*self as f64).sinh() as float
559 fn cosh(&self) -> float {
560 (*self as f64).cosh() as float
564 fn tanh(&self) -> float {
565 (*self as f64).tanh() as float
569 impl Real for float {
570 /// Archimedes' constant
572 fn pi() -> float { 3.14159265358979323846264338327950288 }
576 fn two_pi() -> float { 6.28318530717958647692528676655900576 }
580 fn frac_pi_2() -> float { 1.57079632679489661923132169163975144 }
584 fn frac_pi_3() -> float { 1.04719755119659774615421446109316763 }
588 fn frac_pi_4() -> float { 0.785398163397448309615660845819875721 }
592 fn frac_pi_6() -> float { 0.52359877559829887307710723054658381 }
596 fn frac_pi_8() -> float { 0.39269908169872415480783042290993786 }
600 fn frac_1_pi() -> float { 0.318309886183790671537767526745028724 }
604 fn frac_2_pi() -> float { 0.636619772367581343075535053490057448 }
608 fn frac_2_sqrtpi() -> float { 1.12837916709551257389615890312154517 }
612 fn sqrt2() -> float { 1.41421356237309504880168872420969808 }
616 fn frac_1_sqrt2() -> float { 0.707106781186547524400844362104849039 }
620 fn e() -> float { 2.71828182845904523536028747135266250 }
624 fn log2_e() -> float { 1.44269504088896340735992468100189214 }
628 fn log10_e() -> float { 0.434294481903251827651128918916605082 }
632 fn log_2() -> float { 0.693147180559945309417232121458176568 }
636 fn log_10() -> float { 2.30258509299404568401799145468436421 }
638 /// Converts to degrees, assuming the number is in radians
640 fn to_degrees(&self) -> float { (*self as f64).to_degrees() as float }
642 /// Converts to radians, assuming the number is in degrees
644 fn to_radians(&self) -> float { (*self as f64).to_radians() as float }
647 impl RealExt for float {
649 fn lgamma(&self) -> (int, float) {
651 let result = lgamma(*self as f64, &mut sign);
652 (sign as int, result as float)
656 fn tgamma(&self) -> float { tgamma(*self as f64) as float }
659 fn j0(&self) -> float { j0(*self as f64) as float }
662 fn j1(&self) -> float { j1(*self as f64) as float }
665 fn jn(&self, n: int) -> float { jn(n as c_int, *self as f64) as float }
668 fn y0(&self) -> float { y0(*self as f64) as float }
671 fn y1(&self) -> float { y1(*self as f64) as float }
674 fn yn(&self, n: int) -> float { yn(n as c_int, *self as f64) as float }
678 impl Add<float,float> for float {
680 fn add(&self, other: &float) -> float { *self + *other }
684 impl Sub<float,float> for float {
686 fn sub(&self, other: &float) -> float { *self - *other }
690 impl Mul<float,float> for float {
692 fn mul(&self, other: &float) -> float { *self * *other }
696 impl Div<float,float> for float {
698 fn div(&self, other: &float) -> float { *self / *other }
701 #[cfg(stage0,notest)]
702 impl Modulo<float,float> for float {
704 fn modulo(&self, other: &float) -> float { *self % *other }
706 #[cfg(not(stage0),notest)]
707 impl Rem<float,float> for float {
709 fn rem(&self, other: &float) -> float { *self % *other }
712 impl Neg<float> for float {
714 fn neg(&self) -> float { -*self }
717 impl Signed for float {
718 /// Computes the absolute value. Returns `NaN` if the number is `NaN`.
720 fn abs(&self) -> float { abs(*self) }
725 /// - `1.0` if the number is positive, `+0.0` or `infinity`
726 /// - `-1.0` if the number is negative, `-0.0` or `neg_infinity`
727 /// - `NaN` if the number is NaN
730 fn signum(&self) -> float {
731 if self.is_NaN() { NaN } else { f64::copysign(1.0, *self as f64) as float }
734 /// Returns `true` if the number is positive, including `+0.0` and `infinity`
736 fn is_positive(&self) -> bool { *self > 0.0 || (1.0 / *self) == infinity }
738 /// Returns `true` if the number is negative, including `-0.0` and `neg_infinity`
740 fn is_negative(&self) -> bool { *self < 0.0 || (1.0 / *self) == neg_infinity }
743 impl Bounded for float {
745 fn min_value() -> float { Bounded::min_value::<f64>() as float }
748 fn max_value() -> float { Bounded::max_value::<f64>() as float }
751 impl Primitive for float {
753 fn bits() -> uint { Primitive::bits::<f64>() }
756 fn bytes() -> uint { Primitive::bytes::<f64>() }
759 impl Float for float {
761 fn NaN() -> float { 0.0 / 0.0 }
764 fn infinity() -> float { 1.0 / 0.0 }
767 fn neg_infinity() -> float { -1.0 / 0.0 }
770 fn neg_zero() -> float { -0.0 }
773 fn is_NaN(&self) -> bool { *self != *self }
776 fn mantissa_digits() -> uint { Float::mantissa_digits::<f64>() }
779 fn digits() -> uint { Float::digits::<f64>() }
782 fn epsilon() -> float { Float::epsilon::<f64>() as float }
785 fn min_exp() -> int { Float::min_exp::<f64>() }
788 fn max_exp() -> int { Float::max_exp::<f64>() }
791 fn min_10_exp() -> int { Float::min_10_exp::<f64>() }
794 fn max_10_exp() -> int { Float::max_10_exp::<f64>() }
796 /// Returns `true` if the number is infinite
798 fn is_infinite(&self) -> bool {
799 *self == Float::infinity() || *self == Float::neg_infinity()
802 /// Returns `true` if the number is finite
804 fn is_finite(&self) -> bool {
805 !(self.is_NaN() || self.is_infinite())
809 /// Fused multiply-add. Computes `(self * a) + b` with only one rounding error. This
810 /// produces a more accurate result with better performance than a separate multiplication
811 /// operation followed by an add.
814 fn mul_add(&self, a: float, b: float) -> float {
815 mul_add(*self as f64, a as f64, b as f64) as float
818 /// Returns the next representable floating-point value in the direction of `other`
820 fn next_after(&self, other: float) -> float {
821 next_after(*self as f64, other as f64) as float
830 macro_rules! assert_fuzzy_eq(
831 ($a:expr, $b:expr) => ({
833 if !((a - b).abs() < 1.0e-6) {
834 fail!(fmt!("The values were not approximately equal. Found: %? and %?", a, b));
841 num::test_num(10f, 2f);
846 assert_eq!(1f.min(&2f), 1f);
847 assert_eq!(2f.min(&1f), 1f);
852 assert_eq!(1f.max(&2f), 2f);
853 assert_eq!(2f.max(&1f), 2f);
858 assert_eq!(1f.clamp(&2f, &4f), 2f);
859 assert_eq!(8f.clamp(&2f, &4f), 4f);
860 assert_eq!(3f.clamp(&2f, &4f), 3f);
861 assert!(3f.clamp(&Float::NaN::<float>(), &4f).is_NaN());
862 assert!(3f.clamp(&2f, &Float::NaN::<float>()).is_NaN());
863 assert!(Float::NaN::<float>().clamp(&2f, &4f).is_NaN());
868 assert_fuzzy_eq!(1.0f.floor(), 1.0f);
869 assert_fuzzy_eq!(1.3f.floor(), 1.0f);
870 assert_fuzzy_eq!(1.5f.floor(), 1.0f);
871 assert_fuzzy_eq!(1.7f.floor(), 1.0f);
872 assert_fuzzy_eq!(0.0f.floor(), 0.0f);
873 assert_fuzzy_eq!((-0.0f).floor(), -0.0f);
874 assert_fuzzy_eq!((-1.0f).floor(), -1.0f);
875 assert_fuzzy_eq!((-1.3f).floor(), -2.0f);
876 assert_fuzzy_eq!((-1.5f).floor(), -2.0f);
877 assert_fuzzy_eq!((-1.7f).floor(), -2.0f);
882 assert_fuzzy_eq!(1.0f.ceil(), 1.0f);
883 assert_fuzzy_eq!(1.3f.ceil(), 2.0f);
884 assert_fuzzy_eq!(1.5f.ceil(), 2.0f);
885 assert_fuzzy_eq!(1.7f.ceil(), 2.0f);
886 assert_fuzzy_eq!(0.0f.ceil(), 0.0f);
887 assert_fuzzy_eq!((-0.0f).ceil(), -0.0f);
888 assert_fuzzy_eq!((-1.0f).ceil(), -1.0f);
889 assert_fuzzy_eq!((-1.3f).ceil(), -1.0f);
890 assert_fuzzy_eq!((-1.5f).ceil(), -1.0f);
891 assert_fuzzy_eq!((-1.7f).ceil(), -1.0f);
896 assert_fuzzy_eq!(1.0f.round(), 1.0f);
897 assert_fuzzy_eq!(1.3f.round(), 1.0f);
898 assert_fuzzy_eq!(1.5f.round(), 2.0f);
899 assert_fuzzy_eq!(1.7f.round(), 2.0f);
900 assert_fuzzy_eq!(0.0f.round(), 0.0f);
901 assert_fuzzy_eq!((-0.0f).round(), -0.0f);
902 assert_fuzzy_eq!((-1.0f).round(), -1.0f);
903 assert_fuzzy_eq!((-1.3f).round(), -1.0f);
904 assert_fuzzy_eq!((-1.5f).round(), -2.0f);
905 assert_fuzzy_eq!((-1.7f).round(), -2.0f);
910 assert_fuzzy_eq!(1.0f.trunc(), 1.0f);
911 assert_fuzzy_eq!(1.3f.trunc(), 1.0f);
912 assert_fuzzy_eq!(1.5f.trunc(), 1.0f);
913 assert_fuzzy_eq!(1.7f.trunc(), 1.0f);
914 assert_fuzzy_eq!(0.0f.trunc(), 0.0f);
915 assert_fuzzy_eq!((-0.0f).trunc(), -0.0f);
916 assert_fuzzy_eq!((-1.0f).trunc(), -1.0f);
917 assert_fuzzy_eq!((-1.3f).trunc(), -1.0f);
918 assert_fuzzy_eq!((-1.5f).trunc(), -1.0f);
919 assert_fuzzy_eq!((-1.7f).trunc(), -1.0f);
924 assert_fuzzy_eq!(1.0f.fract(), 0.0f);
925 assert_fuzzy_eq!(1.3f.fract(), 0.3f);
926 assert_fuzzy_eq!(1.5f.fract(), 0.5f);
927 assert_fuzzy_eq!(1.7f.fract(), 0.7f);
928 assert_fuzzy_eq!(0.0f.fract(), 0.0f);
929 assert_fuzzy_eq!((-0.0f).fract(), -0.0f);
930 assert_fuzzy_eq!((-1.0f).fract(), -0.0f);
931 assert_fuzzy_eq!((-1.3f).fract(), -0.3f);
932 assert_fuzzy_eq!((-1.5f).fract(), -0.5f);
933 assert_fuzzy_eq!((-1.7f).fract(), -0.7f);
937 fn test_real_consts() {
938 assert_fuzzy_eq!(Real::two_pi::<float>(), 2f * Real::pi::<float>());
939 assert_fuzzy_eq!(Real::frac_pi_2::<float>(), Real::pi::<float>() / 2f);
940 assert_fuzzy_eq!(Real::frac_pi_3::<float>(), Real::pi::<float>() / 3f);
941 assert_fuzzy_eq!(Real::frac_pi_4::<float>(), Real::pi::<float>() / 4f);
942 assert_fuzzy_eq!(Real::frac_pi_6::<float>(), Real::pi::<float>() / 6f);
943 assert_fuzzy_eq!(Real::frac_pi_8::<float>(), Real::pi::<float>() / 8f);
944 assert_fuzzy_eq!(Real::frac_1_pi::<float>(), 1f / Real::pi::<float>());
945 assert_fuzzy_eq!(Real::frac_2_pi::<float>(), 2f / Real::pi::<float>());
946 assert_fuzzy_eq!(Real::frac_2_sqrtpi::<float>(), 2f / Real::pi::<float>().sqrt());
947 assert_fuzzy_eq!(Real::sqrt2::<float>(), 2f.sqrt());
948 assert_fuzzy_eq!(Real::frac_1_sqrt2::<float>(), 1f / 2f.sqrt());
949 assert_fuzzy_eq!(Real::log2_e::<float>(), Real::e::<float>().log2());
950 assert_fuzzy_eq!(Real::log10_e::<float>(), Real::e::<float>().log10());
951 assert_fuzzy_eq!(Real::log_2::<float>(), 2f.log());
952 assert_fuzzy_eq!(Real::log_10::<float>(), 10f.log());
957 assert_eq!(infinity.abs(), infinity);
958 assert_eq!(1f.abs(), 1f);
959 assert_eq!(0f.abs(), 0f);
960 assert_eq!((-0f).abs(), 0f);
961 assert_eq!((-1f).abs(), 1f);
962 assert_eq!(neg_infinity.abs(), infinity);
963 assert_eq!((1f/neg_infinity).abs(), 0f);
964 assert!(NaN.abs().is_NaN());
966 assert_eq!(infinity.signum(), 1f);
967 assert_eq!(1f.signum(), 1f);
968 assert_eq!(0f.signum(), 1f);
969 assert_eq!((-0f).signum(), -1f);
970 assert_eq!((-1f).signum(), -1f);
971 assert_eq!(neg_infinity.signum(), -1f);
972 assert_eq!((1f/neg_infinity).signum(), -1f);
973 assert!(NaN.signum().is_NaN());
975 assert!(infinity.is_positive());
976 assert!(1f.is_positive());
977 assert!(0f.is_positive());
978 assert!(!(-0f).is_positive());
979 assert!(!(-1f).is_positive());
980 assert!(!neg_infinity.is_positive());
981 assert!(!(1f/neg_infinity).is_positive());
982 assert!(!NaN.is_positive());
984 assert!(!infinity.is_negative());
985 assert!(!1f.is_negative());
986 assert!(!0f.is_negative());
987 assert!((-0f).is_negative());
988 assert!((-1f).is_negative());
989 assert!(neg_infinity.is_negative());
990 assert!((1f/neg_infinity).is_negative());
991 assert!(!NaN.is_negative());
995 fn test_primitive() {
996 assert_eq!(Primitive::bits::<float>(), sys::size_of::<float>() * 8);
997 assert_eq!(Primitive::bytes::<float>(), sys::size_of::<float>());
1001 pub fn test_to_str_exact_do_decimal() {
1002 let s = to_str_exact(5.0, 4u);
1003 assert_eq!(s, ~"5.0000");
1007 pub fn test_from_str() {
1008 assert_eq!(from_str(~"3"), Some(3.));
1009 assert_eq!(from_str(~"3.14"), Some(3.14));
1010 assert_eq!(from_str(~"+3.14"), Some(3.14));
1011 assert_eq!(from_str(~"-3.14"), Some(-3.14));
1012 assert_eq!(from_str(~"2.5E10"), Some(25000000000.));
1013 assert_eq!(from_str(~"2.5e10"), Some(25000000000.));
1014 assert_eq!(from_str(~"25000000000.E-10"), Some(2.5));
1015 assert_eq!(from_str(~"."), Some(0.));
1016 assert_eq!(from_str(~".e1"), Some(0.));
1017 assert_eq!(from_str(~".e-1"), Some(0.));
1018 assert_eq!(from_str(~"5."), Some(5.));
1019 assert_eq!(from_str(~".5"), Some(0.5));
1020 assert_eq!(from_str(~"0.5"), Some(0.5));
1021 assert_eq!(from_str(~"-.5"), Some(-0.5));
1022 assert_eq!(from_str(~"-5"), Some(-5.));
1023 assert_eq!(from_str(~"inf"), Some(infinity));
1024 assert_eq!(from_str(~"+inf"), Some(infinity));
1025 assert_eq!(from_str(~"-inf"), Some(neg_infinity));
1026 // note: NaN != NaN, hence this slightly complex test
1027 match from_str(~"NaN") {
1028 Some(f) => assert!(f.is_NaN()),
1031 // note: -0 == 0, hence these slightly more complex tests
1032 match from_str(~"-0") {
1033 Some(v) if v.is_zero() => assert!(v.is_negative()),
1036 match from_str(~"0") {
1037 Some(v) if v.is_zero() => assert!(v.is_positive()),
1041 assert!(from_str(~"").is_none());
1042 assert!(from_str(~"x").is_none());
1043 assert!(from_str(~" ").is_none());
1044 assert!(from_str(~" ").is_none());
1045 assert!(from_str(~"e").is_none());
1046 assert!(from_str(~"E").is_none());
1047 assert!(from_str(~"E1").is_none());
1048 assert!(from_str(~"1e1e1").is_none());
1049 assert!(from_str(~"1e1.1").is_none());
1050 assert!(from_str(~"1e1-1").is_none());
1054 pub fn test_from_str_hex() {
1055 assert_eq!(from_str_hex(~"a4"), Some(164.));
1056 assert_eq!(from_str_hex(~"a4.fe"), Some(164.9921875));
1057 assert_eq!(from_str_hex(~"-a4.fe"), Some(-164.9921875));
1058 assert_eq!(from_str_hex(~"+a4.fe"), Some(164.9921875));
1059 assert_eq!(from_str_hex(~"ff0P4"), Some(0xff00 as float));
1060 assert_eq!(from_str_hex(~"ff0p4"), Some(0xff00 as float));
1061 assert_eq!(from_str_hex(~"ff0p-4"), Some(0xff as float));
1062 assert_eq!(from_str_hex(~"."), Some(0.));
1063 assert_eq!(from_str_hex(~".p1"), Some(0.));
1064 assert_eq!(from_str_hex(~".p-1"), Some(0.));
1065 assert_eq!(from_str_hex(~"f."), Some(15.));
1066 assert_eq!(from_str_hex(~".f"), Some(0.9375));
1067 assert_eq!(from_str_hex(~"0.f"), Some(0.9375));
1068 assert_eq!(from_str_hex(~"-.f"), Some(-0.9375));
1069 assert_eq!(from_str_hex(~"-f"), Some(-15.));
1070 assert_eq!(from_str_hex(~"inf"), Some(infinity));
1071 assert_eq!(from_str_hex(~"+inf"), Some(infinity));
1072 assert_eq!(from_str_hex(~"-inf"), Some(neg_infinity));
1073 // note: NaN != NaN, hence this slightly complex test
1074 match from_str_hex(~"NaN") {
1075 Some(f) => assert!(f.is_NaN()),
1078 // note: -0 == 0, hence these slightly more complex tests
1079 match from_str_hex(~"-0") {
1080 Some(v) if v.is_zero() => assert!(v.is_negative()),
1083 match from_str_hex(~"0") {
1084 Some(v) if v.is_zero() => assert!(v.is_positive()),
1087 assert_eq!(from_str_hex(~"e"), Some(14.));
1088 assert_eq!(from_str_hex(~"E"), Some(14.));
1089 assert_eq!(from_str_hex(~"E1"), Some(225.));
1090 assert_eq!(from_str_hex(~"1e1e1"), Some(123361.));
1091 assert_eq!(from_str_hex(~"1e1.1"), Some(481.0625));
1093 assert!(from_str_hex(~"").is_none());
1094 assert!(from_str_hex(~"x").is_none());
1095 assert!(from_str_hex(~" ").is_none());
1096 assert!(from_str_hex(~" ").is_none());
1097 assert!(from_str_hex(~"p").is_none());
1098 assert!(from_str_hex(~"P").is_none());
1099 assert!(from_str_hex(~"P1").is_none());
1100 assert!(from_str_hex(~"1p1p1").is_none());
1101 assert!(from_str_hex(~"1p1.1").is_none());
1102 assert!(from_str_hex(~"1p1-1").is_none());
1106 pub fn test_to_str_hex() {
1107 assert_eq!(to_str_hex(164.), ~"a4");
1108 assert_eq!(to_str_hex(164.9921875), ~"a4.fe");
1109 assert_eq!(to_str_hex(-164.9921875), ~"-a4.fe");
1110 assert_eq!(to_str_hex(0xff00 as float), ~"ff00");
1111 assert_eq!(to_str_hex(-(0xff00 as float)), ~"-ff00");
1112 assert_eq!(to_str_hex(0.), ~"0");
1113 assert_eq!(to_str_hex(15.), ~"f");
1114 assert_eq!(to_str_hex(-15.), ~"-f");
1115 assert_eq!(to_str_hex(0.9375), ~"0.f");
1116 assert_eq!(to_str_hex(-0.9375), ~"-0.f");
1117 assert_eq!(to_str_hex(infinity), ~"inf");
1118 assert_eq!(to_str_hex(neg_infinity), ~"-inf");
1119 assert_eq!(to_str_hex(NaN), ~"NaN");
1120 assert_eq!(to_str_hex(0.), ~"0");
1121 assert_eq!(to_str_hex(-0.), ~"-0");
1125 pub fn test_to_str_radix() {
1126 assert_eq!(to_str_radix(36., 36u), ~"10");
1127 assert_eq!(to_str_radix(8.125, 2u), ~"1000.001");
1131 pub fn test_from_str_radix() {
1132 assert_eq!(from_str_radix(~"10", 36u), Some(36.));
1133 assert_eq!(from_str_radix(~"1000.001", 2u), Some(8.125));
1137 pub fn test_to_str_inf() {
1138 assert_eq!(to_str_digits(infinity, 10u), ~"inf");
1139 assert_eq!(to_str_digits(-infinity, 10u), ~"-inf");
1147 // indent-tabs-mode: nil
1148 // c-basic-offset: 4
1149 // buffer-file-coding-system: utf-8-unix