]> git.lizzy.rs Git - rust.git/blob - src/libcore/num/f32.rs
e687f482fa98c1bfcb0f5ebfa52b5d835db445ee
[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 quot(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(stage0,notest)]
283 impl Div<f32,f32> for f32 {
284     #[inline(always)]
285     fn div(&self, other: &f32) -> f32 { *self / *other }
286 }
287 #[cfg(not(stage0),notest)]
288 impl Quot<f32,f32> for f32 {
289     #[inline(always)]
290     fn quot(&self, other: &f32) -> f32 { *self / *other }
291 }
292
293 #[cfg(stage0,notest)]
294 impl Modulo<f32,f32> for f32 {
295     #[inline(always)]
296     fn modulo(&self, other: &f32) -> f32 { *self % *other }
297 }
298 #[cfg(not(stage0),notest)]
299 impl Rem<f32,f32> for f32 {
300     #[inline(always)]
301     fn rem(&self, other: &f32) -> f32 { *self % *other }
302 }
303
304 #[cfg(notest)]
305 impl Neg<f32> for f32 {
306     #[inline(always)]
307     fn neg(&self) -> f32 { -*self }
308 }
309
310 impl Signed for f32 {
311     /// Computes the absolute value. Returns `NaN` if the number is `NaN`.
312     #[inline(always)]
313     fn abs(&self) -> f32 { abs(*self) }
314
315     ///
316     /// # Returns
317     ///
318     /// - `1.0` if the number is positive, `+0.0` or `infinity`
319     /// - `-1.0` if the number is negative, `-0.0` or `neg_infinity`
320     /// - `NaN` if the number is NaN
321     ///
322     #[inline(always)]
323     fn signum(&self) -> f32 {
324         if self.is_NaN() { NaN } else { copysign(1.0, *self) }
325     }
326
327     /// Returns `true` if the number is positive, including `+0.0` and `infinity`
328     #[inline(always)]
329     fn is_positive(&self) -> bool { *self > 0.0 || (1.0 / *self) == infinity }
330
331     /// Returns `true` if the number is negative, including `-0.0` and `neg_infinity`
332     #[inline(always)]
333     fn is_negative(&self) -> bool { *self < 0.0 || (1.0 / *self) == neg_infinity }
334 }
335
336 impl Round for f32 {
337     /// Round half-way cases toward `neg_infinity`
338     #[inline(always)]
339     fn floor(&self) -> f32 { floor(*self) }
340
341     /// Round half-way cases toward `infinity`
342     #[inline(always)]
343     fn ceil(&self) -> f32 { ceil(*self) }
344
345     /// Round half-way cases away from `0.0`
346     #[inline(always)]
347     fn round(&self) -> f32 { round(*self) }
348
349     /// The integer part of the number (rounds towards `0.0`)
350     #[inline(always)]
351     fn trunc(&self) -> f32 { trunc(*self) }
352
353     ///
354     /// The fractional part of the number, satisfying:
355     ///
356     /// ~~~
357     /// assert!(x == trunc(x) + fract(x))
358     /// ~~~
359     ///
360     #[inline(always)]
361     fn fract(&self) -> f32 { *self - self.trunc() }
362 }
363
364 impl Fractional for f32 {
365     /// The reciprocal (multiplicative inverse) of the number
366     #[inline(always)]
367     fn recip(&self) -> f32 { 1.0 / *self }
368 }
369
370 impl Algebraic for f32 {
371     #[inline(always)]
372     fn pow(&self, n: f32) -> f32 { pow(*self, n) }
373
374     #[inline(always)]
375     fn sqrt(&self) -> f32 { sqrt(*self) }
376
377     #[inline(always)]
378     fn rsqrt(&self) -> f32 { self.sqrt().recip() }
379
380     #[inline(always)]
381     fn cbrt(&self) -> f32 { cbrt(*self) }
382
383     #[inline(always)]
384     fn hypot(&self, other: f32) -> f32 { hypot(*self, other) }
385 }
386
387 impl Trigonometric for f32 {
388     #[inline(always)]
389     fn sin(&self) -> f32 { sin(*self) }
390
391     #[inline(always)]
392     fn cos(&self) -> f32 { cos(*self) }
393
394     #[inline(always)]
395     fn tan(&self) -> f32 { tan(*self) }
396
397     #[inline(always)]
398     fn asin(&self) -> f32 { asin(*self) }
399
400     #[inline(always)]
401     fn acos(&self) -> f32 { acos(*self) }
402
403     #[inline(always)]
404     fn atan(&self) -> f32 { atan(*self) }
405
406     #[inline(always)]
407     fn atan2(&self, other: f32) -> f32 { atan2(*self, other) }
408 }
409
410 impl Exponential for f32 {
411     #[inline(always)]
412     fn exp(&self) -> f32 { exp(*self) }
413
414     #[inline(always)]
415     fn exp2(&self) -> f32 { exp2(*self) }
416
417     #[inline(always)]
418     fn expm1(&self) -> f32 { expm1(*self) }
419
420     #[inline(always)]
421     fn log(&self) -> f32 { ln(*self) }
422
423     #[inline(always)]
424     fn log2(&self) -> f32 { log2(*self) }
425
426     #[inline(always)]
427     fn log10(&self) -> f32 { log10(*self) }
428 }
429
430 impl Hyperbolic for f32 {
431     #[inline(always)]
432     fn sinh(&self) -> f32 { sinh(*self) }
433
434     #[inline(always)]
435     fn cosh(&self) -> f32 { cosh(*self) }
436
437     #[inline(always)]
438     fn tanh(&self) -> f32 { tanh(*self) }
439 }
440
441 impl Real for f32 {
442     /// Archimedes' constant
443     #[inline(always)]
444     fn pi() -> f32 { 3.14159265358979323846264338327950288 }
445
446     /// 2.0 * pi
447     #[inline(always)]
448     fn two_pi() -> f32 { 6.28318530717958647692528676655900576 }
449
450     /// pi / 2.0
451     #[inline(always)]
452     fn frac_pi_2() -> f32 { 1.57079632679489661923132169163975144 }
453
454     /// pi / 3.0
455     #[inline(always)]
456     fn frac_pi_3() -> f32 { 1.04719755119659774615421446109316763 }
457
458     /// pi / 4.0
459     #[inline(always)]
460     fn frac_pi_4() -> f32 { 0.785398163397448309615660845819875721 }
461
462     /// pi / 6.0
463     #[inline(always)]
464     fn frac_pi_6() -> f32 { 0.52359877559829887307710723054658381 }
465
466     /// pi / 8.0
467     #[inline(always)]
468     fn frac_pi_8() -> f32 { 0.39269908169872415480783042290993786 }
469
470     /// 1 .0/ pi
471     #[inline(always)]
472     fn frac_1_pi() -> f32 { 0.318309886183790671537767526745028724 }
473
474     /// 2.0 / pi
475     #[inline(always)]
476     fn frac_2_pi() -> f32 { 0.636619772367581343075535053490057448 }
477
478     /// 2.0 / sqrt(pi)
479     #[inline(always)]
480     fn frac_2_sqrtpi() -> f32 { 1.12837916709551257389615890312154517 }
481
482     /// sqrt(2.0)
483     #[inline(always)]
484     fn sqrt2() -> f32 { 1.41421356237309504880168872420969808 }
485
486     /// 1.0 / sqrt(2.0)
487     #[inline(always)]
488     fn frac_1_sqrt2() -> f32 { 0.707106781186547524400844362104849039 }
489
490     /// Euler's number
491     #[inline(always)]
492     fn e() -> f32 { 2.71828182845904523536028747135266250 }
493
494     /// log2(e)
495     #[inline(always)]
496     fn log2_e() -> f32 { 1.44269504088896340735992468100189214 }
497
498     /// log10(e)
499     #[inline(always)]
500     fn log10_e() -> f32 { 0.434294481903251827651128918916605082 }
501
502     /// log(2.0)
503     #[inline(always)]
504     fn log_2() -> f32 { 0.693147180559945309417232121458176568 }
505
506     /// log(10.0)
507     #[inline(always)]
508     fn log_10() -> f32 { 2.30258509299404568401799145468436421 }
509
510     /// Converts to degrees, assuming the number is in radians
511     #[inline(always)]
512     fn to_degrees(&self) -> f32 { *self * (180.0 / Real::pi::<f32>()) }
513
514     /// Converts to radians, assuming the number is in degrees
515     #[inline(always)]
516     fn to_radians(&self) -> f32 { *self * (Real::pi::<f32>() / 180.0) }
517 }
518
519 impl Bounded for f32 {
520     #[inline(always)]
521     fn min_value() -> f32 { 1.17549435e-38 }
522
523     #[inline(always)]
524     fn max_value() -> f32 { 3.40282347e+38 }
525 }
526
527 impl Primitive for f32 {
528     #[inline(always)]
529     fn bits() -> uint { 32 }
530
531     #[inline(always)]
532     fn bytes() -> uint { Primitive::bits::<f32>() / 8 }
533 }
534
535 impl Float for f32 {
536     #[inline(always)]
537     fn NaN() -> f32 { 0.0 / 0.0 }
538
539     #[inline(always)]
540     fn infinity() -> f32 { 1.0 / 0.0 }
541
542     #[inline(always)]
543     fn neg_infinity() -> f32 { -1.0 / 0.0 }
544
545     #[inline(always)]
546     fn neg_zero() -> f32 { -0.0 }
547
548     #[inline(always)]
549     fn is_NaN(&self) -> bool { *self != *self }
550
551     #[inline(always)]
552     fn mantissa_digits() -> uint { 24 }
553
554     #[inline(always)]
555     fn digits() -> uint { 6 }
556
557     #[inline(always)]
558     fn epsilon() -> f32 { 1.19209290e-07 }
559
560     #[inline(always)]
561     fn min_exp() -> int { -125 }
562
563     #[inline(always)]
564     fn max_exp() -> int { 128 }
565
566     #[inline(always)]
567     fn min_10_exp() -> int { -37 }
568
569     #[inline(always)]
570     fn max_10_exp() -> int { 38 }
571
572     /// Returns `true` if the number is infinite
573     #[inline(always)]
574     fn is_infinite(&self) -> bool {
575         *self == Float::infinity() || *self == Float::neg_infinity()
576     }
577
578     /// Returns `true` if the number is finite
579     #[inline(always)]
580     fn is_finite(&self) -> bool {
581         !(self.is_NaN() || self.is_infinite())
582     }
583
584     ///
585     /// Fused multiply-add. Computes `(self * a) + b` with only one rounding error. This
586     /// produces a more accurate result with better performance than a separate multiplication
587     /// operation followed by an add.
588     ///
589     #[inline(always)]
590     fn mul_add(&self, a: f32, b: f32) -> f32 {
591         mul_add(*self, a, b)
592     }
593
594     /// Returns the next representable floating-point value in the direction of `other`
595     #[inline(always)]
596     fn next_after(&self, other: f32) -> f32 {
597         next_after(*self, other)
598     }
599 }
600
601 //
602 // Section: String Conversions
603 //
604
605 ///
606 /// Converts a float to a string
607 ///
608 /// # Arguments
609 ///
610 /// * num - The float value
611 ///
612 #[inline(always)]
613 pub fn to_str(num: f32) -> ~str {
614     let (r, _) = strconv::to_str_common(
615         &num, 10u, true, strconv::SignNeg, strconv::DigAll);
616     r
617 }
618
619 ///
620 /// Converts a float to a string in hexadecimal format
621 ///
622 /// # Arguments
623 ///
624 /// * num - The float value
625 ///
626 #[inline(always)]
627 pub fn to_str_hex(num: f32) -> ~str {
628     let (r, _) = strconv::to_str_common(
629         &num, 16u, true, strconv::SignNeg, strconv::DigAll);
630     r
631 }
632
633 ///
634 /// Converts a float to a string in a given radix
635 ///
636 /// # Arguments
637 ///
638 /// * num - The float value
639 /// * radix - The base to use
640 ///
641 /// # Failure
642 ///
643 /// Fails if called on a special value like `inf`, `-inf` or `NaN` due to
644 /// possible misinterpretation of the result at higher bases. If those values
645 /// are expected, use `to_str_radix_special()` instead.
646 ///
647 #[inline(always)]
648 pub fn to_str_radix(num: f32, rdx: uint) -> ~str {
649     let (r, special) = strconv::to_str_common(
650         &num, rdx, true, strconv::SignNeg, strconv::DigAll);
651     if special { fail!(~"number has a special value, \
652                       try to_str_radix_special() if those are expected") }
653     r
654 }
655
656 ///
657 /// Converts a float to a string in a given radix, and a flag indicating
658 /// whether it's a special value
659 ///
660 /// # Arguments
661 ///
662 /// * num - The float value
663 /// * radix - The base to use
664 ///
665 #[inline(always)]
666 pub fn to_str_radix_special(num: f32, rdx: uint) -> (~str, bool) {
667     strconv::to_str_common(&num, rdx, true,
668                            strconv::SignNeg, strconv::DigAll)
669 }
670
671 ///
672 /// Converts a float to a string with exactly the number of
673 /// provided significant digits
674 ///
675 /// # Arguments
676 ///
677 /// * num - The float value
678 /// * digits - The number of significant digits
679 ///
680 #[inline(always)]
681 pub fn to_str_exact(num: f32, dig: uint) -> ~str {
682     let (r, _) = strconv::to_str_common(
683         &num, 10u, true, strconv::SignNeg, strconv::DigExact(dig));
684     r
685 }
686
687 ///
688 /// Converts a float to a string with a maximum number of
689 /// significant digits
690 ///
691 /// # Arguments
692 ///
693 /// * num - The float value
694 /// * digits - The number of significant digits
695 ///
696 #[inline(always)]
697 pub fn to_str_digits(num: f32, dig: uint) -> ~str {
698     let (r, _) = strconv::to_str_common(
699         &num, 10u, true, strconv::SignNeg, strconv::DigMax(dig));
700     r
701 }
702
703 impl to_str::ToStr for f32 {
704     #[inline(always)]
705     fn to_str(&self) -> ~str { to_str_digits(*self, 8) }
706 }
707
708 impl num::ToStrRadix for f32 {
709     #[inline(always)]
710     fn to_str_radix(&self, rdx: uint) -> ~str {
711         to_str_radix(*self, rdx)
712     }
713 }
714
715 ///
716 /// Convert a string in base 10 to a float.
717 /// Accepts a optional decimal exponent.
718 ///
719 /// This function accepts strings such as
720 ///
721 /// * '3.14'
722 /// * '+3.14', equivalent to '3.14'
723 /// * '-3.14'
724 /// * '2.5E10', or equivalently, '2.5e10'
725 /// * '2.5E-10'
726 /// * '.' (understood as 0)
727 /// * '5.'
728 /// * '.5', or, equivalently,  '0.5'
729 /// * '+inf', 'inf', '-inf', 'NaN'
730 ///
731 /// Leading and trailing whitespace represent an error.
732 ///
733 /// # Arguments
734 ///
735 /// * num - A string
736 ///
737 /// # Return value
738 ///
739 /// `none` if the string did not represent a valid number.  Otherwise,
740 /// `Some(n)` where `n` is the floating-point number represented by `num`.
741 ///
742 #[inline(always)]
743 pub fn from_str(num: &str) -> Option<f32> {
744     strconv::from_str_common(num, 10u, true, true, true,
745                              strconv::ExpDec, false, false)
746 }
747
748 ///
749 /// Convert a string in base 16 to a float.
750 /// Accepts a optional binary exponent.
751 ///
752 /// This function accepts strings such as
753 ///
754 /// * 'a4.fe'
755 /// * '+a4.fe', equivalent to 'a4.fe'
756 /// * '-a4.fe'
757 /// * '2b.aP128', or equivalently, '2b.ap128'
758 /// * '2b.aP-128'
759 /// * '.' (understood as 0)
760 /// * 'c.'
761 /// * '.c', or, equivalently,  '0.c'
762 /// * '+inf', 'inf', '-inf', 'NaN'
763 ///
764 /// Leading and trailing whitespace represent an error.
765 ///
766 /// # Arguments
767 ///
768 /// * num - A string
769 ///
770 /// # Return value
771 ///
772 /// `none` if the string did not represent a valid number.  Otherwise,
773 /// `Some(n)` where `n` is the floating-point number represented by `[num]`.
774 ///
775 #[inline(always)]
776 pub fn from_str_hex(num: &str) -> Option<f32> {
777     strconv::from_str_common(num, 16u, true, true, true,
778                              strconv::ExpBin, false, false)
779 }
780
781 ///
782 /// Convert a string in an given base to a float.
783 ///
784 /// Due to possible conflicts, this function does **not** accept
785 /// the special values `inf`, `-inf`, `+inf` and `NaN`, **nor**
786 /// does it recognize exponents of any kind.
787 ///
788 /// Leading and trailing whitespace represent an error.
789 ///
790 /// # Arguments
791 ///
792 /// * num - A string
793 /// * radix - The base to use. Must lie in the range [2 .. 36]
794 ///
795 /// # Return value
796 ///
797 /// `none` if the string did not represent a valid number. Otherwise,
798 /// `Some(n)` where `n` is the floating-point number represented by `num`.
799 ///
800 #[inline(always)]
801 pub fn from_str_radix(num: &str, rdx: uint) -> Option<f32> {
802     strconv::from_str_common(num, rdx, true, true, false,
803                              strconv::ExpNone, false, false)
804 }
805
806 impl from_str::FromStr for f32 {
807     #[inline(always)]
808     fn from_str(val: &str) -> Option<f32> { from_str(val) }
809 }
810
811 impl num::FromStrRadix for f32 {
812     #[inline(always)]
813     fn from_str_radix(val: &str, rdx: uint) -> Option<f32> {
814         from_str_radix(val, rdx)
815     }
816 }
817
818 #[cfg(test)]
819 mod tests {
820     use f32::*;
821     use super::*;
822     use prelude::*;
823
824     macro_rules! assert_fuzzy_eq(
825         ($a:expr, $b:expr) => ({
826             let a = $a, b = $b;
827             if !((a - b).abs() < 1.0e-6) {
828                 fail!(fmt!("The values were not approximately equal. Found: %? and %?", a, b));
829             }
830         })
831     )
832
833     #[test]
834     fn test_num() {
835         num::test_num(10f32, 2f32);
836     }
837
838     #[test]
839     fn test_min() {
840         assert_eq!(1f32.min(&2f32), 1f32);
841         assert_eq!(2f32.min(&1f32), 1f32);
842     }
843
844     #[test]
845     fn test_max() {
846         assert_eq!(1f32.max(&2f32), 2f32);
847         assert_eq!(2f32.max(&1f32), 2f32);
848     }
849
850     #[test]
851     fn test_clamp() {
852         assert_eq!(1f32.clamp(&2f32, &4f32), 2f32);
853         assert_eq!(8f32.clamp(&2f32, &4f32), 4f32);
854         assert_eq!(3f32.clamp(&2f32, &4f32), 3f32);
855         assert!(3f32.clamp(&Float::NaN::<f32>(), &4f32).is_NaN());
856         assert!(3f32.clamp(&2f32, &Float::NaN::<f32>()).is_NaN());
857         assert!(Float::NaN::<f32>().clamp(&2f32, &4f32).is_NaN());
858     }
859
860     #[test]
861     fn test_floor() {
862         assert_fuzzy_eq!(1.0f32.floor(), 1.0f32);
863         assert_fuzzy_eq!(1.3f32.floor(), 1.0f32);
864         assert_fuzzy_eq!(1.5f32.floor(), 1.0f32);
865         assert_fuzzy_eq!(1.7f32.floor(), 1.0f32);
866         assert_fuzzy_eq!(0.0f32.floor(), 0.0f32);
867         assert_fuzzy_eq!((-0.0f32).floor(), -0.0f32);
868         assert_fuzzy_eq!((-1.0f32).floor(), -1.0f32);
869         assert_fuzzy_eq!((-1.3f32).floor(), -2.0f32);
870         assert_fuzzy_eq!((-1.5f32).floor(), -2.0f32);
871         assert_fuzzy_eq!((-1.7f32).floor(), -2.0f32);
872     }
873
874     #[test]
875     fn test_ceil() {
876         assert_fuzzy_eq!(1.0f32.ceil(), 1.0f32);
877         assert_fuzzy_eq!(1.3f32.ceil(), 2.0f32);
878         assert_fuzzy_eq!(1.5f32.ceil(), 2.0f32);
879         assert_fuzzy_eq!(1.7f32.ceil(), 2.0f32);
880         assert_fuzzy_eq!(0.0f32.ceil(), 0.0f32);
881         assert_fuzzy_eq!((-0.0f32).ceil(), -0.0f32);
882         assert_fuzzy_eq!((-1.0f32).ceil(), -1.0f32);
883         assert_fuzzy_eq!((-1.3f32).ceil(), -1.0f32);
884         assert_fuzzy_eq!((-1.5f32).ceil(), -1.0f32);
885         assert_fuzzy_eq!((-1.7f32).ceil(), -1.0f32);
886     }
887
888     #[test]
889     fn test_round() {
890         assert_fuzzy_eq!(1.0f32.round(), 1.0f32);
891         assert_fuzzy_eq!(1.3f32.round(), 1.0f32);
892         assert_fuzzy_eq!(1.5f32.round(), 2.0f32);
893         assert_fuzzy_eq!(1.7f32.round(), 2.0f32);
894         assert_fuzzy_eq!(0.0f32.round(), 0.0f32);
895         assert_fuzzy_eq!((-0.0f32).round(), -0.0f32);
896         assert_fuzzy_eq!((-1.0f32).round(), -1.0f32);
897         assert_fuzzy_eq!((-1.3f32).round(), -1.0f32);
898         assert_fuzzy_eq!((-1.5f32).round(), -2.0f32);
899         assert_fuzzy_eq!((-1.7f32).round(), -2.0f32);
900     }
901
902     #[test]
903     fn test_trunc() {
904         assert_fuzzy_eq!(1.0f32.trunc(), 1.0f32);
905         assert_fuzzy_eq!(1.3f32.trunc(), 1.0f32);
906         assert_fuzzy_eq!(1.5f32.trunc(), 1.0f32);
907         assert_fuzzy_eq!(1.7f32.trunc(), 1.0f32);
908         assert_fuzzy_eq!(0.0f32.trunc(), 0.0f32);
909         assert_fuzzy_eq!((-0.0f32).trunc(), -0.0f32);
910         assert_fuzzy_eq!((-1.0f32).trunc(), -1.0f32);
911         assert_fuzzy_eq!((-1.3f32).trunc(), -1.0f32);
912         assert_fuzzy_eq!((-1.5f32).trunc(), -1.0f32);
913         assert_fuzzy_eq!((-1.7f32).trunc(), -1.0f32);
914     }
915
916     #[test]
917     fn test_fract() {
918         assert_fuzzy_eq!(1.0f32.fract(), 0.0f32);
919         assert_fuzzy_eq!(1.3f32.fract(), 0.3f32);
920         assert_fuzzy_eq!(1.5f32.fract(), 0.5f32);
921         assert_fuzzy_eq!(1.7f32.fract(), 0.7f32);
922         assert_fuzzy_eq!(0.0f32.fract(), 0.0f32);
923         assert_fuzzy_eq!((-0.0f32).fract(), -0.0f32);
924         assert_fuzzy_eq!((-1.0f32).fract(), -0.0f32);
925         assert_fuzzy_eq!((-1.3f32).fract(), -0.3f32);
926         assert_fuzzy_eq!((-1.5f32).fract(), -0.5f32);
927         assert_fuzzy_eq!((-1.7f32).fract(), -0.7f32);
928     }
929
930     #[test]
931     fn test_real_consts() {
932         assert_fuzzy_eq!(Real::two_pi::<f32>(), 2f32 * Real::pi::<f32>());
933         assert_fuzzy_eq!(Real::frac_pi_2::<f32>(), Real::pi::<f32>() / 2f32);
934         assert_fuzzy_eq!(Real::frac_pi_3::<f32>(), Real::pi::<f32>() / 3f32);
935         assert_fuzzy_eq!(Real::frac_pi_4::<f32>(), Real::pi::<f32>() / 4f32);
936         assert_fuzzy_eq!(Real::frac_pi_6::<f32>(), Real::pi::<f32>() / 6f32);
937         assert_fuzzy_eq!(Real::frac_pi_8::<f32>(), Real::pi::<f32>() / 8f32);
938         assert_fuzzy_eq!(Real::frac_1_pi::<f32>(), 1f32 / Real::pi::<f32>());
939         assert_fuzzy_eq!(Real::frac_2_pi::<f32>(), 2f32 / Real::pi::<f32>());
940         assert_fuzzy_eq!(Real::frac_2_sqrtpi::<f32>(), 2f32 / Real::pi::<f32>().sqrt());
941         assert_fuzzy_eq!(Real::sqrt2::<f32>(), 2f32.sqrt());
942         assert_fuzzy_eq!(Real::frac_1_sqrt2::<f32>(), 1f32 / 2f32.sqrt());
943         assert_fuzzy_eq!(Real::log2_e::<f32>(), Real::e::<f32>().log2());
944         assert_fuzzy_eq!(Real::log10_e::<f32>(), Real::e::<f32>().log10());
945         assert_fuzzy_eq!(Real::log_2::<f32>(), 2f32.log());
946         assert_fuzzy_eq!(Real::log_10::<f32>(), 10f32.log());
947     }
948
949     #[test]
950     pub fn test_signed() {
951         assert_eq!(infinity.abs(), infinity);
952         assert_eq!(1f32.abs(), 1f32);
953         assert_eq!(0f32.abs(), 0f32);
954         assert_eq!((-0f32).abs(), 0f32);
955         assert_eq!((-1f32).abs(), 1f32);
956         assert_eq!(neg_infinity.abs(), infinity);
957         assert_eq!((1f32/neg_infinity).abs(), 0f32);
958         assert!(NaN.abs().is_NaN());
959
960         assert_eq!(infinity.signum(), 1f32);
961         assert_eq!(1f32.signum(), 1f32);
962         assert_eq!(0f32.signum(), 1f32);
963         assert_eq!((-0f32).signum(), -1f32);
964         assert_eq!((-1f32).signum(), -1f32);
965         assert_eq!(neg_infinity.signum(), -1f32);
966         assert_eq!((1f32/neg_infinity).signum(), -1f32);
967         assert!(NaN.signum().is_NaN());
968
969         assert!(infinity.is_positive());
970         assert!(1f32.is_positive());
971         assert!(0f32.is_positive());
972         assert!(!(-0f32).is_positive());
973         assert!(!(-1f32).is_positive());
974         assert!(!neg_infinity.is_positive());
975         assert!(!(1f32/neg_infinity).is_positive());
976         assert!(!NaN.is_positive());
977
978         assert!(!infinity.is_negative());
979         assert!(!1f32.is_negative());
980         assert!(!0f32.is_negative());
981         assert!((-0f32).is_negative());
982         assert!((-1f32).is_negative());
983         assert!(neg_infinity.is_negative());
984         assert!((1f32/neg_infinity).is_negative());
985         assert!(!NaN.is_negative());
986     }
987
988     #[test]
989     fn test_primitive() {
990         assert_eq!(Primitive::bits::<f32>(), sys::size_of::<f32>() * 8);
991         assert_eq!(Primitive::bytes::<f32>(), sys::size_of::<f32>());
992     }
993 }
994
995 //
996 // Local Variables:
997 // mode: rust
998 // fill-column: 78;
999 // indent-tabs-mode: nil
1000 // c-basic-offset: 4
1001 // buffer-file-coding-system: utf-8-unix
1002 // End:
1003 //