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