]> git.lizzy.rs Git - rust.git/blob - src/libcore/num/float.rs
libcore: Export core::from_str::FromStr from core::prelude
[rust.git] / src / libcore / num / float.rs
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.
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 `float`
12
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.
16
17
18 // export when m_float == c_double
19
20
21 // PORT this must match in width according to architecture
22
23 use libc::c_int;
24 use num::{Zero, One, strconv};
25 use prelude::*;
26
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};
35
36 pub static NaN: float = 0.0/0.0;
37
38 pub static infinity: float = 1.0/0.0;
39
40 pub static neg_infinity: float = -1.0/0.0;
41
42 /* Module: consts */
43 pub mod consts {
44     // FIXME (requires Issue #1433 to fix): replace with mathematical
45     // staticants from cmath.
46     /// Archimedes' staticant
47     pub static pi: float = 3.14159265358979323846264338327950288;
48
49     /// pi/2.0
50     pub static frac_pi_2: float = 1.57079632679489661923132169163975144;
51
52     /// pi/4.0
53     pub static frac_pi_4: float = 0.785398163397448309615660845819875721;
54
55     /// 1.0/pi
56     pub static frac_1_pi: float = 0.318309886183790671537767526745028724;
57
58     /// 2.0/pi
59     pub static frac_2_pi: float = 0.636619772367581343075535053490057448;
60
61     /// 2.0/sqrt(pi)
62     pub static frac_2_sqrtpi: float = 1.12837916709551257389615890312154517;
63
64     /// sqrt(2.0)
65     pub static sqrt2: float = 1.41421356237309504880168872420969808;
66
67     /// 1.0/sqrt(2.0)
68     pub static frac_1_sqrt2: float = 0.707106781186547524400844362104849039;
69
70     /// Euler's number
71     pub static e: float = 2.71828182845904523536028747135266250;
72
73     /// log2(e)
74     pub static log2_e: float = 1.44269504088896340735992468100189214;
75
76     /// log10(e)
77     pub static log10_e: float = 0.434294481903251827651128918916605082;
78
79     /// ln(2.0)
80     pub static ln_2: float = 0.693147180559945309417232121458176568;
81
82     /// ln(10.0)
83     pub static ln_10: float = 2.30258509299404568401799145468436421;
84 }
85
86 //
87 // Section: String Conversions
88 //
89
90 ///
91 /// Converts a float to a string
92 ///
93 /// # Arguments
94 ///
95 /// * num - The float value
96 ///
97 #[inline(always)]
98 pub fn to_str(num: float) -> ~str {
99     let (r, _) = strconv::to_str_common(
100         &num, 10u, true, strconv::SignNeg, strconv::DigAll);
101     r
102 }
103
104 ///
105 /// Converts a float to a string in hexadecimal format
106 ///
107 /// # Arguments
108 ///
109 /// * num - The float value
110 ///
111 #[inline(always)]
112 pub fn to_str_hex(num: float) -> ~str {
113     let (r, _) = strconv::to_str_common(
114         &num, 16u, true, strconv::SignNeg, strconv::DigAll);
115     r
116 }
117
118 ///
119 /// Converts a float to a string in a given radix
120 ///
121 /// # Arguments
122 ///
123 /// * num - The float value
124 /// * radix - The base to use
125 ///
126 /// # Failure
127 ///
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.
131 ///
132 #[inline(always)]
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") }
138     r
139 }
140
141 ///
142 /// Converts a float to a string in a given radix, and a flag indicating
143 /// whether it's a special value
144 ///
145 /// # Arguments
146 ///
147 /// * num - The float value
148 /// * radix - The base to use
149 ///
150 #[inline(always)]
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)
154 }
155
156 ///
157 /// Converts a float to a string with exactly the number of
158 /// provided significant digits
159 ///
160 /// # Arguments
161 ///
162 /// * num - The float value
163 /// * digits - The number of significant digits
164 ///
165 #[inline(always)]
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));
169     r
170 }
171
172 ///
173 /// Converts a float to a string with a maximum number of
174 /// significant digits
175 ///
176 /// # Arguments
177 ///
178 /// * num - The float value
179 /// * digits - The number of significant digits
180 ///
181 #[inline(always)]
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));
185     r
186 }
187
188 impl to_str::ToStr for float {
189     #[inline(always)]
190     fn to_str(&self) -> ~str { to_str_digits(*self, 8) }
191 }
192
193 impl num::ToStrRadix for float {
194     #[inline(always)]
195     fn to_str_radix(&self, radix: uint) -> ~str {
196         to_str_radix(*self, radix)
197     }
198 }
199
200 ///
201 /// Convert a string in base 10 to a float.
202 /// Accepts a optional decimal exponent.
203 ///
204 /// This function accepts strings such as
205 ///
206 /// * '3.14'
207 /// * '+3.14', equivalent to '3.14'
208 /// * '-3.14'
209 /// * '2.5E10', or equivalently, '2.5e10'
210 /// * '2.5E-10'
211 /// * '.' (understood as 0)
212 /// * '5.'
213 /// * '.5', or, equivalently,  '0.5'
214 /// * '+inf', 'inf', '-inf', 'NaN'
215 ///
216 /// Leading and trailing whitespace represent an error.
217 ///
218 /// # Arguments
219 ///
220 /// * num - A string
221 ///
222 /// # Return value
223 ///
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`.
226 ///
227 #[inline(always)]
228 pub fn from_str(num: &str) -> Option<float> {
229     strconv::from_str_common(num, 10u, true, true, true,
230                              strconv::ExpDec, false, false)
231 }
232
233 ///
234 /// Convert a string in base 16 to a float.
235 /// Accepts a optional binary exponent.
236 ///
237 /// This function accepts strings such as
238 ///
239 /// * 'a4.fe'
240 /// * '+a4.fe', equivalent to 'a4.fe'
241 /// * '-a4.fe'
242 /// * '2b.aP128', or equivalently, '2b.ap128'
243 /// * '2b.aP-128'
244 /// * '.' (understood as 0)
245 /// * 'c.'
246 /// * '.c', or, equivalently,  '0.c'
247 /// * '+inf', 'inf', '-inf', 'NaN'
248 ///
249 /// Leading and trailing whitespace represent an error.
250 ///
251 /// # Arguments
252 ///
253 /// * num - A string
254 ///
255 /// # Return value
256 ///
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]`.
259 ///
260 #[inline(always)]
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)
264 }
265
266 ///
267 /// Convert a string in an given base to a float.
268 ///
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.
272 ///
273 /// Leading and trailing whitespace represent an error.
274 ///
275 /// # Arguments
276 ///
277 /// * num - A string
278 /// * radix - The base to use. Must lie in the range [2 .. 36]
279 ///
280 /// # Return value
281 ///
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`.
284 ///
285 #[inline(always)]
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)
289 }
290
291 impl FromStr for float {
292     #[inline(always)]
293     fn from_str(val: &str) -> Option<float> { from_str(val) }
294 }
295
296 impl num::FromStrRadix for float {
297     #[inline(always)]
298     fn from_str_radix(val: &str, radix: uint) -> Option<float> {
299         from_str_radix(val, radix)
300     }
301 }
302
303 //
304 // Section: Arithmetics
305 //
306
307 ///
308 /// Compute the exponentiation of an integer by another integer as a float
309 ///
310 /// # Arguments
311 ///
312 /// * x - The base
313 /// * pow - The exponent
314 ///
315 /// # Return value
316 ///
317 /// `NaN` if both `x` and `pow` are `0u`, otherwise `x^pow`
318 ///
319 pub fn pow_with_uint(base: uint, pow: uint) -> float {
320     if base == 0u {
321         if pow == 0u {
322             return NaN as float;
323         }
324         return 0.;
325     }
326     let mut my_pow     = pow;
327     let mut total      = 1f;
328     let mut multiplier = base as float;
329     while (my_pow > 0u) {
330         if my_pow % 2u == 1u {
331             total = total * multiplier;
332         }
333         my_pow     /= 2u;
334         multiplier *= multiplier;
335     }
336     return total;
337 }
338
339 #[inline(always)]
340 pub fn abs(x: float) -> float {
341     f64::abs(x as f64) as float
342 }
343 #[inline(always)]
344 pub fn sqrt(x: float) -> float {
345     f64::sqrt(x as f64) as float
346 }
347 #[inline(always)]
348 pub fn atan(x: float) -> float {
349     f64::atan(x as f64) as float
350 }
351 #[inline(always)]
352 pub fn sin(x: float) -> float {
353     f64::sin(x as f64) as float
354 }
355 #[inline(always)]
356 pub fn cos(x: float) -> float {
357     f64::cos(x as f64) as float
358 }
359 #[inline(always)]
360 pub fn tan(x: float) -> float {
361     f64::tan(x as f64) as float
362 }
363
364 impl Num for float {}
365
366 #[cfg(notest)]
367 impl Eq for float {
368     #[inline(always)]
369     fn eq(&self, other: &float) -> bool { (*self) == (*other) }
370     #[inline(always)]
371     fn ne(&self, other: &float) -> bool { (*self) != (*other) }
372 }
373
374 #[cfg(notest)]
375 impl Ord for float {
376     #[inline(always)]
377     fn lt(&self, other: &float) -> bool { (*self) < (*other) }
378     #[inline(always)]
379     fn le(&self, other: &float) -> bool { (*self) <= (*other) }
380     #[inline(always)]
381     fn ge(&self, other: &float) -> bool { (*self) >= (*other) }
382     #[inline(always)]
383     fn gt(&self, other: &float) -> bool { (*self) > (*other) }
384 }
385
386 impl Orderable for float {
387     /// Returns `NaN` if either of the numbers are `NaN`.
388     #[inline(always)]
389     fn min(&self, other: &float) -> float {
390         (*self as f64).min(&(*other as f64)) as float
391     }
392
393     /// Returns `NaN` if either of the numbers are `NaN`.
394     #[inline(always)]
395     fn max(&self, other: &float) -> float {
396         (*self as f64).max(&(*other as f64)) as float
397     }
398
399     /// Returns the number constrained within the range `mn <= self <= mx`.
400     /// If any of the numbers are `NaN` then `NaN` is returned.
401     #[inline(always)]
402     fn clamp(&self, mn: &float, mx: &float) -> float {
403         (*self as f64).clamp(&(*mn as f64), &(*mx as f64)) as float
404     }
405 }
406
407 impl Zero for float {
408     #[inline(always)]
409     fn zero() -> float { 0.0 }
410
411     /// Returns true if the number is equal to either `0.0` or `-0.0`
412     #[inline(always)]
413     fn is_zero(&self) -> bool { *self == 0.0 || *self == -0.0 }
414 }
415
416 impl One for float {
417     #[inline(always)]
418     fn one() -> float { 1.0 }
419 }
420
421 impl Round for float {
422     /// Round half-way cases toward `neg_infinity`
423     #[inline(always)]
424     fn floor(&self) -> float { floor(*self as f64) as float }
425
426     /// Round half-way cases toward `infinity`
427     #[inline(always)]
428     fn ceil(&self) -> float { ceil(*self as f64) as float }
429
430     /// Round half-way cases away from `0.0`
431     #[inline(always)]
432     fn round(&self) -> float { round(*self as f64) as float }
433
434     /// The integer part of the number (rounds towards `0.0`)
435     #[inline(always)]
436     fn trunc(&self) -> float { trunc(*self as f64) as float }
437
438     ///
439     /// The fractional part of the number, satisfying:
440     ///
441     /// ~~~
442     /// assert!(x == trunc(x) + fract(x))
443     /// ~~~
444     ///
445     #[inline(always)]
446     fn fract(&self) -> float { *self - self.trunc() }
447 }
448
449 impl Fractional for float {
450     /// The reciprocal (multiplicative inverse) of the number
451     #[inline(always)]
452     fn recip(&self) -> float { 1.0 / *self }
453 }
454
455 impl Algebraic for float {
456     #[inline(always)]
457     fn pow(&self, n: float) -> float {
458         (*self as f64).pow(n as f64) as float
459     }
460
461     #[inline(always)]
462     fn sqrt(&self) -> float {
463         (*self as f64).sqrt() as float
464     }
465
466     #[inline(always)]
467     fn rsqrt(&self) -> float {
468         (*self as f64).rsqrt() as float
469     }
470
471     #[inline(always)]
472     fn cbrt(&self) -> float {
473         (*self as f64).cbrt() as float
474     }
475
476     #[inline(always)]
477     fn hypot(&self, other: float) -> float {
478         (*self as f64).hypot(other as f64) as float
479     }
480 }
481
482 impl Trigonometric for float {
483     #[inline(always)]
484     fn sin(&self) -> float {
485         (*self as f64).sin() as float
486     }
487
488     #[inline(always)]
489     fn cos(&self) -> float {
490         (*self as f64).cos() as float
491     }
492
493     #[inline(always)]
494     fn tan(&self) -> float {
495         (*self as f64).tan() as float
496     }
497
498     #[inline(always)]
499     fn asin(&self) -> float {
500         (*self as f64).asin() as float
501     }
502
503     #[inline(always)]
504     fn acos(&self) -> float {
505         (*self as f64).acos() as float
506     }
507
508     #[inline(always)]
509     fn atan(&self) -> float {
510         (*self as f64).atan() as float
511     }
512
513     #[inline(always)]
514     fn atan2(&self, other: float) -> float {
515         (*self as f64).atan2(other as f64) as float
516     }
517 }
518
519 impl Exponential for float {
520     #[inline(always)]
521     fn exp(&self) -> float {
522         (*self as f64).exp() as float
523     }
524
525     #[inline(always)]
526     fn exp2(&self) -> float {
527         (*self as f64).exp2() as float
528     }
529
530     #[inline(always)]
531     fn expm1(&self) -> float {
532         (*self as f64).expm1() as float
533     }
534
535     #[inline(always)]
536     fn log(&self) -> float {
537         (*self as f64).log() as float
538     }
539
540     #[inline(always)]
541     fn log2(&self) -> float {
542         (*self as f64).log2() as float
543     }
544
545     #[inline(always)]
546     fn log10(&self) -> float {
547         (*self as f64).log10() as float
548     }
549 }
550
551 impl Hyperbolic for float {
552     #[inline(always)]
553     fn sinh(&self) -> float {
554         (*self as f64).sinh() as float
555     }
556
557     #[inline(always)]
558     fn cosh(&self) -> float {
559         (*self as f64).cosh() as float
560     }
561
562     #[inline(always)]
563     fn tanh(&self) -> float {
564         (*self as f64).tanh() as float
565     }
566 }
567
568 impl Real for float {
569     /// Archimedes' constant
570     #[inline(always)]
571     fn pi() -> float { 3.14159265358979323846264338327950288 }
572
573     /// 2.0 * pi
574     #[inline(always)]
575     fn two_pi() -> float { 6.28318530717958647692528676655900576 }
576
577     /// pi / 2.0
578     #[inline(always)]
579     fn frac_pi_2() -> float { 1.57079632679489661923132169163975144 }
580
581     /// pi / 3.0
582     #[inline(always)]
583     fn frac_pi_3() -> float { 1.04719755119659774615421446109316763 }
584
585     /// pi / 4.0
586     #[inline(always)]
587     fn frac_pi_4() -> float { 0.785398163397448309615660845819875721 }
588
589     /// pi / 6.0
590     #[inline(always)]
591     fn frac_pi_6() -> float { 0.52359877559829887307710723054658381 }
592
593     /// pi / 8.0
594     #[inline(always)]
595     fn frac_pi_8() -> float { 0.39269908169872415480783042290993786 }
596
597     /// 1.0 / pi
598     #[inline(always)]
599     fn frac_1_pi() -> float { 0.318309886183790671537767526745028724 }
600
601     /// 2.0 / pi
602     #[inline(always)]
603     fn frac_2_pi() -> float { 0.636619772367581343075535053490057448 }
604
605     /// 2 .0/ sqrt(pi)
606     #[inline(always)]
607     fn frac_2_sqrtpi() -> float { 1.12837916709551257389615890312154517 }
608
609     /// sqrt(2.0)
610     #[inline(always)]
611     fn sqrt2() -> float { 1.41421356237309504880168872420969808 }
612
613     /// 1.0 / sqrt(2.0)
614     #[inline(always)]
615     fn frac_1_sqrt2() -> float { 0.707106781186547524400844362104849039 }
616
617     /// Euler's number
618     #[inline(always)]
619     fn e() -> float { 2.71828182845904523536028747135266250 }
620
621     /// log2(e)
622     #[inline(always)]
623     fn log2_e() -> float { 1.44269504088896340735992468100189214 }
624
625     /// log10(e)
626     #[inline(always)]
627     fn log10_e() -> float { 0.434294481903251827651128918916605082 }
628
629     /// log(2.0)
630     #[inline(always)]
631     fn log_2() -> float { 0.693147180559945309417232121458176568 }
632
633     /// log(10.0)
634     #[inline(always)]
635     fn log_10() -> float { 2.30258509299404568401799145468436421 }
636
637     /// Converts to degrees, assuming the number is in radians
638     #[inline(always)]
639     fn to_degrees(&self) -> float { (*self as f64).to_degrees() as float }
640
641     /// Converts to radians, assuming the number is in degrees
642     #[inline(always)]
643     fn to_radians(&self) -> float { (*self as f64).to_radians() as float }
644 }
645
646 impl RealExt for float {
647     #[inline(always)]
648     fn lgamma(&self) -> (int, float) {
649         let mut sign = 0;
650         let result = lgamma(*self as f64, &mut sign);
651         (sign as int, result as float)
652     }
653
654     #[inline(always)]
655     fn tgamma(&self) -> float { tgamma(*self as f64) as float }
656
657     #[inline(always)]
658     fn j0(&self) -> float { j0(*self as f64) as float }
659
660     #[inline(always)]
661     fn j1(&self) -> float { j1(*self as f64) as float }
662
663     #[inline(always)]
664     fn jn(&self, n: int) -> float { jn(n as c_int, *self as f64) as float }
665
666     #[inline(always)]
667     fn y0(&self) -> float { y0(*self as f64) as float }
668
669     #[inline(always)]
670     fn y1(&self) -> float { y1(*self as f64) as float }
671
672     #[inline(always)]
673     fn yn(&self, n: int) -> float { yn(n as c_int, *self as f64) as float }
674 }
675
676 #[cfg(notest)]
677 impl Add<float,float> for float {
678     #[inline(always)]
679     fn add(&self, other: &float) -> float { *self + *other }
680 }
681
682 #[cfg(notest)]
683 impl Sub<float,float> for float {
684     #[inline(always)]
685     fn sub(&self, other: &float) -> float { *self - *other }
686 }
687
688 #[cfg(notest)]
689 impl Mul<float,float> for float {
690     #[inline(always)]
691     fn mul(&self, other: &float) -> float { *self * *other }
692 }
693
694 #[cfg(notest)]
695 impl Div<float,float> for float {
696     #[inline(always)]
697     fn div(&self, other: &float) -> float { *self / *other }
698 }
699
700 #[cfg(stage0,notest)]
701 impl Modulo<float,float> for float {
702     #[inline(always)]
703     fn modulo(&self, other: &float) -> float { *self % *other }
704 }
705 #[cfg(not(stage0),notest)]
706 impl Rem<float,float> for float {
707     #[inline(always)]
708     fn rem(&self, other: &float) -> float { *self % *other }
709 }
710 #[cfg(notest)]
711 impl Neg<float> for float {
712     #[inline(always)]
713     fn neg(&self) -> float { -*self }
714 }
715
716 impl Signed for float {
717     /// Computes the absolute value. Returns `NaN` if the number is `NaN`.
718     #[inline(always)]
719     fn abs(&self) -> float { abs(*self) }
720
721     ///
722     /// # Returns
723     ///
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
727     ///
728     #[inline(always)]
729     fn signum(&self) -> float {
730         if self.is_NaN() { NaN } else { f64::copysign(1.0, *self as f64) as float }
731     }
732
733     /// Returns `true` if the number is positive, including `+0.0` and `infinity`
734     #[inline(always)]
735     fn is_positive(&self) -> bool { *self > 0.0 || (1.0 / *self) == infinity }
736
737     /// Returns `true` if the number is negative, including `-0.0` and `neg_infinity`
738     #[inline(always)]
739     fn is_negative(&self) -> bool { *self < 0.0 || (1.0 / *self) == neg_infinity }
740 }
741
742 impl Bounded for float {
743     #[inline(always)]
744     fn min_value() -> float { Bounded::min_value::<f64>() as float }
745
746     #[inline(always)]
747     fn max_value() -> float { Bounded::max_value::<f64>() as float }
748 }
749
750 impl Primitive for float {
751     #[inline(always)]
752     fn bits() -> uint { Primitive::bits::<f64>() }
753
754     #[inline(always)]
755     fn bytes() -> uint { Primitive::bytes::<f64>() }
756 }
757
758 impl Float for float {
759     #[inline(always)]
760     fn NaN() -> float { 0.0 / 0.0 }
761
762     #[inline(always)]
763     fn infinity() -> float { 1.0 / 0.0 }
764
765     #[inline(always)]
766     fn neg_infinity() -> float { -1.0 / 0.0 }
767
768     #[inline(always)]
769     fn neg_zero() -> float { -0.0 }
770
771     #[inline(always)]
772     fn is_NaN(&self) -> bool { *self != *self }
773
774     #[inline(always)]
775     fn mantissa_digits() -> uint { Float::mantissa_digits::<f64>() }
776
777     #[inline(always)]
778     fn digits() -> uint { Float::digits::<f64>() }
779
780     #[inline(always)]
781     fn epsilon() -> float { Float::epsilon::<f64>() as float }
782
783     #[inline(always)]
784     fn min_exp() -> int { Float::min_exp::<f64>() }
785
786     #[inline(always)]
787     fn max_exp() -> int { Float::max_exp::<f64>() }
788
789     #[inline(always)]
790     fn min_10_exp() -> int { Float::min_10_exp::<f64>() }
791
792     #[inline(always)]
793     fn max_10_exp() -> int { Float::max_10_exp::<f64>() }
794
795     /// Returns `true` if the number is infinite
796     #[inline(always)]
797     fn is_infinite(&self) -> bool {
798         *self == Float::infinity() || *self == Float::neg_infinity()
799     }
800
801     /// Returns `true` if the number is finite
802     #[inline(always)]
803     fn is_finite(&self) -> bool {
804         !(self.is_NaN() || self.is_infinite())
805     }
806
807     ///
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.
811     ///
812     #[inline(always)]
813     fn mul_add(&self, a: float, b: float) -> float {
814         mul_add(*self as f64, a as f64, b as f64) as float
815     }
816
817     /// Returns the next representable floating-point value in the direction of `other`
818     #[inline(always)]
819     fn next_after(&self, other: float) -> float {
820         next_after(*self as f64, other as f64) as float
821     }
822 }
823
824 #[cfg(test)]
825 mod tests {
826     use super::*;
827     use prelude::*;
828
829     macro_rules! assert_fuzzy_eq(
830         ($a:expr, $b:expr) => ({
831             let a = $a, b = $b;
832             if !((a - b).abs() < 1.0e-6) {
833                 fail!(fmt!("The values were not approximately equal. Found: %? and %?", a, b));
834             }
835         })
836     )
837
838     #[test]
839     fn test_num() {
840         num::test_num(10f, 2f);
841     }
842
843     #[test]
844     fn test_min() {
845         assert_eq!(1f.min(&2f), 1f);
846         assert_eq!(2f.min(&1f), 1f);
847     }
848
849     #[test]
850     fn test_max() {
851         assert_eq!(1f.max(&2f), 2f);
852         assert_eq!(2f.max(&1f), 2f);
853     }
854
855     #[test]
856     fn test_clamp() {
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());
863     }
864
865     #[test]
866     fn test_floor() {
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);
877     }
878
879     #[test]
880     fn test_ceil() {
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);
891     }
892
893     #[test]
894     fn test_round() {
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);
905     }
906
907     #[test]
908     fn test_trunc() {
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);
919     }
920
921     #[test]
922     fn test_fract() {
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);
933     }
934
935     #[test]
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());
952     }
953
954     #[test]
955     fn test_signed() {
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());
964
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());
973
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());
982
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());
991     }
992
993     #[test]
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>());
997     }
998
999     #[test]
1000     pub fn test_to_str_exact_do_decimal() {
1001         let s = to_str_exact(5.0, 4u);
1002         assert_eq!(s, ~"5.0000");
1003     }
1004
1005     #[test]
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()),
1028             None => fail!()
1029         }
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()),
1033             _ => fail!()
1034         }
1035         match from_str(~"0") {
1036             Some(v) if v.is_zero() => assert!(v.is_positive()),
1037             _ => fail!()
1038         }
1039
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());
1050     }
1051
1052     #[test]
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()),
1075             None => fail!()
1076         }
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()),
1080             _ => fail!()
1081         }
1082         match from_str_hex(~"0") {
1083             Some(v) if v.is_zero() => assert!(v.is_positive()),
1084             _ => fail!()
1085         }
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));
1091
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());
1102     }
1103
1104     #[test]
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");
1121     }
1122
1123     #[test]
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");
1127     }
1128
1129     #[test]
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));
1133     }
1134
1135     #[test]
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");
1139     }
1140 }