]> git.lizzy.rs Git - rust.git/blob - src/libcore/num/f32.rs
Remove 'Local Variable' comments
[rust.git] / src / libcore / num / f32.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 `f32`
12
13 use from_str;
14 use num::{Zero, One, strconv};
15 use prelude::*;
16
17 pub use cmath::c_float_targ_consts::*;
18
19 // An inner module is required to get the #[inline(always)] attribute on the
20 // functions.
21 pub use self::delegated::*;
22
23 macro_rules! delegate(
24     (
25         $(
26             fn $name:ident(
27                 $(
28                     $arg:ident : $arg_ty:ty
29                 ),*
30             ) -> $rv:ty = $bound_name:path
31         ),*
32     ) => (
33         mod delegated {
34             use cmath::c_float_utils;
35             use libc::{c_float, c_int};
36             use unstable::intrinsics;
37
38             $(
39                 #[inline(always)]
40                 pub fn $name($( $arg : $arg_ty ),*) -> $rv {
41                     unsafe {
42                         $bound_name($( $arg ),*)
43                     }
44                 }
45             )*
46         }
47     )
48 )
49
50 delegate!(
51     // intrinsics
52     fn abs(n: f32) -> f32 = intrinsics::fabsf32,
53     fn cos(n: f32) -> f32 = intrinsics::cosf32,
54     fn exp(n: f32) -> f32 = intrinsics::expf32,
55     fn exp2(n: f32) -> f32 = intrinsics::exp2f32,
56     fn floor(x: f32) -> f32 = intrinsics::floorf32,
57     fn ln(n: f32) -> f32 = intrinsics::logf32,
58     fn log10(n: f32) -> f32 = intrinsics::log10f32,
59     fn log2(n: f32) -> f32 = intrinsics::log2f32,
60     fn mul_add(a: f32, b: f32, c: f32) -> f32 = intrinsics::fmaf32,
61     fn pow(n: f32, e: f32) -> f32 = intrinsics::powf32,
62     fn powi(n: f32, e: c_int) -> f32 = intrinsics::powif32,
63     fn sin(n: f32) -> f32 = intrinsics::sinf32,
64     fn sqrt(n: f32) -> f32 = intrinsics::sqrtf32,
65
66     // LLVM 3.3 required to use intrinsics for these four
67     fn ceil(n: c_float) -> c_float = c_float_utils::ceil,
68     fn trunc(n: c_float) -> c_float = c_float_utils::trunc,
69     /*
70     fn ceil(n: f32) -> f32 = intrinsics::ceilf32,
71     fn trunc(n: f32) -> f32 = intrinsics::truncf32,
72     fn rint(n: f32) -> f32 = intrinsics::rintf32,
73     fn nearbyint(n: f32) -> f32 = intrinsics::nearbyintf32,
74     */
75
76     // cmath
77     fn acos(n: c_float) -> c_float = c_float_utils::acos,
78     fn asin(n: c_float) -> c_float = c_float_utils::asin,
79     fn atan(n: c_float) -> c_float = c_float_utils::atan,
80     fn atan2(a: c_float, b: c_float) -> c_float = c_float_utils::atan2,
81     fn cbrt(n: c_float) -> c_float = c_float_utils::cbrt,
82     fn copysign(x: c_float, y: c_float) -> c_float = c_float_utils::copysign,
83     fn cosh(n: c_float) -> c_float = c_float_utils::cosh,
84     fn erf(n: c_float) -> c_float = c_float_utils::erf,
85     fn erfc(n: c_float) -> c_float = c_float_utils::erfc,
86     fn expm1(n: c_float) -> c_float = c_float_utils::expm1,
87     fn abs_sub(a: c_float, b: c_float) -> c_float = c_float_utils::abs_sub,
88     fn fmax(a: c_float, b: c_float) -> c_float = c_float_utils::fmax,
89     fn fmin(a: c_float, b: c_float) -> c_float = c_float_utils::fmin,
90     fn next_after(x: c_float, y: c_float) -> c_float = c_float_utils::next_after,
91     fn frexp(n: c_float, value: &mut c_int) -> c_float = c_float_utils::frexp,
92     fn hypot(x: c_float, y: c_float) -> c_float = c_float_utils::hypot,
93     fn ldexp(x: c_float, n: c_int) -> c_float = c_float_utils::ldexp,
94     fn lgamma(n: c_float, sign: &mut c_int) -> c_float = c_float_utils::lgamma,
95     fn log_radix(n: c_float) -> c_float = c_float_utils::log_radix,
96     fn ln1p(n: c_float) -> c_float = c_float_utils::ln1p,
97     fn ilog_radix(n: c_float) -> c_int = c_float_utils::ilog_radix,
98     fn modf(n: c_float, iptr: &mut c_float) -> c_float = c_float_utils::modf,
99     fn round(n: c_float) -> c_float = c_float_utils::round,
100     fn ldexp_radix(n: c_float, i: c_int) -> c_float = c_float_utils::ldexp_radix,
101     fn sinh(n: c_float) -> c_float = c_float_utils::sinh,
102     fn tan(n: c_float) -> c_float = c_float_utils::tan,
103     fn tanh(n: c_float) -> c_float = c_float_utils::tanh,
104     fn tgamma(n: c_float) -> c_float = c_float_utils::tgamma
105 )
106
107 // These are not defined inside consts:: for consistency with
108 // the integer types
109
110 pub static NaN: f32 = 0.0_f32/0.0_f32;
111
112 pub static infinity: f32 = 1.0_f32/0.0_f32;
113
114 pub static neg_infinity: f32 = -1.0_f32/0.0_f32;
115
116 #[inline(always)]
117 pub fn add(x: f32, y: f32) -> f32 { return x + y; }
118
119 #[inline(always)]
120 pub fn sub(x: f32, y: f32) -> f32 { return x - y; }
121
122 #[inline(always)]
123 pub fn mul(x: f32, y: f32) -> f32 { return x * y; }
124
125 #[inline(always)]
126 pub fn div(x: f32, y: f32) -> f32 { return x / y; }
127
128 #[inline(always)]
129 pub fn rem(x: f32, y: f32) -> f32 { return x % y; }
130
131 #[inline(always)]
132 pub fn lt(x: f32, y: f32) -> bool { return x < y; }
133
134 #[inline(always)]
135 pub fn le(x: f32, y: f32) -> bool { return x <= y; }
136
137 #[inline(always)]
138 pub fn eq(x: f32, y: f32) -> bool { return x == y; }
139
140 #[inline(always)]
141 pub fn ne(x: f32, y: f32) -> bool { return x != y; }
142
143 #[inline(always)]
144 pub fn ge(x: f32, y: f32) -> bool { return x >= y; }
145
146 #[inline(always)]
147 pub fn gt(x: f32, y: f32) -> bool { return x > y; }
148
149
150 // FIXME (#1999): replace the predicates below with llvm intrinsics or
151 // calls to the libmath macros in the rust runtime for performance.
152
153 // FIXME (#1999): add is_normal, is_subnormal, and fpclassify.
154
155 /* Module: consts */
156 pub mod consts {
157     // FIXME (requires Issue #1433 to fix): replace with mathematical
158     // staticants from cmath.
159     /// Archimedes' staticant
160     pub static pi: f32 = 3.14159265358979323846264338327950288_f32;
161
162     /// pi/2.0
163     pub static frac_pi_2: f32 = 1.57079632679489661923132169163975144_f32;
164
165     /// pi/4.0
166     pub static frac_pi_4: f32 = 0.785398163397448309615660845819875721_f32;
167
168     /// 1.0/pi
169     pub static frac_1_pi: f32 = 0.318309886183790671537767526745028724_f32;
170
171     /// 2.0/pi
172     pub static frac_2_pi: f32 = 0.636619772367581343075535053490057448_f32;
173
174     /// 2.0/sqrt(pi)
175     pub static frac_2_sqrtpi: f32 = 1.12837916709551257389615890312154517_f32;
176
177     /// sqrt(2.0)
178     pub static sqrt2: f32 = 1.41421356237309504880168872420969808_f32;
179
180     /// 1.0/sqrt(2.0)
181     pub static frac_1_sqrt2: f32 = 0.707106781186547524400844362104849039_f32;
182
183     /// Euler's number
184     pub static e: f32 = 2.71828182845904523536028747135266250_f32;
185
186     /// log2(e)
187     pub static log2_e: f32 = 1.44269504088896340735992468100189214_f32;
188
189     /// log10(e)
190     pub static log10_e: f32 = 0.434294481903251827651128918916605082_f32;
191
192     /// ln(2.0)
193     pub static ln_2: f32 = 0.693147180559945309417232121458176568_f32;
194
195     /// ln(10.0)
196     pub static ln_10: f32 = 2.30258509299404568401799145468436421_f32;
197 }
198
199 #[inline(always)]
200 pub fn logarithm(n: f32, b: f32) -> f32 {
201     return log2(n) / log2(b);
202 }
203
204 impl Num for f32 {}
205
206 #[cfg(notest)]
207 impl Eq for f32 {
208     #[inline(always)]
209     fn eq(&self, other: &f32) -> bool { (*self) == (*other) }
210     #[inline(always)]
211     fn ne(&self, other: &f32) -> bool { (*self) != (*other) }
212 }
213
214 #[cfg(notest)]
215 impl Ord for f32 {
216     #[inline(always)]
217     fn lt(&self, other: &f32) -> bool { (*self) < (*other) }
218     #[inline(always)]
219     fn le(&self, other: &f32) -> bool { (*self) <= (*other) }
220     #[inline(always)]
221     fn ge(&self, other: &f32) -> bool { (*self) >= (*other) }
222     #[inline(always)]
223     fn gt(&self, other: &f32) -> bool { (*self) > (*other) }
224 }
225
226 impl Orderable for f32 {
227     /// Returns `NaN` if either of the numbers are `NaN`.
228     #[inline(always)]
229     fn min(&self, other: &f32) -> f32 {
230         if self.is_NaN() || other.is_NaN() { Float::NaN() } else { fmin(*self, *other) }
231     }
232
233     /// Returns `NaN` if either of the numbers are `NaN`.
234     #[inline(always)]
235     fn max(&self, other: &f32) -> f32 {
236         if self.is_NaN() || other.is_NaN() { Float::NaN() } else { fmax(*self, *other) }
237     }
238
239     /// Returns the number constrained within the range `mn <= self <= mx`.
240     /// If any of the numbers are `NaN` then `NaN` is returned.
241     #[inline(always)]
242     fn clamp(&self, mn: &f32, mx: &f32) -> f32 {
243         if self.is_NaN() { *self }
244         else if !(*self <= *mx) { *mx }
245         else if !(*self >= *mn) { *mn }
246         else { *self }
247     }
248 }
249
250 impl Zero for f32 {
251     #[inline(always)]
252     fn zero() -> f32 { 0.0 }
253
254     /// Returns true if the number is equal to either `0.0` or `-0.0`
255     #[inline(always)]
256     fn is_zero(&self) -> bool { *self == 0.0 || *self == -0.0 }
257 }
258
259 impl One for f32 {
260     #[inline(always)]
261     fn one() -> f32 { 1.0 }
262 }
263
264 #[cfg(notest)]
265 impl Add<f32,f32> for f32 {
266     #[inline(always)]
267     fn add(&self, other: &f32) -> f32 { *self + *other }
268 }
269
270 #[cfg(notest)]
271 impl Sub<f32,f32> for f32 {
272     #[inline(always)]
273     fn sub(&self, other: &f32) -> f32 { *self - *other }
274 }
275
276 #[cfg(notest)]
277 impl Mul<f32,f32> for f32 {
278     #[inline(always)]
279     fn mul(&self, other: &f32) -> f32 { *self * *other }
280 }
281
282 #[cfg(notest)]
283 impl Div<f32,f32> for f32 {
284     #[inline(always)]
285     fn div(&self, other: &f32) -> f32 { *self / *other }
286 }
287
288 #[cfg(stage0,notest)]
289 impl Modulo<f32,f32> for f32 {
290     #[inline(always)]
291     fn modulo(&self, other: &f32) -> f32 { *self % *other }
292 }
293 #[cfg(not(stage0),notest)]
294 impl Rem<f32,f32> for f32 {
295     #[inline(always)]
296     fn rem(&self, other: &f32) -> f32 { *self % *other }
297 }
298
299 #[cfg(notest)]
300 impl Neg<f32> for f32 {
301     #[inline(always)]
302     fn neg(&self) -> f32 { -*self }
303 }
304
305 impl Signed for f32 {
306     /// Computes the absolute value. Returns `NaN` if the number is `NaN`.
307     #[inline(always)]
308     fn abs(&self) -> f32 { abs(*self) }
309
310     ///
311     /// # Returns
312     ///
313     /// - `1.0` if the number is positive, `+0.0` or `infinity`
314     /// - `-1.0` if the number is negative, `-0.0` or `neg_infinity`
315     /// - `NaN` if the number is NaN
316     ///
317     #[inline(always)]
318     fn signum(&self) -> f32 {
319         if self.is_NaN() { NaN } else { copysign(1.0, *self) }
320     }
321
322     /// Returns `true` if the number is positive, including `+0.0` and `infinity`
323     #[inline(always)]
324     fn is_positive(&self) -> bool { *self > 0.0 || (1.0 / *self) == infinity }
325
326     /// Returns `true` if the number is negative, including `-0.0` and `neg_infinity`
327     #[inline(always)]
328     fn is_negative(&self) -> bool { *self < 0.0 || (1.0 / *self) == neg_infinity }
329 }
330
331 impl Round for f32 {
332     /// Round half-way cases toward `neg_infinity`
333     #[inline(always)]
334     fn floor(&self) -> f32 { floor(*self) }
335
336     /// Round half-way cases toward `infinity`
337     #[inline(always)]
338     fn ceil(&self) -> f32 { ceil(*self) }
339
340     /// Round half-way cases away from `0.0`
341     #[inline(always)]
342     fn round(&self) -> f32 { round(*self) }
343
344     /// The integer part of the number (rounds towards `0.0`)
345     #[inline(always)]
346     fn trunc(&self) -> f32 { trunc(*self) }
347
348     ///
349     /// The fractional part of the number, satisfying:
350     ///
351     /// ~~~
352     /// assert!(x == trunc(x) + fract(x))
353     /// ~~~
354     ///
355     #[inline(always)]
356     fn fract(&self) -> f32 { *self - self.trunc() }
357 }
358
359 impl Fractional for f32 {
360     /// The reciprocal (multiplicative inverse) of the number
361     #[inline(always)]
362     fn recip(&self) -> f32 { 1.0 / *self }
363 }
364
365 impl Algebraic for f32 {
366     #[inline(always)]
367     fn pow(&self, n: f32) -> f32 { pow(*self, n) }
368
369     #[inline(always)]
370     fn sqrt(&self) -> f32 { sqrt(*self) }
371
372     #[inline(always)]
373     fn rsqrt(&self) -> f32 { self.sqrt().recip() }
374
375     #[inline(always)]
376     fn cbrt(&self) -> f32 { cbrt(*self) }
377
378     #[inline(always)]
379     fn hypot(&self, other: f32) -> f32 { hypot(*self, other) }
380 }
381
382 impl Trigonometric for f32 {
383     #[inline(always)]
384     fn sin(&self) -> f32 { sin(*self) }
385
386     #[inline(always)]
387     fn cos(&self) -> f32 { cos(*self) }
388
389     #[inline(always)]
390     fn tan(&self) -> f32 { tan(*self) }
391
392     #[inline(always)]
393     fn asin(&self) -> f32 { asin(*self) }
394
395     #[inline(always)]
396     fn acos(&self) -> f32 { acos(*self) }
397
398     #[inline(always)]
399     fn atan(&self) -> f32 { atan(*self) }
400
401     #[inline(always)]
402     fn atan2(&self, other: f32) -> f32 { atan2(*self, other) }
403 }
404
405 impl Exponential for f32 {
406     #[inline(always)]
407     fn exp(&self) -> f32 { exp(*self) }
408
409     #[inline(always)]
410     fn exp2(&self) -> f32 { exp2(*self) }
411
412     #[inline(always)]
413     fn expm1(&self) -> f32 { expm1(*self) }
414
415     #[inline(always)]
416     fn log(&self) -> f32 { ln(*self) }
417
418     #[inline(always)]
419     fn log2(&self) -> f32 { log2(*self) }
420
421     #[inline(always)]
422     fn log10(&self) -> f32 { log10(*self) }
423 }
424
425 impl Hyperbolic for f32 {
426     #[inline(always)]
427     fn sinh(&self) -> f32 { sinh(*self) }
428
429     #[inline(always)]
430     fn cosh(&self) -> f32 { cosh(*self) }
431
432     #[inline(always)]
433     fn tanh(&self) -> f32 { tanh(*self) }
434 }
435
436 impl Real for f32 {
437     /// Archimedes' constant
438     #[inline(always)]
439     fn pi() -> f32 { 3.14159265358979323846264338327950288 }
440
441     /// 2.0 * pi
442     #[inline(always)]
443     fn two_pi() -> f32 { 6.28318530717958647692528676655900576 }
444
445     /// pi / 2.0
446     #[inline(always)]
447     fn frac_pi_2() -> f32 { 1.57079632679489661923132169163975144 }
448
449     /// pi / 3.0
450     #[inline(always)]
451     fn frac_pi_3() -> f32 { 1.04719755119659774615421446109316763 }
452
453     /// pi / 4.0
454     #[inline(always)]
455     fn frac_pi_4() -> f32 { 0.785398163397448309615660845819875721 }
456
457     /// pi / 6.0
458     #[inline(always)]
459     fn frac_pi_6() -> f32 { 0.52359877559829887307710723054658381 }
460
461     /// pi / 8.0
462     #[inline(always)]
463     fn frac_pi_8() -> f32 { 0.39269908169872415480783042290993786 }
464
465     /// 1 .0/ pi
466     #[inline(always)]
467     fn frac_1_pi() -> f32 { 0.318309886183790671537767526745028724 }
468
469     /// 2.0 / pi
470     #[inline(always)]
471     fn frac_2_pi() -> f32 { 0.636619772367581343075535053490057448 }
472
473     /// 2.0 / sqrt(pi)
474     #[inline(always)]
475     fn frac_2_sqrtpi() -> f32 { 1.12837916709551257389615890312154517 }
476
477     /// sqrt(2.0)
478     #[inline(always)]
479     fn sqrt2() -> f32 { 1.41421356237309504880168872420969808 }
480
481     /// 1.0 / sqrt(2.0)
482     #[inline(always)]
483     fn frac_1_sqrt2() -> f32 { 0.707106781186547524400844362104849039 }
484
485     /// Euler's number
486     #[inline(always)]
487     fn e() -> f32 { 2.71828182845904523536028747135266250 }
488
489     /// log2(e)
490     #[inline(always)]
491     fn log2_e() -> f32 { 1.44269504088896340735992468100189214 }
492
493     /// log10(e)
494     #[inline(always)]
495     fn log10_e() -> f32 { 0.434294481903251827651128918916605082 }
496
497     /// log(2.0)
498     #[inline(always)]
499     fn log_2() -> f32 { 0.693147180559945309417232121458176568 }
500
501     /// log(10.0)
502     #[inline(always)]
503     fn log_10() -> f32 { 2.30258509299404568401799145468436421 }
504
505     /// Converts to degrees, assuming the number is in radians
506     #[inline(always)]
507     fn to_degrees(&self) -> f32 { *self * (180.0 / Real::pi::<f32>()) }
508
509     /// Converts to radians, assuming the number is in degrees
510     #[inline(always)]
511     fn to_radians(&self) -> f32 { *self * (Real::pi::<f32>() / 180.0) }
512 }
513
514 impl Bounded for f32 {
515     #[inline(always)]
516     fn min_value() -> f32 { 1.17549435e-38 }
517
518     #[inline(always)]
519     fn max_value() -> f32 { 3.40282347e+38 }
520 }
521
522 impl Primitive for f32 {
523     #[inline(always)]
524     fn bits() -> uint { 32 }
525
526     #[inline(always)]
527     fn bytes() -> uint { Primitive::bits::<f32>() / 8 }
528 }
529
530 impl Float for f32 {
531     #[inline(always)]
532     fn NaN() -> f32 { 0.0 / 0.0 }
533
534     #[inline(always)]
535     fn infinity() -> f32 { 1.0 / 0.0 }
536
537     #[inline(always)]
538     fn neg_infinity() -> f32 { -1.0 / 0.0 }
539
540     #[inline(always)]
541     fn neg_zero() -> f32 { -0.0 }
542
543     #[inline(always)]
544     fn is_NaN(&self) -> bool { *self != *self }
545
546     #[inline(always)]
547     fn mantissa_digits() -> uint { 24 }
548
549     #[inline(always)]
550     fn digits() -> uint { 6 }
551
552     #[inline(always)]
553     fn epsilon() -> f32 { 1.19209290e-07 }
554
555     #[inline(always)]
556     fn min_exp() -> int { -125 }
557
558     #[inline(always)]
559     fn max_exp() -> int { 128 }
560
561     #[inline(always)]
562     fn min_10_exp() -> int { -37 }
563
564     #[inline(always)]
565     fn max_10_exp() -> int { 38 }
566
567     /// Returns `true` if the number is infinite
568     #[inline(always)]
569     fn is_infinite(&self) -> bool {
570         *self == Float::infinity() || *self == Float::neg_infinity()
571     }
572
573     /// Returns `true` if the number is finite
574     #[inline(always)]
575     fn is_finite(&self) -> bool {
576         !(self.is_NaN() || self.is_infinite())
577     }
578
579     ///
580     /// Fused multiply-add. Computes `(self * a) + b` with only one rounding error. This
581     /// produces a more accurate result with better performance than a separate multiplication
582     /// operation followed by an add.
583     ///
584     #[inline(always)]
585     fn mul_add(&self, a: f32, b: f32) -> f32 {
586         mul_add(*self, a, b)
587     }
588
589     /// Returns the next representable floating-point value in the direction of `other`
590     #[inline(always)]
591     fn next_after(&self, other: f32) -> f32 {
592         next_after(*self, other)
593     }
594 }
595
596 //
597 // Section: String Conversions
598 //
599
600 ///
601 /// Converts a float to a string
602 ///
603 /// # Arguments
604 ///
605 /// * num - The float value
606 ///
607 #[inline(always)]
608 pub fn to_str(num: f32) -> ~str {
609     let (r, _) = strconv::to_str_common(
610         &num, 10u, true, strconv::SignNeg, strconv::DigAll);
611     r
612 }
613
614 ///
615 /// Converts a float to a string in hexadecimal format
616 ///
617 /// # Arguments
618 ///
619 /// * num - The float value
620 ///
621 #[inline(always)]
622 pub fn to_str_hex(num: f32) -> ~str {
623     let (r, _) = strconv::to_str_common(
624         &num, 16u, true, strconv::SignNeg, strconv::DigAll);
625     r
626 }
627
628 ///
629 /// Converts a float to a string in a given radix
630 ///
631 /// # Arguments
632 ///
633 /// * num - The float value
634 /// * radix - The base to use
635 ///
636 /// # Failure
637 ///
638 /// Fails if called on a special value like `inf`, `-inf` or `NaN` due to
639 /// possible misinterpretation of the result at higher bases. If those values
640 /// are expected, use `to_str_radix_special()` instead.
641 ///
642 #[inline(always)]
643 pub fn to_str_radix(num: f32, rdx: uint) -> ~str {
644     let (r, special) = strconv::to_str_common(
645         &num, rdx, true, strconv::SignNeg, strconv::DigAll);
646     if special { fail!(~"number has a special value, \
647                       try to_str_radix_special() if those are expected") }
648     r
649 }
650
651 ///
652 /// Converts a float to a string in a given radix, and a flag indicating
653 /// whether it's a special value
654 ///
655 /// # Arguments
656 ///
657 /// * num - The float value
658 /// * radix - The base to use
659 ///
660 #[inline(always)]
661 pub fn to_str_radix_special(num: f32, rdx: uint) -> (~str, bool) {
662     strconv::to_str_common(&num, rdx, true,
663                            strconv::SignNeg, strconv::DigAll)
664 }
665
666 ///
667 /// Converts a float to a string with exactly the number of
668 /// provided significant digits
669 ///
670 /// # Arguments
671 ///
672 /// * num - The float value
673 /// * digits - The number of significant digits
674 ///
675 #[inline(always)]
676 pub fn to_str_exact(num: f32, dig: uint) -> ~str {
677     let (r, _) = strconv::to_str_common(
678         &num, 10u, true, strconv::SignNeg, strconv::DigExact(dig));
679     r
680 }
681
682 ///
683 /// Converts a float to a string with a maximum number of
684 /// significant digits
685 ///
686 /// # Arguments
687 ///
688 /// * num - The float value
689 /// * digits - The number of significant digits
690 ///
691 #[inline(always)]
692 pub fn to_str_digits(num: f32, dig: uint) -> ~str {
693     let (r, _) = strconv::to_str_common(
694         &num, 10u, true, strconv::SignNeg, strconv::DigMax(dig));
695     r
696 }
697
698 impl to_str::ToStr for f32 {
699     #[inline(always)]
700     fn to_str(&self) -> ~str { to_str_digits(*self, 8) }
701 }
702
703 impl num::ToStrRadix for f32 {
704     #[inline(always)]
705     fn to_str_radix(&self, rdx: uint) -> ~str {
706         to_str_radix(*self, rdx)
707     }
708 }
709
710 ///
711 /// Convert a string in base 10 to a float.
712 /// Accepts a optional decimal exponent.
713 ///
714 /// This function accepts strings such as
715 ///
716 /// * '3.14'
717 /// * '+3.14', equivalent to '3.14'
718 /// * '-3.14'
719 /// * '2.5E10', or equivalently, '2.5e10'
720 /// * '2.5E-10'
721 /// * '.' (understood as 0)
722 /// * '5.'
723 /// * '.5', or, equivalently,  '0.5'
724 /// * '+inf', 'inf', '-inf', 'NaN'
725 ///
726 /// Leading and trailing whitespace represent an error.
727 ///
728 /// # Arguments
729 ///
730 /// * num - A string
731 ///
732 /// # Return value
733 ///
734 /// `none` if the string did not represent a valid number.  Otherwise,
735 /// `Some(n)` where `n` is the floating-point number represented by `num`.
736 ///
737 #[inline(always)]
738 pub fn from_str(num: &str) -> Option<f32> {
739     strconv::from_str_common(num, 10u, true, true, true,
740                              strconv::ExpDec, false, false)
741 }
742
743 ///
744 /// Convert a string in base 16 to a float.
745 /// Accepts a optional binary exponent.
746 ///
747 /// This function accepts strings such as
748 ///
749 /// * 'a4.fe'
750 /// * '+a4.fe', equivalent to 'a4.fe'
751 /// * '-a4.fe'
752 /// * '2b.aP128', or equivalently, '2b.ap128'
753 /// * '2b.aP-128'
754 /// * '.' (understood as 0)
755 /// * 'c.'
756 /// * '.c', or, equivalently,  '0.c'
757 /// * '+inf', 'inf', '-inf', 'NaN'
758 ///
759 /// Leading and trailing whitespace represent an error.
760 ///
761 /// # Arguments
762 ///
763 /// * num - A string
764 ///
765 /// # Return value
766 ///
767 /// `none` if the string did not represent a valid number.  Otherwise,
768 /// `Some(n)` where `n` is the floating-point number represented by `[num]`.
769 ///
770 #[inline(always)]
771 pub fn from_str_hex(num: &str) -> Option<f32> {
772     strconv::from_str_common(num, 16u, true, true, true,
773                              strconv::ExpBin, false, false)
774 }
775
776 ///
777 /// Convert a string in an given base to a float.
778 ///
779 /// Due to possible conflicts, this function does **not** accept
780 /// the special values `inf`, `-inf`, `+inf` and `NaN`, **nor**
781 /// does it recognize exponents of any kind.
782 ///
783 /// Leading and trailing whitespace represent an error.
784 ///
785 /// # Arguments
786 ///
787 /// * num - A string
788 /// * radix - The base to use. Must lie in the range [2 .. 36]
789 ///
790 /// # Return value
791 ///
792 /// `none` if the string did not represent a valid number. Otherwise,
793 /// `Some(n)` where `n` is the floating-point number represented by `num`.
794 ///
795 #[inline(always)]
796 pub fn from_str_radix(num: &str, rdx: uint) -> Option<f32> {
797     strconv::from_str_common(num, rdx, true, true, false,
798                              strconv::ExpNone, false, false)
799 }
800
801 impl from_str::FromStr for f32 {
802     #[inline(always)]
803     fn from_str(val: &str) -> Option<f32> { from_str(val) }
804 }
805
806 impl num::FromStrRadix for f32 {
807     #[inline(always)]
808     fn from_str_radix(val: &str, rdx: uint) -> Option<f32> {
809         from_str_radix(val, rdx)
810     }
811 }
812
813 #[cfg(test)]
814 mod tests {
815     use f32::*;
816     use super::*;
817     use prelude::*;
818
819     macro_rules! assert_fuzzy_eq(
820         ($a:expr, $b:expr) => ({
821             let a = $a, b = $b;
822             if !((a - b).abs() < 1.0e-6) {
823                 fail!(fmt!("The values were not approximately equal. Found: %? and %?", a, b));
824             }
825         })
826     )
827
828     #[test]
829     fn test_num() {
830         num::test_num(10f32, 2f32);
831     }
832
833     #[test]
834     fn test_min() {
835         assert_eq!(1f32.min(&2f32), 1f32);
836         assert_eq!(2f32.min(&1f32), 1f32);
837     }
838
839     #[test]
840     fn test_max() {
841         assert_eq!(1f32.max(&2f32), 2f32);
842         assert_eq!(2f32.max(&1f32), 2f32);
843     }
844
845     #[test]
846     fn test_clamp() {
847         assert_eq!(1f32.clamp(&2f32, &4f32), 2f32);
848         assert_eq!(8f32.clamp(&2f32, &4f32), 4f32);
849         assert_eq!(3f32.clamp(&2f32, &4f32), 3f32);
850         assert!(3f32.clamp(&Float::NaN::<f32>(), &4f32).is_NaN());
851         assert!(3f32.clamp(&2f32, &Float::NaN::<f32>()).is_NaN());
852         assert!(Float::NaN::<f32>().clamp(&2f32, &4f32).is_NaN());
853     }
854
855     #[test]
856     fn test_floor() {
857         assert_fuzzy_eq!(1.0f32.floor(), 1.0f32);
858         assert_fuzzy_eq!(1.3f32.floor(), 1.0f32);
859         assert_fuzzy_eq!(1.5f32.floor(), 1.0f32);
860         assert_fuzzy_eq!(1.7f32.floor(), 1.0f32);
861         assert_fuzzy_eq!(0.0f32.floor(), 0.0f32);
862         assert_fuzzy_eq!((-0.0f32).floor(), -0.0f32);
863         assert_fuzzy_eq!((-1.0f32).floor(), -1.0f32);
864         assert_fuzzy_eq!((-1.3f32).floor(), -2.0f32);
865         assert_fuzzy_eq!((-1.5f32).floor(), -2.0f32);
866         assert_fuzzy_eq!((-1.7f32).floor(), -2.0f32);
867     }
868
869     #[test]
870     fn test_ceil() {
871         assert_fuzzy_eq!(1.0f32.ceil(), 1.0f32);
872         assert_fuzzy_eq!(1.3f32.ceil(), 2.0f32);
873         assert_fuzzy_eq!(1.5f32.ceil(), 2.0f32);
874         assert_fuzzy_eq!(1.7f32.ceil(), 2.0f32);
875         assert_fuzzy_eq!(0.0f32.ceil(), 0.0f32);
876         assert_fuzzy_eq!((-0.0f32).ceil(), -0.0f32);
877         assert_fuzzy_eq!((-1.0f32).ceil(), -1.0f32);
878         assert_fuzzy_eq!((-1.3f32).ceil(), -1.0f32);
879         assert_fuzzy_eq!((-1.5f32).ceil(), -1.0f32);
880         assert_fuzzy_eq!((-1.7f32).ceil(), -1.0f32);
881     }
882
883     #[test]
884     fn test_round() {
885         assert_fuzzy_eq!(1.0f32.round(), 1.0f32);
886         assert_fuzzy_eq!(1.3f32.round(), 1.0f32);
887         assert_fuzzy_eq!(1.5f32.round(), 2.0f32);
888         assert_fuzzy_eq!(1.7f32.round(), 2.0f32);
889         assert_fuzzy_eq!(0.0f32.round(), 0.0f32);
890         assert_fuzzy_eq!((-0.0f32).round(), -0.0f32);
891         assert_fuzzy_eq!((-1.0f32).round(), -1.0f32);
892         assert_fuzzy_eq!((-1.3f32).round(), -1.0f32);
893         assert_fuzzy_eq!((-1.5f32).round(), -2.0f32);
894         assert_fuzzy_eq!((-1.7f32).round(), -2.0f32);
895     }
896
897     #[test]
898     fn test_trunc() {
899         assert_fuzzy_eq!(1.0f32.trunc(), 1.0f32);
900         assert_fuzzy_eq!(1.3f32.trunc(), 1.0f32);
901         assert_fuzzy_eq!(1.5f32.trunc(), 1.0f32);
902         assert_fuzzy_eq!(1.7f32.trunc(), 1.0f32);
903         assert_fuzzy_eq!(0.0f32.trunc(), 0.0f32);
904         assert_fuzzy_eq!((-0.0f32).trunc(), -0.0f32);
905         assert_fuzzy_eq!((-1.0f32).trunc(), -1.0f32);
906         assert_fuzzy_eq!((-1.3f32).trunc(), -1.0f32);
907         assert_fuzzy_eq!((-1.5f32).trunc(), -1.0f32);
908         assert_fuzzy_eq!((-1.7f32).trunc(), -1.0f32);
909     }
910
911     #[test]
912     fn test_fract() {
913         assert_fuzzy_eq!(1.0f32.fract(), 0.0f32);
914         assert_fuzzy_eq!(1.3f32.fract(), 0.3f32);
915         assert_fuzzy_eq!(1.5f32.fract(), 0.5f32);
916         assert_fuzzy_eq!(1.7f32.fract(), 0.7f32);
917         assert_fuzzy_eq!(0.0f32.fract(), 0.0f32);
918         assert_fuzzy_eq!((-0.0f32).fract(), -0.0f32);
919         assert_fuzzy_eq!((-1.0f32).fract(), -0.0f32);
920         assert_fuzzy_eq!((-1.3f32).fract(), -0.3f32);
921         assert_fuzzy_eq!((-1.5f32).fract(), -0.5f32);
922         assert_fuzzy_eq!((-1.7f32).fract(), -0.7f32);
923     }
924
925     #[test]
926     fn test_real_consts() {
927         assert_fuzzy_eq!(Real::two_pi::<f32>(), 2f32 * Real::pi::<f32>());
928         assert_fuzzy_eq!(Real::frac_pi_2::<f32>(), Real::pi::<f32>() / 2f32);
929         assert_fuzzy_eq!(Real::frac_pi_3::<f32>(), Real::pi::<f32>() / 3f32);
930         assert_fuzzy_eq!(Real::frac_pi_4::<f32>(), Real::pi::<f32>() / 4f32);
931         assert_fuzzy_eq!(Real::frac_pi_6::<f32>(), Real::pi::<f32>() / 6f32);
932         assert_fuzzy_eq!(Real::frac_pi_8::<f32>(), Real::pi::<f32>() / 8f32);
933         assert_fuzzy_eq!(Real::frac_1_pi::<f32>(), 1f32 / Real::pi::<f32>());
934         assert_fuzzy_eq!(Real::frac_2_pi::<f32>(), 2f32 / Real::pi::<f32>());
935         assert_fuzzy_eq!(Real::frac_2_sqrtpi::<f32>(), 2f32 / Real::pi::<f32>().sqrt());
936         assert_fuzzy_eq!(Real::sqrt2::<f32>(), 2f32.sqrt());
937         assert_fuzzy_eq!(Real::frac_1_sqrt2::<f32>(), 1f32 / 2f32.sqrt());
938         assert_fuzzy_eq!(Real::log2_e::<f32>(), Real::e::<f32>().log2());
939         assert_fuzzy_eq!(Real::log10_e::<f32>(), Real::e::<f32>().log10());
940         assert_fuzzy_eq!(Real::log_2::<f32>(), 2f32.log());
941         assert_fuzzy_eq!(Real::log_10::<f32>(), 10f32.log());
942     }
943
944     #[test]
945     pub fn test_signed() {
946         assert_eq!(infinity.abs(), infinity);
947         assert_eq!(1f32.abs(), 1f32);
948         assert_eq!(0f32.abs(), 0f32);
949         assert_eq!((-0f32).abs(), 0f32);
950         assert_eq!((-1f32).abs(), 1f32);
951         assert_eq!(neg_infinity.abs(), infinity);
952         assert_eq!((1f32/neg_infinity).abs(), 0f32);
953         assert!(NaN.abs().is_NaN());
954
955         assert_eq!(infinity.signum(), 1f32);
956         assert_eq!(1f32.signum(), 1f32);
957         assert_eq!(0f32.signum(), 1f32);
958         assert_eq!((-0f32).signum(), -1f32);
959         assert_eq!((-1f32).signum(), -1f32);
960         assert_eq!(neg_infinity.signum(), -1f32);
961         assert_eq!((1f32/neg_infinity).signum(), -1f32);
962         assert!(NaN.signum().is_NaN());
963
964         assert!(infinity.is_positive());
965         assert!(1f32.is_positive());
966         assert!(0f32.is_positive());
967         assert!(!(-0f32).is_positive());
968         assert!(!(-1f32).is_positive());
969         assert!(!neg_infinity.is_positive());
970         assert!(!(1f32/neg_infinity).is_positive());
971         assert!(!NaN.is_positive());
972
973         assert!(!infinity.is_negative());
974         assert!(!1f32.is_negative());
975         assert!(!0f32.is_negative());
976         assert!((-0f32).is_negative());
977         assert!((-1f32).is_negative());
978         assert!(neg_infinity.is_negative());
979         assert!((1f32/neg_infinity).is_negative());
980         assert!(!NaN.is_negative());
981     }
982
983     #[test]
984     fn test_primitive() {
985         assert_eq!(Primitive::bits::<f32>(), sys::size_of::<f32>() * 8);
986         assert_eq!(Primitive::bytes::<f32>(), sys::size_of::<f32>());
987     }
988 }