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
24 use num::{Zero, One, strconv};
27 pub use f64::{add, sub, mul, div, rem, lt, le, eq, ne, ge, gt};
28 pub use f64::logarithm;
29 pub use f64::{acos, asin, atan2, cbrt, ceil, copysign, cosh, floor};
30 pub use f64::{erf, erfc, exp, expm1, exp2, abs_sub};
31 pub use f64::{mul_add, fmax, fmin, next_after, frexp, hypot, ldexp};
32 pub use f64::{lgamma, ln, log_radix, ln1p, log10, log2, ilog_radix};
33 pub use f64::{modf, pow, powi, round, sinh, tanh, tgamma, trunc};
34 pub use f64::{j0, j1, jn, y0, y1, yn};
36 pub static NaN: float = 0.0/0.0;
38 pub static infinity: float = 1.0/0.0;
40 pub static neg_infinity: float = -1.0/0.0;
44 // FIXME (requires Issue #1433 to fix): replace with mathematical
45 // staticants from cmath.
46 /// Archimedes' staticant
47 pub static pi: float = 3.14159265358979323846264338327950288;
50 pub static frac_pi_2: float = 1.57079632679489661923132169163975144;
53 pub static frac_pi_4: float = 0.785398163397448309615660845819875721;
56 pub static frac_1_pi: float = 0.318309886183790671537767526745028724;
59 pub static frac_2_pi: float = 0.636619772367581343075535053490057448;
62 pub static frac_2_sqrtpi: float = 1.12837916709551257389615890312154517;
65 pub static sqrt2: float = 1.41421356237309504880168872420969808;
68 pub static frac_1_sqrt2: float = 0.707106781186547524400844362104849039;
71 pub static e: float = 2.71828182845904523536028747135266250;
74 pub static log2_e: float = 1.44269504088896340735992468100189214;
77 pub static log10_e: float = 0.434294481903251827651128918916605082;
80 pub static ln_2: float = 0.693147180559945309417232121458176568;
83 pub static ln_10: float = 2.30258509299404568401799145468436421;
87 // Section: String Conversions
91 /// Converts a float to a string
95 /// * num - The float value
98 pub fn to_str(num: float) -> ~str {
99 let (r, _) = strconv::to_str_common(
100 &num, 10u, true, strconv::SignNeg, strconv::DigAll);
105 /// Converts a float to a string in hexadecimal format
109 /// * num - The float value
112 pub fn to_str_hex(num: float) -> ~str {
113 let (r, _) = strconv::to_str_common(
114 &num, 16u, true, strconv::SignNeg, strconv::DigAll);
119 /// Converts a float to a string in a given radix
123 /// * num - The float value
124 /// * radix - The base to use
128 /// Fails if called on a special value like `inf`, `-inf` or `NaN` due to
129 /// possible misinterpretation of the result at higher bases. If those values
130 /// are expected, use `to_str_radix_special()` instead.
133 pub fn to_str_radix(num: float, radix: uint) -> ~str {
134 let (r, special) = strconv::to_str_common(
135 &num, radix, true, strconv::SignNeg, strconv::DigAll);
136 if special { fail!(~"number has a special value, \
137 try to_str_radix_special() if those are expected") }
142 /// Converts a float to a string in a given radix, and a flag indicating
143 /// whether it's a special value
147 /// * num - The float value
148 /// * radix - The base to use
151 pub fn to_str_radix_special(num: float, radix: uint) -> (~str, bool) {
152 strconv::to_str_common(&num, radix, true,
153 strconv::SignNeg, strconv::DigAll)
157 /// Converts a float to a string with exactly the number of
158 /// provided significant digits
162 /// * num - The float value
163 /// * digits - The number of significant digits
166 pub fn to_str_exact(num: float, digits: uint) -> ~str {
167 let (r, _) = strconv::to_str_common(
168 &num, 10u, true, strconv::SignNeg, strconv::DigExact(digits));
173 /// Converts a float to a string with a maximum number of
174 /// significant digits
178 /// * num - The float value
179 /// * digits - The number of significant digits
182 pub fn to_str_digits(num: float, digits: uint) -> ~str {
183 let (r, _) = strconv::to_str_common(
184 &num, 10u, true, strconv::SignNeg, strconv::DigMax(digits));
188 impl to_str::ToStr for float {
190 fn to_str(&self) -> ~str { to_str_digits(*self, 8) }
193 impl num::ToStrRadix for float {
195 fn to_str_radix(&self, radix: uint) -> ~str {
196 to_str_radix(*self, radix)
201 /// Convert a string in base 10 to a float.
202 /// Accepts a optional decimal exponent.
204 /// This function accepts strings such as
207 /// * '+3.14', equivalent to '3.14'
209 /// * '2.5E10', or equivalently, '2.5e10'
211 /// * '.' (understood as 0)
213 /// * '.5', or, equivalently, '0.5'
214 /// * '+inf', 'inf', '-inf', 'NaN'
216 /// Leading and trailing whitespace represent an error.
224 /// `none` if the string did not represent a valid number. Otherwise,
225 /// `Some(n)` where `n` is the floating-point number represented by `num`.
228 pub fn from_str(num: &str) -> Option<float> {
229 strconv::from_str_common(num, 10u, true, true, true,
230 strconv::ExpDec, false, false)
234 /// Convert a string in base 16 to a float.
235 /// Accepts a optional binary exponent.
237 /// This function accepts strings such as
240 /// * '+a4.fe', equivalent to 'a4.fe'
242 /// * '2b.aP128', or equivalently, '2b.ap128'
244 /// * '.' (understood as 0)
246 /// * '.c', or, equivalently, '0.c'
247 /// * '+inf', 'inf', '-inf', 'NaN'
249 /// Leading and trailing whitespace represent an error.
257 /// `none` if the string did not represent a valid number. Otherwise,
258 /// `Some(n)` where `n` is the floating-point number represented by `[num]`.
261 pub fn from_str_hex(num: &str) -> Option<float> {
262 strconv::from_str_common(num, 16u, true, true, true,
263 strconv::ExpBin, false, false)
267 /// Convert a string in an given base to a float.
269 /// Due to possible conflicts, this function does **not** accept
270 /// the special values `inf`, `-inf`, `+inf` and `NaN`, **nor**
271 /// does it recognize exponents of any kind.
273 /// Leading and trailing whitespace represent an error.
278 /// * radix - The base to use. Must lie in the range [2 .. 36]
282 /// `none` if the string did not represent a valid number. Otherwise,
283 /// `Some(n)` where `n` is the floating-point number represented by `num`.
286 pub fn from_str_radix(num: &str, radix: uint) -> Option<float> {
287 strconv::from_str_common(num, radix, true, true, false,
288 strconv::ExpNone, false, false)
291 impl FromStr for float {
293 fn from_str(val: &str) -> Option<float> { from_str(val) }
296 impl num::FromStrRadix for float {
298 fn from_str_radix(val: &str, radix: uint) -> Option<float> {
299 from_str_radix(val, radix)
304 // Section: Arithmetics
308 /// Compute the exponentiation of an integer by another integer as a float
313 /// * pow - The exponent
317 /// `NaN` if both `x` and `pow` are `0u`, otherwise `x^pow`
319 pub fn pow_with_uint(base: uint, pow: uint) -> float {
326 let mut my_pow = pow;
328 let mut multiplier = base as float;
329 while (my_pow > 0u) {
330 if my_pow % 2u == 1u {
331 total = total * multiplier;
334 multiplier *= multiplier;
340 pub fn abs(x: float) -> float {
341 f64::abs(x as f64) as float
344 pub fn sqrt(x: float) -> float {
345 f64::sqrt(x as f64) as float
348 pub fn atan(x: float) -> float {
349 f64::atan(x as f64) as float
352 pub fn sin(x: float) -> float {
353 f64::sin(x as f64) as float
356 pub fn cos(x: float) -> float {
357 f64::cos(x as f64) as float
360 pub fn tan(x: float) -> float {
361 f64::tan(x as f64) as float
364 impl Num for float {}
369 fn eq(&self, other: &float) -> bool { (*self) == (*other) }
371 fn ne(&self, other: &float) -> bool { (*self) != (*other) }
377 fn lt(&self, other: &float) -> bool { (*self) < (*other) }
379 fn le(&self, other: &float) -> bool { (*self) <= (*other) }
381 fn ge(&self, other: &float) -> bool { (*self) >= (*other) }
383 fn gt(&self, other: &float) -> bool { (*self) > (*other) }
386 impl Orderable for float {
387 /// Returns `NaN` if either of the numbers are `NaN`.
389 fn min(&self, other: &float) -> float {
390 (*self as f64).min(&(*other as f64)) as float
393 /// Returns `NaN` if either of the numbers are `NaN`.
395 fn max(&self, other: &float) -> float {
396 (*self as f64).max(&(*other as f64)) as float
399 /// Returns the number constrained within the range `mn <= self <= mx`.
400 /// If any of the numbers are `NaN` then `NaN` is returned.
402 fn clamp(&self, mn: &float, mx: &float) -> float {
403 (*self as f64).clamp(&(*mn as f64), &(*mx as f64)) as float
407 impl Zero for float {
409 fn zero() -> float { 0.0 }
411 /// Returns true if the number is equal to either `0.0` or `-0.0`
413 fn is_zero(&self) -> bool { *self == 0.0 || *self == -0.0 }
418 fn one() -> float { 1.0 }
421 impl Round for float {
422 /// Round half-way cases toward `neg_infinity`
424 fn floor(&self) -> float { floor(*self as f64) as float }
426 /// Round half-way cases toward `infinity`
428 fn ceil(&self) -> float { ceil(*self as f64) as float }
430 /// Round half-way cases away from `0.0`
432 fn round(&self) -> float { round(*self as f64) as float }
434 /// The integer part of the number (rounds towards `0.0`)
436 fn trunc(&self) -> float { trunc(*self as f64) as float }
439 /// The fractional part of the number, satisfying:
442 /// assert!(x == trunc(x) + fract(x))
446 fn fract(&self) -> float { *self - self.trunc() }
449 impl Fractional for float {
450 /// The reciprocal (multiplicative inverse) of the number
452 fn recip(&self) -> float { 1.0 / *self }
455 impl Algebraic for float {
457 fn pow(&self, n: float) -> float {
458 (*self as f64).pow(n as f64) as float
462 fn sqrt(&self) -> float {
463 (*self as f64).sqrt() as float
467 fn rsqrt(&self) -> float {
468 (*self as f64).rsqrt() as float
472 fn cbrt(&self) -> float {
473 (*self as f64).cbrt() as float
477 fn hypot(&self, other: float) -> float {
478 (*self as f64).hypot(other as f64) as float
482 impl Trigonometric for float {
484 fn sin(&self) -> float {
485 (*self as f64).sin() as float
489 fn cos(&self) -> float {
490 (*self as f64).cos() as float
494 fn tan(&self) -> float {
495 (*self as f64).tan() as float
499 fn asin(&self) -> float {
500 (*self as f64).asin() as float
504 fn acos(&self) -> float {
505 (*self as f64).acos() as float
509 fn atan(&self) -> float {
510 (*self as f64).atan() as float
514 fn atan2(&self, other: float) -> float {
515 (*self as f64).atan2(other as f64) as float
519 impl Exponential for float {
521 fn exp(&self) -> float {
522 (*self as f64).exp() as float
526 fn exp2(&self) -> float {
527 (*self as f64).exp2() as float
531 fn expm1(&self) -> float {
532 (*self as f64).expm1() as float
536 fn log(&self) -> float {
537 (*self as f64).log() as float
541 fn log2(&self) -> float {
542 (*self as f64).log2() as float
546 fn log10(&self) -> float {
547 (*self as f64).log10() as float
551 impl Hyperbolic for float {
553 fn sinh(&self) -> float {
554 (*self as f64).sinh() as float
558 fn cosh(&self) -> float {
559 (*self as f64).cosh() as float
563 fn tanh(&self) -> float {
564 (*self as f64).tanh() as float
568 impl Real for float {
569 /// Archimedes' constant
571 fn pi() -> float { 3.14159265358979323846264338327950288 }
575 fn two_pi() -> float { 6.28318530717958647692528676655900576 }
579 fn frac_pi_2() -> float { 1.57079632679489661923132169163975144 }
583 fn frac_pi_3() -> float { 1.04719755119659774615421446109316763 }
587 fn frac_pi_4() -> float { 0.785398163397448309615660845819875721 }
591 fn frac_pi_6() -> float { 0.52359877559829887307710723054658381 }
595 fn frac_pi_8() -> float { 0.39269908169872415480783042290993786 }
599 fn frac_1_pi() -> float { 0.318309886183790671537767526745028724 }
603 fn frac_2_pi() -> float { 0.636619772367581343075535053490057448 }
607 fn frac_2_sqrtpi() -> float { 1.12837916709551257389615890312154517 }
611 fn sqrt2() -> float { 1.41421356237309504880168872420969808 }
615 fn frac_1_sqrt2() -> float { 0.707106781186547524400844362104849039 }
619 fn e() -> float { 2.71828182845904523536028747135266250 }
623 fn log2_e() -> float { 1.44269504088896340735992468100189214 }
627 fn log10_e() -> float { 0.434294481903251827651128918916605082 }
631 fn log_2() -> float { 0.693147180559945309417232121458176568 }
635 fn log_10() -> float { 2.30258509299404568401799145468436421 }
637 /// Converts to degrees, assuming the number is in radians
639 fn to_degrees(&self) -> float { (*self as f64).to_degrees() as float }
641 /// Converts to radians, assuming the number is in degrees
643 fn to_radians(&self) -> float { (*self as f64).to_radians() as float }
646 impl RealExt for float {
648 fn lgamma(&self) -> (int, float) {
650 let result = lgamma(*self as f64, &mut sign);
651 (sign as int, result as float)
655 fn tgamma(&self) -> float { tgamma(*self as f64) as float }
658 fn j0(&self) -> float { j0(*self as f64) as float }
661 fn j1(&self) -> float { j1(*self as f64) as float }
664 fn jn(&self, n: int) -> float { jn(n as c_int, *self as f64) as float }
667 fn y0(&self) -> float { y0(*self as f64) as float }
670 fn y1(&self) -> float { y1(*self as f64) as float }
673 fn yn(&self, n: int) -> float { yn(n as c_int, *self as f64) as float }
677 impl Add<float,float> for float {
679 fn add(&self, other: &float) -> float { *self + *other }
683 impl Sub<float,float> for float {
685 fn sub(&self, other: &float) -> float { *self - *other }
689 impl Mul<float,float> for float {
691 fn mul(&self, other: &float) -> float { *self * *other }
695 impl Div<float,float> for float {
697 fn div(&self, other: &float) -> float { *self / *other }
700 #[cfg(stage0,notest)]
701 impl Modulo<float,float> for float {
703 fn modulo(&self, other: &float) -> float { *self % *other }
705 #[cfg(not(stage0),notest)]
706 impl Rem<float,float> for float {
708 fn rem(&self, other: &float) -> float { *self % *other }
711 impl Neg<float> for float {
713 fn neg(&self) -> float { -*self }
716 impl Signed for float {
717 /// Computes the absolute value. Returns `NaN` if the number is `NaN`.
719 fn abs(&self) -> float { abs(*self) }
724 /// - `1.0` if the number is positive, `+0.0` or `infinity`
725 /// - `-1.0` if the number is negative, `-0.0` or `neg_infinity`
726 /// - `NaN` if the number is NaN
729 fn signum(&self) -> float {
730 if self.is_NaN() { NaN } else { f64::copysign(1.0, *self as f64) as float }
733 /// Returns `true` if the number is positive, including `+0.0` and `infinity`
735 fn is_positive(&self) -> bool { *self > 0.0 || (1.0 / *self) == infinity }
737 /// Returns `true` if the number is negative, including `-0.0` and `neg_infinity`
739 fn is_negative(&self) -> bool { *self < 0.0 || (1.0 / *self) == neg_infinity }
742 impl Bounded for float {
744 fn min_value() -> float { Bounded::min_value::<f64>() as float }
747 fn max_value() -> float { Bounded::max_value::<f64>() as float }
750 impl Primitive for float {
752 fn bits() -> uint { Primitive::bits::<f64>() }
755 fn bytes() -> uint { Primitive::bytes::<f64>() }
758 impl Float for float {
760 fn NaN() -> float { 0.0 / 0.0 }
763 fn infinity() -> float { 1.0 / 0.0 }
766 fn neg_infinity() -> float { -1.0 / 0.0 }
769 fn neg_zero() -> float { -0.0 }
772 fn is_NaN(&self) -> bool { *self != *self }
775 fn mantissa_digits() -> uint { Float::mantissa_digits::<f64>() }
778 fn digits() -> uint { Float::digits::<f64>() }
781 fn epsilon() -> float { Float::epsilon::<f64>() as float }
784 fn min_exp() -> int { Float::min_exp::<f64>() }
787 fn max_exp() -> int { Float::max_exp::<f64>() }
790 fn min_10_exp() -> int { Float::min_10_exp::<f64>() }
793 fn max_10_exp() -> int { Float::max_10_exp::<f64>() }
795 /// Returns `true` if the number is infinite
797 fn is_infinite(&self) -> bool {
798 *self == Float::infinity() || *self == Float::neg_infinity()
801 /// Returns `true` if the number is finite
803 fn is_finite(&self) -> bool {
804 !(self.is_NaN() || self.is_infinite())
808 /// Fused multiply-add. Computes `(self * a) + b` with only one rounding error. This
809 /// produces a more accurate result with better performance than a separate multiplication
810 /// operation followed by an add.
813 fn mul_add(&self, a: float, b: float) -> float {
814 mul_add(*self as f64, a as f64, b as f64) as float
817 /// Returns the next representable floating-point value in the direction of `other`
819 fn next_after(&self, other: float) -> float {
820 next_after(*self as f64, other as f64) as float
829 macro_rules! assert_fuzzy_eq(
830 ($a:expr, $b:expr) => ({
832 if !((a - b).abs() < 1.0e-6) {
833 fail!(fmt!("The values were not approximately equal. Found: %? and %?", a, b));
840 num::test_num(10f, 2f);
845 assert_eq!(1f.min(&2f), 1f);
846 assert_eq!(2f.min(&1f), 1f);
851 assert_eq!(1f.max(&2f), 2f);
852 assert_eq!(2f.max(&1f), 2f);
857 assert_eq!(1f.clamp(&2f, &4f), 2f);
858 assert_eq!(8f.clamp(&2f, &4f), 4f);
859 assert_eq!(3f.clamp(&2f, &4f), 3f);
860 assert!(3f.clamp(&Float::NaN::<float>(), &4f).is_NaN());
861 assert!(3f.clamp(&2f, &Float::NaN::<float>()).is_NaN());
862 assert!(Float::NaN::<float>().clamp(&2f, &4f).is_NaN());
867 assert_fuzzy_eq!(1.0f.floor(), 1.0f);
868 assert_fuzzy_eq!(1.3f.floor(), 1.0f);
869 assert_fuzzy_eq!(1.5f.floor(), 1.0f);
870 assert_fuzzy_eq!(1.7f.floor(), 1.0f);
871 assert_fuzzy_eq!(0.0f.floor(), 0.0f);
872 assert_fuzzy_eq!((-0.0f).floor(), -0.0f);
873 assert_fuzzy_eq!((-1.0f).floor(), -1.0f);
874 assert_fuzzy_eq!((-1.3f).floor(), -2.0f);
875 assert_fuzzy_eq!((-1.5f).floor(), -2.0f);
876 assert_fuzzy_eq!((-1.7f).floor(), -2.0f);
881 assert_fuzzy_eq!(1.0f.ceil(), 1.0f);
882 assert_fuzzy_eq!(1.3f.ceil(), 2.0f);
883 assert_fuzzy_eq!(1.5f.ceil(), 2.0f);
884 assert_fuzzy_eq!(1.7f.ceil(), 2.0f);
885 assert_fuzzy_eq!(0.0f.ceil(), 0.0f);
886 assert_fuzzy_eq!((-0.0f).ceil(), -0.0f);
887 assert_fuzzy_eq!((-1.0f).ceil(), -1.0f);
888 assert_fuzzy_eq!((-1.3f).ceil(), -1.0f);
889 assert_fuzzy_eq!((-1.5f).ceil(), -1.0f);
890 assert_fuzzy_eq!((-1.7f).ceil(), -1.0f);
895 assert_fuzzy_eq!(1.0f.round(), 1.0f);
896 assert_fuzzy_eq!(1.3f.round(), 1.0f);
897 assert_fuzzy_eq!(1.5f.round(), 2.0f);
898 assert_fuzzy_eq!(1.7f.round(), 2.0f);
899 assert_fuzzy_eq!(0.0f.round(), 0.0f);
900 assert_fuzzy_eq!((-0.0f).round(), -0.0f);
901 assert_fuzzy_eq!((-1.0f).round(), -1.0f);
902 assert_fuzzy_eq!((-1.3f).round(), -1.0f);
903 assert_fuzzy_eq!((-1.5f).round(), -2.0f);
904 assert_fuzzy_eq!((-1.7f).round(), -2.0f);
909 assert_fuzzy_eq!(1.0f.trunc(), 1.0f);
910 assert_fuzzy_eq!(1.3f.trunc(), 1.0f);
911 assert_fuzzy_eq!(1.5f.trunc(), 1.0f);
912 assert_fuzzy_eq!(1.7f.trunc(), 1.0f);
913 assert_fuzzy_eq!(0.0f.trunc(), 0.0f);
914 assert_fuzzy_eq!((-0.0f).trunc(), -0.0f);
915 assert_fuzzy_eq!((-1.0f).trunc(), -1.0f);
916 assert_fuzzy_eq!((-1.3f).trunc(), -1.0f);
917 assert_fuzzy_eq!((-1.5f).trunc(), -1.0f);
918 assert_fuzzy_eq!((-1.7f).trunc(), -1.0f);
923 assert_fuzzy_eq!(1.0f.fract(), 0.0f);
924 assert_fuzzy_eq!(1.3f.fract(), 0.3f);
925 assert_fuzzy_eq!(1.5f.fract(), 0.5f);
926 assert_fuzzy_eq!(1.7f.fract(), 0.7f);
927 assert_fuzzy_eq!(0.0f.fract(), 0.0f);
928 assert_fuzzy_eq!((-0.0f).fract(), -0.0f);
929 assert_fuzzy_eq!((-1.0f).fract(), -0.0f);
930 assert_fuzzy_eq!((-1.3f).fract(), -0.3f);
931 assert_fuzzy_eq!((-1.5f).fract(), -0.5f);
932 assert_fuzzy_eq!((-1.7f).fract(), -0.7f);
936 fn test_real_consts() {
937 assert_fuzzy_eq!(Real::two_pi::<float>(), 2f * Real::pi::<float>());
938 assert_fuzzy_eq!(Real::frac_pi_2::<float>(), Real::pi::<float>() / 2f);
939 assert_fuzzy_eq!(Real::frac_pi_3::<float>(), Real::pi::<float>() / 3f);
940 assert_fuzzy_eq!(Real::frac_pi_4::<float>(), Real::pi::<float>() / 4f);
941 assert_fuzzy_eq!(Real::frac_pi_6::<float>(), Real::pi::<float>() / 6f);
942 assert_fuzzy_eq!(Real::frac_pi_8::<float>(), Real::pi::<float>() / 8f);
943 assert_fuzzy_eq!(Real::frac_1_pi::<float>(), 1f / Real::pi::<float>());
944 assert_fuzzy_eq!(Real::frac_2_pi::<float>(), 2f / Real::pi::<float>());
945 assert_fuzzy_eq!(Real::frac_2_sqrtpi::<float>(), 2f / Real::pi::<float>().sqrt());
946 assert_fuzzy_eq!(Real::sqrt2::<float>(), 2f.sqrt());
947 assert_fuzzy_eq!(Real::frac_1_sqrt2::<float>(), 1f / 2f.sqrt());
948 assert_fuzzy_eq!(Real::log2_e::<float>(), Real::e::<float>().log2());
949 assert_fuzzy_eq!(Real::log10_e::<float>(), Real::e::<float>().log10());
950 assert_fuzzy_eq!(Real::log_2::<float>(), 2f.log());
951 assert_fuzzy_eq!(Real::log_10::<float>(), 10f.log());
956 assert_eq!(infinity.abs(), infinity);
957 assert_eq!(1f.abs(), 1f);
958 assert_eq!(0f.abs(), 0f);
959 assert_eq!((-0f).abs(), 0f);
960 assert_eq!((-1f).abs(), 1f);
961 assert_eq!(neg_infinity.abs(), infinity);
962 assert_eq!((1f/neg_infinity).abs(), 0f);
963 assert!(NaN.abs().is_NaN());
965 assert_eq!(infinity.signum(), 1f);
966 assert_eq!(1f.signum(), 1f);
967 assert_eq!(0f.signum(), 1f);
968 assert_eq!((-0f).signum(), -1f);
969 assert_eq!((-1f).signum(), -1f);
970 assert_eq!(neg_infinity.signum(), -1f);
971 assert_eq!((1f/neg_infinity).signum(), -1f);
972 assert!(NaN.signum().is_NaN());
974 assert!(infinity.is_positive());
975 assert!(1f.is_positive());
976 assert!(0f.is_positive());
977 assert!(!(-0f).is_positive());
978 assert!(!(-1f).is_positive());
979 assert!(!neg_infinity.is_positive());
980 assert!(!(1f/neg_infinity).is_positive());
981 assert!(!NaN.is_positive());
983 assert!(!infinity.is_negative());
984 assert!(!1f.is_negative());
985 assert!(!0f.is_negative());
986 assert!((-0f).is_negative());
987 assert!((-1f).is_negative());
988 assert!(neg_infinity.is_negative());
989 assert!((1f/neg_infinity).is_negative());
990 assert!(!NaN.is_negative());
994 fn test_primitive() {
995 assert_eq!(Primitive::bits::<float>(), sys::size_of::<float>() * 8);
996 assert_eq!(Primitive::bytes::<float>(), sys::size_of::<float>());
1000 pub fn test_to_str_exact_do_decimal() {
1001 let s = to_str_exact(5.0, 4u);
1002 assert_eq!(s, ~"5.0000");
1006 pub fn test_from_str() {
1007 assert_eq!(from_str(~"3"), Some(3.));
1008 assert_eq!(from_str(~"3.14"), Some(3.14));
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(~"2.5E10"), Some(25000000000.));
1012 assert_eq!(from_str(~"2.5e10"), Some(25000000000.));
1013 assert_eq!(from_str(~"25000000000.E-10"), Some(2.5));
1014 assert_eq!(from_str(~"."), Some(0.));
1015 assert_eq!(from_str(~".e1"), Some(0.));
1016 assert_eq!(from_str(~".e-1"), Some(0.));
1017 assert_eq!(from_str(~"5."), Some(5.));
1018 assert_eq!(from_str(~".5"), Some(0.5));
1019 assert_eq!(from_str(~"0.5"), Some(0.5));
1020 assert_eq!(from_str(~"-.5"), Some(-0.5));
1021 assert_eq!(from_str(~"-5"), Some(-5.));
1022 assert_eq!(from_str(~"inf"), Some(infinity));
1023 assert_eq!(from_str(~"+inf"), Some(infinity));
1024 assert_eq!(from_str(~"-inf"), Some(neg_infinity));
1025 // note: NaN != NaN, hence this slightly complex test
1026 match from_str(~"NaN") {
1027 Some(f) => assert!(f.is_NaN()),
1030 // note: -0 == 0, hence these slightly more complex tests
1031 match from_str(~"-0") {
1032 Some(v) if v.is_zero() => assert!(v.is_negative()),
1035 match from_str(~"0") {
1036 Some(v) if v.is_zero() => assert!(v.is_positive()),
1040 assert!(from_str(~"").is_none());
1041 assert!(from_str(~"x").is_none());
1042 assert!(from_str(~" ").is_none());
1043 assert!(from_str(~" ").is_none());
1044 assert!(from_str(~"e").is_none());
1045 assert!(from_str(~"E").is_none());
1046 assert!(from_str(~"E1").is_none());
1047 assert!(from_str(~"1e1e1").is_none());
1048 assert!(from_str(~"1e1.1").is_none());
1049 assert!(from_str(~"1e1-1").is_none());
1053 pub fn test_from_str_hex() {
1054 assert_eq!(from_str_hex(~"a4"), Some(164.));
1055 assert_eq!(from_str_hex(~"a4.fe"), Some(164.9921875));
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(~"ff0P4"), Some(0xff00 as float));
1059 assert_eq!(from_str_hex(~"ff0p4"), Some(0xff00 as float));
1060 assert_eq!(from_str_hex(~"ff0p-4"), Some(0xff as float));
1061 assert_eq!(from_str_hex(~"."), Some(0.));
1062 assert_eq!(from_str_hex(~".p1"), Some(0.));
1063 assert_eq!(from_str_hex(~".p-1"), Some(0.));
1064 assert_eq!(from_str_hex(~"f."), Some(15.));
1065 assert_eq!(from_str_hex(~".f"), Some(0.9375));
1066 assert_eq!(from_str_hex(~"0.f"), Some(0.9375));
1067 assert_eq!(from_str_hex(~"-.f"), Some(-0.9375));
1068 assert_eq!(from_str_hex(~"-f"), Some(-15.));
1069 assert_eq!(from_str_hex(~"inf"), Some(infinity));
1070 assert_eq!(from_str_hex(~"+inf"), Some(infinity));
1071 assert_eq!(from_str_hex(~"-inf"), Some(neg_infinity));
1072 // note: NaN != NaN, hence this slightly complex test
1073 match from_str_hex(~"NaN") {
1074 Some(f) => assert!(f.is_NaN()),
1077 // note: -0 == 0, hence these slightly more complex tests
1078 match from_str_hex(~"-0") {
1079 Some(v) if v.is_zero() => assert!(v.is_negative()),
1082 match from_str_hex(~"0") {
1083 Some(v) if v.is_zero() => assert!(v.is_positive()),
1086 assert_eq!(from_str_hex(~"e"), Some(14.));
1087 assert_eq!(from_str_hex(~"E"), Some(14.));
1088 assert_eq!(from_str_hex(~"E1"), Some(225.));
1089 assert_eq!(from_str_hex(~"1e1e1"), Some(123361.));
1090 assert_eq!(from_str_hex(~"1e1.1"), Some(481.0625));
1092 assert!(from_str_hex(~"").is_none());
1093 assert!(from_str_hex(~"x").is_none());
1094 assert!(from_str_hex(~" ").is_none());
1095 assert!(from_str_hex(~" ").is_none());
1096 assert!(from_str_hex(~"p").is_none());
1097 assert!(from_str_hex(~"P").is_none());
1098 assert!(from_str_hex(~"P1").is_none());
1099 assert!(from_str_hex(~"1p1p1").is_none());
1100 assert!(from_str_hex(~"1p1.1").is_none());
1101 assert!(from_str_hex(~"1p1-1").is_none());
1105 pub fn test_to_str_hex() {
1106 assert_eq!(to_str_hex(164.), ~"a4");
1107 assert_eq!(to_str_hex(164.9921875), ~"a4.fe");
1108 assert_eq!(to_str_hex(-164.9921875), ~"-a4.fe");
1109 assert_eq!(to_str_hex(0xff00 as float), ~"ff00");
1110 assert_eq!(to_str_hex(-(0xff00 as float)), ~"-ff00");
1111 assert_eq!(to_str_hex(0.), ~"0");
1112 assert_eq!(to_str_hex(15.), ~"f");
1113 assert_eq!(to_str_hex(-15.), ~"-f");
1114 assert_eq!(to_str_hex(0.9375), ~"0.f");
1115 assert_eq!(to_str_hex(-0.9375), ~"-0.f");
1116 assert_eq!(to_str_hex(infinity), ~"inf");
1117 assert_eq!(to_str_hex(neg_infinity), ~"-inf");
1118 assert_eq!(to_str_hex(NaN), ~"NaN");
1119 assert_eq!(to_str_hex(0.), ~"0");
1120 assert_eq!(to_str_hex(-0.), ~"-0");
1124 pub fn test_to_str_radix() {
1125 assert_eq!(to_str_radix(36., 36u), ~"10");
1126 assert_eq!(to_str_radix(8.125, 2u), ~"1000.001");
1130 pub fn test_from_str_radix() {
1131 assert_eq!(from_str_radix(~"10", 36u), Some(36.));
1132 assert_eq!(from_str_radix(~"1000.001", 2u), Some(8.125));
1136 pub fn test_to_str_inf() {
1137 assert_eq!(to_str_digits(infinity, 10u), ~"inf");
1138 assert_eq!(to_str_digits(-infinity, 10u), ~"-inf");