(index<- ) ./libstd/num/f32.rs
git branch: * master 5200215 auto merge of #14035 : alexcrichton/rust/experimental, r=huonw
modified: Fri May 9 13:02:28 2014
1 // Copyright 2012-2014 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 32-bits floats (`f32` type)
12
13 #![allow(missing_doc)]
14 #![allow(unsigned_negate)]
15
16 use prelude::*;
17
18 use cast;
19 use from_str::FromStr;
20 use libc::c_int;
21 use num::{FPCategory, FPNaN, FPInfinite , FPZero, FPSubnormal, FPNormal};
22 use num::strconv;
23 use num;
24 use intrinsics;
25
26 pub use core::f32::{RADIX, MANTISSA_DIGITS, DIGITS, EPSILON, MIN_VALUE};
27 pub use core::f32::{MIN_POS_VALUE, MAX_VALUE, MIN_EXP, MAX_EXP, MIN_10_EXP};
28 pub use core::f32::{MAX_10_EXP, NAN, INFINITY, NEG_INFINITY};
29 pub use core::f32::consts;
30
31 #[allow(dead_code)]
32 mod cmath {
33 use libc::{c_float, c_int};
34
35 #[link_name = "m"]
36 extern {
37 pub fn acosf(n: c_float) -> c_float;
38 pub fn asinf(n: c_float) -> c_float;
39 pub fn atanf(n: c_float) -> c_float;
40 pub fn atan2f(a: c_float, b: c_float) -> c_float;
41 pub fn cbrtf(n: c_float) -> c_float;
42 pub fn coshf(n: c_float) -> c_float;
43 pub fn erff(n: c_float) -> c_float;
44 pub fn erfcf(n: c_float) -> c_float;
45 pub fn expm1f(n: c_float) -> c_float;
46 pub fn fdimf(a: c_float, b: c_float) -> c_float;
47 pub fn frexpf(n: c_float, value: &mut c_int) -> c_float;
48 pub fn fmaxf(a: c_float, b: c_float) -> c_float;
49 pub fn fminf(a: c_float, b: c_float) -> c_float;
50 pub fn fmodf(a: c_float, b: c_float) -> c_float;
51 pub fn nextafterf(x: c_float, y: c_float) -> c_float;
52 pub fn hypotf(x: c_float, y: c_float) -> c_float;
53 pub fn ldexpf(x: c_float, n: c_int) -> c_float;
54 pub fn logbf(n: c_float) -> c_float;
55 pub fn log1pf(n: c_float) -> c_float;
56 pub fn ilogbf(n: c_float) -> c_int;
57 pub fn modff(n: c_float, iptr: &mut c_float) -> c_float;
58 pub fn sinhf(n: c_float) -> c_float;
59 pub fn tanf(n: c_float) -> c_float;
60 pub fn tanhf(n: c_float) -> c_float;
61 pub fn tgammaf(n: c_float) -> c_float;
62
63 #[cfg(unix)]
64 pub fn lgammaf_r(n: c_float, sign: &mut c_int) -> c_float;
65
66 #[cfg(windows)]
67 #[link_name="__lgammaf_r"]
68 pub fn lgammaf_r(n: c_float, sign: &mut c_int) -> c_float;
69 }
70 }
71
72 impl Float for f32 {
73 #[inline]
74 fn nan() -> f32 { NAN }
75
76 #[inline]
77 fn infinity() -> f32 { INFINITY }
78
79 #[inline]
80 fn neg_infinity() -> f32 { NEG_INFINITY }
81
82 #[inline]
83 fn neg_zero() -> f32 { -0.0 }
84
85 /// Returns `true` if the number is NaN
86 #[inline]
87 fn is_nan(self) -> bool { self != self }
88
89 /// Returns `true` if the number is infinite
90 #[inline]
91 fn is_infinite(self) -> bool {
92 self == Float::infinity() || self == Float::neg_infinity()
93 }
94
95 /// Returns `true` if the number is neither infinite or NaN
96 #[inline]
97 fn is_finite(self) -> bool {
98 !(self.is_nan() || self.is_infinite())
99 }
100
101 /// Returns `true` if the number is neither zero, infinite, subnormal or NaN
102 #[inline]
103 fn is_normal(self) -> bool {
104 self.classify() == FPNormal
105 }
106
107 /// Returns the floating point category of the number. If only one property
108 /// is going to be tested, it is generally faster to use the specific
109 /// predicate instead.
110 fn classify(self) -> FPCategory {
111 static EXP_MASK: u32 = 0x7f800000;
112 static MAN_MASK: u32 = 0x007fffff;
113
114 let bits: u32 = unsafe { cast::transmute(self) };
115 match (bits & MAN_MASK, bits & EXP_MASK) {
116 (0, 0) => FPZero,
117 (_, 0) => FPSubnormal,
118 (0, EXP_MASK) => FPInfinite,
119 (_, EXP_MASK) => FPNaN,
120 _ => FPNormal,
121 }
122 }
123
124 #[inline]
125 fn mantissa_digits(_: Option<f32>) -> uint { MANTISSA_DIGITS }
126
127 #[inline]
128 fn digits(_: Option<f32>) -> uint { DIGITS }
129
130 #[inline]
131 fn epsilon() -> f32 { EPSILON }
132
133 #[inline]
134 fn min_exp(_: Option<f32>) -> int { MIN_EXP }
135
136 #[inline]
137 fn max_exp(_: Option<f32>) -> int { MAX_EXP }
138
139 #[inline]
140 fn min_10_exp(_: Option<f32>) -> int { MIN_10_EXP }
141
142 #[inline]
143 fn max_10_exp(_: Option<f32>) -> int { MAX_10_EXP }
144
145 #[inline]
146 fn min_pos_value(_: Option<f32>) -> f32 { MIN_POS_VALUE }
147
148 /// Constructs a floating point number by multiplying `x` by 2 raised to the
149 /// power of `exp`
150 #[inline]
151 fn ldexp(x: f32, exp: int) -> f32 {
152 unsafe { cmath::ldexpf(x, exp as c_int) }
153 }
154
155 /// Breaks the number into a normalized fraction and a base-2 exponent,
156 /// satisfying:
157 ///
158 /// - `self = x * pow(2, exp)`
159 /// - `0.5 <= abs(x) < 1.0`
160 #[inline]
161 fn frexp(self) -> (f32, int) {
162 unsafe {
163 let mut exp = 0;
164 let x = cmath::frexpf(self, &mut exp);
165 (x, exp as int)
166 }
167 }
168
169 /// Returns the mantissa, exponent and sign as integers.
170 fn integer_decode(self) -> (u64, i16, i8) {
171 let bits: u32 = unsafe { cast::transmute(self) };
172 let sign: i8 = if bits >> 31 == 0 { 1 } else { -1 };
173 let mut exponent: i16 = ((bits >> 23) & 0xff) as i16;
174 let mantissa = if exponent == 0 {
175 (bits & 0x7fffff) << 1
176 } else {
177 (bits & 0x7fffff) | 0x800000
178 };
179 // Exponent bias + mantissa shift
180 exponent -= 127 + 23;
181 (mantissa as u64, exponent, sign)
182 }
183
184 /// Returns the next representable floating-point value in the direction of
185 /// `other`.
186 #[inline]
187 fn next_after(self, other: f32) -> f32 {
188 unsafe { cmath::nextafterf(self, other) }
189 }
190
191 /// Round half-way cases toward `NEG_INFINITY`
192 #[inline]
193 fn floor(self) -> f32 {
194 unsafe { intrinsics::floorf32(self) }
195 }
196
197 /// Round half-way cases toward `INFINITY`
198 #[inline]
199 fn ceil(self) -> f32 {
200 unsafe { intrinsics::ceilf32(self) }
201 }
202
203 /// Round half-way cases away from `0.0`
204 #[inline]
205 fn round(self) -> f32 {
206 unsafe { intrinsics::roundf32(self) }
207 }
208
209 /// The integer part of the number (rounds towards `0.0`)
210 #[inline]
211 fn trunc(self) -> f32 {
212 unsafe { intrinsics::truncf32(self) }
213 }
214
215 /// The fractional part of the number, satisfying:
216 ///
217 /// ```rust
218 /// let x = 1.65f32;
219 /// assert!(x == x.trunc() + x.fract())
220 /// ```
221 #[inline]
222 fn fract(self) -> f32 { self - self.trunc() }
223
224 #[inline]
225 fn max(self, other: f32) -> f32 {
226 unsafe { cmath::fmaxf(self, other) }
227 }
228
229 #[inline]
230 fn min(self, other: f32) -> f32 {
231 unsafe { cmath::fminf(self, other) }
232 }
233
234 /// Fused multiply-add. Computes `(self * a) + b` with only one rounding
235 /// error. This produces a more accurate result with better performance than
236 /// a separate multiplication operation followed by an add.
237 #[inline]
238 fn mul_add(self, a: f32, b: f32) -> f32 {
239 unsafe { intrinsics::fmaf32(self, a, b) }
240 }
241
242 /// The reciprocal (multiplicative inverse) of the number
243 #[inline]
244 fn recip(self) -> f32 { 1.0 / self }
245
246 fn powi(self, n: i32) -> f32 {
247 unsafe { intrinsics::powif32(self, n) }
248 }
249
250 #[inline]
251 fn powf(self, n: f32) -> f32 {
252 unsafe { intrinsics::powf32(self, n) }
253 }
254
255 /// sqrt(2.0)
256 #[inline]
257 fn sqrt2() -> f32 { consts::SQRT2 }
258
259 /// 1.0 / sqrt(2.0)
260 #[inline]
261 fn frac_1_sqrt2() -> f32 { consts::FRAC_1_SQRT2 }
262
263 #[inline]
264 fn sqrt(self) -> f32 {
265 unsafe { intrinsics::sqrtf32(self) }
266 }
267
268 #[inline]
269 fn rsqrt(self) -> f32 { self.sqrt().recip() }
270
271 #[inline]
272 fn cbrt(self) -> f32 {
273 unsafe { cmath::cbrtf(self) }
274 }
275
276 #[inline]
277 fn hypot(self, other: f32) -> f32 {
278 unsafe { cmath::hypotf(self, other) }
279 }
280
281 /// Archimedes' constant
282 #[inline]
283 fn pi() -> f32 { consts::PI }
284
285 /// 2.0 * pi
286 #[inline]
287 fn two_pi() -> f32 { consts::PI_2 }
288
289 /// pi / 2.0
290 #[inline]
291 fn frac_pi_2() -> f32 { consts::FRAC_PI_2 }
292
293 /// pi / 3.0
294 #[inline]
295 fn frac_pi_3() -> f32 { consts::FRAC_PI_3 }
296
297 /// pi / 4.0
298 #[inline]
299 fn frac_pi_4() -> f32 { consts::FRAC_PI_4 }
300
301 /// pi / 6.0
302 #[inline]
303 fn frac_pi_6() -> f32 { consts::FRAC_PI_6 }
304
305 /// pi / 8.0
306 #[inline]
307 fn frac_pi_8() -> f32 { consts::FRAC_PI_8 }
308
309 /// 1 .0/ pi
310 #[inline]
311 fn frac_1_pi() -> f32 { consts::FRAC_1_PI }
312
313 /// 2.0 / pi
314 #[inline]
315 fn frac_2_pi() -> f32 { consts::FRAC_2_PI }
316
317 /// 2.0 / sqrt(pi)
318 #[inline]
319 fn frac_2_sqrtpi() -> f32 { consts::FRAC_2_SQRTPI }
320
321 #[inline]
322 fn sin(self) -> f32 {
323 unsafe { intrinsics::sinf32(self) }
324 }
325
326 #[inline]
327 fn cos(self) -> f32 {
328 unsafe { intrinsics::cosf32(self) }
329 }
330
331 #[inline]
332 fn tan(self) -> f32 {
333 unsafe { cmath::tanf(self) }
334 }
335
336 #[inline]
337 fn asin(self) -> f32 {
338 unsafe { cmath::asinf(self) }
339 }
340
341 #[inline]
342 fn acos(self) -> f32 {
343 unsafe { cmath::acosf(self) }
344 }
345
346 #[inline]
347 fn atan(self) -> f32 {
348 unsafe { cmath::atanf(self) }
349 }
350
351 #[inline]
352 fn atan2(self, other: f32) -> f32 {
353 unsafe { cmath::atan2f(self, other) }
354 }
355
356 /// Simultaneously computes the sine and cosine of the number
357 #[inline]
358 fn sin_cos(self) -> (f32, f32) {
359 (self.sin(), self.cos())
360 }
361
362 /// Euler's number
363 #[inline]
364 fn e() -> f32 { consts::E }
365
366 /// log2(e)
367 #[inline]
368 fn log2_e() -> f32 { consts::LOG2_E }
369
370 /// log10(e)
371 #[inline]
372 fn log10_e() -> f32 { consts::LOG10_E }
373
374 /// ln(2.0)
375 #[inline]
376 fn ln_2() -> f32 { consts::LN_2 }
377
378 /// ln(10.0)
379 #[inline]
380 fn ln_10() -> f32 { consts::LN_10 }
381
382 /// Returns the exponential of the number
383 #[inline]
384 fn exp(self) -> f32 {
385 unsafe { intrinsics::expf32(self) }
386 }
387
388 /// Returns 2 raised to the power of the number
389 #[inline]
390 fn exp2(self) -> f32 {
391 unsafe { intrinsics::exp2f32(self) }
392 }
393
394 /// Returns the exponential of the number, minus `1`, in a way that is
395 /// accurate even if the number is close to zero
396 #[inline]
397 fn exp_m1(self) -> f32 {
398 unsafe { cmath::expm1f(self) }
399 }
400
401 /// Returns the natural logarithm of the number
402 #[inline]
403 fn ln(self) -> f32 {
404 unsafe { intrinsics::logf32(self) }
405 }
406
407 /// Returns the logarithm of the number with respect to an arbitrary base
408 #[inline]
409 fn log(self, base: f32) -> f32 { self.ln() / base.ln() }
410
411 /// Returns the base 2 logarithm of the number
412 #[inline]
413 fn log2(self) -> f32 {
414 unsafe { intrinsics::log2f32(self) }
415 }
416
417 /// Returns the base 10 logarithm of the number
418 #[inline]
419 fn log10(self) -> f32 {
420 unsafe { intrinsics::log10f32(self) }
421 }
422
423 /// Returns the natural logarithm of the number plus `1` (`ln(1+n)`) more
424 /// accurately than if the operations were performed separately
425 #[inline]
426 fn ln_1p(self) -> f32 {
427 unsafe { cmath::log1pf(self) }
428 }
429
430 #[inline]
431 fn sinh(self) -> f32 {
432 unsafe { cmath::sinhf(self) }
433 }
434
435 #[inline]
436 fn cosh(self) -> f32 {
437 unsafe { cmath::coshf(self) }
438 }
439
440 #[inline]
441 fn tanh(self) -> f32 {
442 unsafe { cmath::tanhf(self) }
443 }
444
445 /// Inverse hyperbolic sine
446 ///
447 /// # Returns
448 ///
449 /// - on success, the inverse hyperbolic sine of `self` will be returned
450 /// - `self` if `self` is `0.0`, `-0.0`, `INFINITY`, or `NEG_INFINITY`
451 /// - `NAN` if `self` is `NAN`
452 #[inline]
453 fn asinh(self) -> f32 {
454 match self {
455 NEG_INFINITY => NEG_INFINITY,
456 x => (x + ((x * x) + 1.0).sqrt()).ln(),
457 }
458 }
459
460 /// Inverse hyperbolic cosine
461 ///
462 /// # Returns
463 ///
464 /// - on success, the inverse hyperbolic cosine of `self` will be returned
465 /// - `INFINITY` if `self` is `INFINITY`
466 /// - `NAN` if `self` is `NAN` or `self < 1.0` (including `NEG_INFINITY`)
467 #[inline]
468 fn acosh(self) -> f32 {
469 match self {
470 x if x < 1.0 => Float::nan(),
471 x => (x + ((x * x) - 1.0).sqrt()).ln(),
472 }
473 }
474
475 /// Inverse hyperbolic tangent
476 ///
477 /// # Returns
478 ///
479 /// - on success, the inverse hyperbolic tangent of `self` will be returned
480 /// - `self` if `self` is `0.0` or `-0.0`
481 /// - `INFINITY` if `self` is `1.0`
482 /// - `NEG_INFINITY` if `self` is `-1.0`
483 /// - `NAN` if the `self` is `NAN` or outside the domain of `-1.0 <= self <= 1.0`
484 /// (including `INFINITY` and `NEG_INFINITY`)
485 #[inline]
486 fn atanh(self) -> f32 {
487 0.5 * ((2.0 * self) / (1.0 - self)).ln_1p()
488 }
489
490 /// Converts to degrees, assuming the number is in radians
491 #[inline]
492 fn to_degrees(self) -> f32 { self * (180.0f32 / Float::pi()) }
493
494 /// Converts to radians, assuming the number is in degrees
495 #[inline]
496 fn to_radians(self) -> f32 {
497 let value: f32 = Float::pi();
498 self * (value / 180.0f32)
499 }
500 }
501
502 //
503 // Section: String Conversions
504 //
505
506 /// Converts a float to a string
507 ///
508 /// # Arguments
509 ///
510 /// * num - The float value
511 #[inline]
512 pub fn to_str(num: f32) -> ~str {
513 let (r, _) = strconv::float_to_str_common(
514 num, 10u, true, strconv::SignNeg, strconv::DigAll, strconv::ExpNone, false);
515 r
516 }
517
518 /// Converts a float to a string in hexadecimal format
519 ///
520 /// # Arguments
521 ///
522 /// * num - The float value
523 #[inline]
524 pub fn to_str_hex(num: f32) -> ~str {
525 let (r, _) = strconv::float_to_str_common(
526 num, 16u, true, strconv::SignNeg, strconv::DigAll, strconv::ExpNone, false);
527 r
528 }
529
530 /// Converts a float to a string in a given radix, and a flag indicating
531 /// whether it's a special value
532 ///
533 /// # Arguments
534 ///
535 /// * num - The float value
536 /// * radix - The base to use
537 #[inline]
538 pub fn to_str_radix_special(num: f32, rdx: uint) -> (~str, bool) {
539 strconv::float_to_str_common(num, rdx, true,
540 strconv::SignNeg, strconv::DigAll, strconv::ExpNone, false)
541 }
542
543 /// Converts a float to a string with exactly the number of
544 /// provided significant digits
545 ///
546 /// # Arguments
547 ///
548 /// * num - The float value
549 /// * digits - The number of significant digits
550 #[inline]
551 pub fn to_str_exact(num: f32, dig: uint) -> ~str {
552 let (r, _) = strconv::float_to_str_common(
553 num, 10u, true, strconv::SignNeg, strconv::DigExact(dig), strconv::ExpNone, false);
554 r
555 }
556
557 /// Converts a float to a string with a maximum number of
558 /// significant digits
559 ///
560 /// # Arguments
561 ///
562 /// * num - The float value
563 /// * digits - The number of significant digits
564 #[inline]
565 pub fn to_str_digits(num: f32, dig: uint) -> ~str {
566 let (r, _) = strconv::float_to_str_common(
567 num, 10u, true, strconv::SignNeg, strconv::DigMax(dig), strconv::ExpNone, false);
568 r
569 }
570
571 /// Converts a float to a string using the exponential notation with exactly the number of
572 /// provided digits after the decimal point in the significand
573 ///
574 /// # Arguments
575 ///
576 /// * num - The float value
577 /// * digits - The number of digits after the decimal point
578 /// * upper - Use `E` instead of `e` for the exponent sign
579 #[inline]
580 pub fn to_str_exp_exact(num: f32, dig: uint, upper: bool) -> ~str {
581 let (r, _) = strconv::float_to_str_common(
582 num, 10u, true, strconv::SignNeg, strconv::DigExact(dig), strconv::ExpDec, upper);
583 r
584 }
585
586 /// Converts a float to a string using the exponential notation with the maximum number of
587 /// digits after the decimal point in the significand
588 ///
589 /// # Arguments
590 ///
591 /// * num - The float value
592 /// * digits - The number of digits after the decimal point
593 /// * upper - Use `E` instead of `e` for the exponent sign
594 #[inline]
595 pub fn to_str_exp_digits(num: f32, dig: uint, upper: bool) -> ~str {
596 let (r, _) = strconv::float_to_str_common(
597 num, 10u, true, strconv::SignNeg, strconv::DigMax(dig), strconv::ExpDec, upper);
598 r
599 }
600
601 impl num::ToStrRadix for f32 {
602 /// Converts a float to a string in a given radix
603 ///
604 /// # Arguments
605 ///
606 /// * num - The float value
607 /// * radix - The base to use
608 ///
609 /// # Failure
610 ///
611 /// Fails if called on a special value like `inf`, `-inf` or `NaN` due to
612 /// possible misinterpretation of the result at higher bases. If those values
613 /// are expected, use `to_str_radix_special()` instead.
614 #[inline]
615 fn to_str_radix(&self, rdx: uint) -> ~str {
616 let (r, special) = strconv::float_to_str_common(
617 *self, rdx, true, strconv::SignNeg, strconv::DigAll, strconv::ExpNone, false);
618 if special { fail!("number has a special value, \
619 try to_str_radix_special() if those are expected") }
620 r
621 }
622 }
623
624 /// Convert a string in base 16 to a float.
625 /// Accepts an optional binary exponent.
626 ///
627 /// This function accepts strings such as
628 ///
629 /// * 'a4.fe'
630 /// * '+a4.fe', equivalent to 'a4.fe'
631 /// * '-a4.fe'
632 /// * '2b.aP128', or equivalently, '2b.ap128'
633 /// * '2b.aP-128'
634 /// * '.' (understood as 0)
635 /// * 'c.'
636 /// * '.c', or, equivalently, '0.c'
637 /// * '+inf', 'inf', '-inf', 'NaN'
638 ///
639 /// Leading and trailing whitespace represent an error.
640 ///
641 /// # Arguments
642 ///
643 /// * num - A string
644 ///
645 /// # Return value
646 ///
647 /// `None` if the string did not represent a valid number. Otherwise,
648 /// `Some(n)` where `n` is the floating-point number represented by `[num]`.
649 #[inline]
650 pub fn from_str_hex(num: &str) -> Option<f32> {
651 strconv::from_str_common(num, 16u, true, true, true,
652 strconv::ExpBin, false, false)
653 }
654
655 impl FromStr for f32 {
656 /// Convert a string in base 10 to a float.
657 /// Accepts an optional decimal exponent.
658 ///
659 /// This function accepts strings such as
660 ///
661 /// * '3.14'
662 /// * '+3.14', equivalent to '3.14'
663 /// * '-3.14'
664 /// * '2.5E10', or equivalently, '2.5e10'
665 /// * '2.5E-10'
666 /// * '.' (understood as 0)
667 /// * '5.'
668 /// * '.5', or, equivalently, '0.5'
669 /// * '+inf', 'inf', '-inf', 'NaN'
670 ///
671 /// Leading and trailing whitespace represent an error.
672 ///
673 /// # Arguments
674 ///
675 /// * num - A string
676 ///
677 /// # Return value
678 ///
679 /// `None` if the string did not represent a valid number. Otherwise,
680 /// `Some(n)` where `n` is the floating-point number represented by `num`.
681 #[inline]
682 fn from_str(val: &str) -> Option<f32> {
683 strconv::from_str_common(val, 10u, true, true, true,
684 strconv::ExpDec, false, false)
685 }
686 }
687
688 impl num::FromStrRadix for f32 {
689 /// Convert a string in a given base to a float.
690 ///
691 /// Due to possible conflicts, this function does **not** accept
692 /// the special values `inf`, `-inf`, `+inf` and `NaN`, **nor**
693 /// does it recognize exponents of any kind.
694 ///
695 /// Leading and trailing whitespace represent an error.
696 ///
697 /// # Arguments
698 ///
699 /// * num - A string
700 /// * radix - The base to use. Must lie in the range [2 .. 36]
701 ///
702 /// # Return value
703 ///
704 /// `None` if the string did not represent a valid number. Otherwise,
705 /// `Some(n)` where `n` is the floating-point number represented by `num`.
706 #[inline]
707 fn from_str_radix(val: &str, rdx: uint) -> Option<f32> {
708 strconv::from_str_common(val, rdx, true, true, false,
709 strconv::ExpNone, false, false)
710 }
711 }
712
713 #[cfg(test)]
714 mod tests {
715 use f32::*;
716 use num::*;
717 use num;
718
719 #[test]
720 fn test_min_nan() {
721 assert_eq!(NAN.min(2.0), 2.0);
722 assert_eq!(2.0f32.min(NAN), 2.0);
723 }
724
725 #[test]
726 fn test_max_nan() {
727 assert_eq!(NAN.max(2.0), 2.0);
728 assert_eq!(2.0f32.max(NAN), 2.0);
729 }
730
731 #[test]
732 fn test_num() {
733 num::test_num(10f32, 2f32);
734 }
735
736 #[test]
737 fn test_floor() {
738 assert_approx_eq!(1.0f32.floor(), 1.0f32);
739 assert_approx_eq!(1.3f32.floor(), 1.0f32);
740 assert_approx_eq!(1.5f32.floor(), 1.0f32);
741 assert_approx_eq!(1.7f32.floor(), 1.0f32);
742 assert_approx_eq!(0.0f32.floor(), 0.0f32);
743 assert_approx_eq!((-0.0f32).floor(), -0.0f32);
744 assert_approx_eq!((-1.0f32).floor(), -1.0f32);
745 assert_approx_eq!((-1.3f32).floor(), -2.0f32);
746 assert_approx_eq!((-1.5f32).floor(), -2.0f32);
747 assert_approx_eq!((-1.7f32).floor(), -2.0f32);
748 }
749
750 #[test]
751 fn test_ceil() {
752 assert_approx_eq!(1.0f32.ceil(), 1.0f32);
753 assert_approx_eq!(1.3f32.ceil(), 2.0f32);
754 assert_approx_eq!(1.5f32.ceil(), 2.0f32);
755 assert_approx_eq!(1.7f32.ceil(), 2.0f32);
756 assert_approx_eq!(0.0f32.ceil(), 0.0f32);
757 assert_approx_eq!((-0.0f32).ceil(), -0.0f32);
758 assert_approx_eq!((-1.0f32).ceil(), -1.0f32);
759 assert_approx_eq!((-1.3f32).ceil(), -1.0f32);
760 assert_approx_eq!((-1.5f32).ceil(), -1.0f32);
761 assert_approx_eq!((-1.7f32).ceil(), -1.0f32);
762 }
763
764 #[test]
765 fn test_round() {
766 assert_approx_eq!(1.0f32.round(), 1.0f32);
767 assert_approx_eq!(1.3f32.round(), 1.0f32);
768 assert_approx_eq!(1.5f32.round(), 2.0f32);
769 assert_approx_eq!(1.7f32.round(), 2.0f32);
770 assert_approx_eq!(0.0f32.round(), 0.0f32);
771 assert_approx_eq!((-0.0f32).round(), -0.0f32);
772 assert_approx_eq!((-1.0f32).round(), -1.0f32);
773 assert_approx_eq!((-1.3f32).round(), -1.0f32);
774 assert_approx_eq!((-1.5f32).round(), -2.0f32);
775 assert_approx_eq!((-1.7f32).round(), -2.0f32);
776 }
777
778 #[test]
779 fn test_trunc() {
780 assert_approx_eq!(1.0f32.trunc(), 1.0f32);
781 assert_approx_eq!(1.3f32.trunc(), 1.0f32);
782 assert_approx_eq!(1.5f32.trunc(), 1.0f32);
783 assert_approx_eq!(1.7f32.trunc(), 1.0f32);
784 assert_approx_eq!(0.0f32.trunc(), 0.0f32);
785 assert_approx_eq!((-0.0f32).trunc(), -0.0f32);
786 assert_approx_eq!((-1.0f32).trunc(), -1.0f32);
787 assert_approx_eq!((-1.3f32).trunc(), -1.0f32);
788 assert_approx_eq!((-1.5f32).trunc(), -1.0f32);
789 assert_approx_eq!((-1.7f32).trunc(), -1.0f32);
790 }
791
792 #[test]
793 fn test_fract() {
794 assert_approx_eq!(1.0f32.fract(), 0.0f32);
795 assert_approx_eq!(1.3f32.fract(), 0.3f32);
796 assert_approx_eq!(1.5f32.fract(), 0.5f32);
797 assert_approx_eq!(1.7f32.fract(), 0.7f32);
798 assert_approx_eq!(0.0f32.fract(), 0.0f32);
799 assert_approx_eq!((-0.0f32).fract(), -0.0f32);
800 assert_approx_eq!((-1.0f32).fract(), -0.0f32);
801 assert_approx_eq!((-1.3f32).fract(), -0.3f32);
802 assert_approx_eq!((-1.5f32).fract(), -0.5f32);
803 assert_approx_eq!((-1.7f32).fract(), -0.7f32);
804 }
805
806 #[test]
807 fn test_asinh() {
808 assert_eq!(0.0f32.asinh(), 0.0f32);
809 assert_eq!((-0.0f32).asinh(), -0.0f32);
810
811 let inf: f32 = Float::infinity();
812 let neg_inf: f32 = Float::neg_infinity();
813 let nan: f32 = Float::nan();
814 assert_eq!(inf.asinh(), inf);
815 assert_eq!(neg_inf.asinh(), neg_inf);
816 assert!(nan.asinh().is_nan());
817 assert_approx_eq!(2.0f32.asinh(), 1.443635475178810342493276740273105f32);
818 assert_approx_eq!((-2.0f32).asinh(), -1.443635475178810342493276740273105f32);
819 }
820
821 #[test]
822 fn test_acosh() {
823 assert_eq!(1.0f32.acosh(), 0.0f32);
824 assert!(0.999f32.acosh().is_nan());
825
826 let inf: f32 = Float::infinity();
827 let neg_inf: f32 = Float::neg_infinity();
828 let nan: f32 = Float::nan();
829 assert_eq!(inf.acosh(), inf);
830 assert!(neg_inf.acosh().is_nan());
831 assert!(nan.acosh().is_nan());
832 assert_approx_eq!(2.0f32.acosh(), 1.31695789692481670862504634730796844f32);
833 assert_approx_eq!(3.0f32.acosh(), 1.76274717403908605046521864995958461f32);
834 }
835
836 #[test]
837 fn test_atanh() {
838 assert_eq!(0.0f32.atanh(), 0.0f32);
839 assert_eq!((-0.0f32).atanh(), -0.0f32);
840
841 let inf32: f32 = Float::infinity();
842 let neg_inf32: f32 = Float::neg_infinity();
843 assert_eq!(1.0f32.atanh(), inf32);
844 assert_eq!((-1.0f32).atanh(), neg_inf32);
845
846 assert!(2f64.atanh().atanh().is_nan());
847 assert!((-2f64).atanh().atanh().is_nan());
848
849 let inf64: f32 = Float::infinity();
850 let neg_inf64: f32 = Float::neg_infinity();
851 let nan32: f32 = Float::nan();
852 assert!(inf64.atanh().is_nan());
853 assert!(neg_inf64.atanh().is_nan());
854 assert!(nan32.atanh().is_nan());
855
856 assert_approx_eq!(0.5f32.atanh(), 0.54930614433405484569762261846126285f32);
857 assert_approx_eq!((-0.5f32).atanh(), -0.54930614433405484569762261846126285f32);
858 }
859
860 #[test]
861 fn test_real_consts() {
862 let pi: f32 = Float::pi();
863 let two_pi: f32 = Float::two_pi();
864 let frac_pi_2: f32 = Float::frac_pi_2();
865 let frac_pi_3: f32 = Float::frac_pi_3();
866 let frac_pi_4: f32 = Float::frac_pi_4();
867 let frac_pi_6: f32 = Float::frac_pi_6();
868 let frac_pi_8: f32 = Float::frac_pi_8();
869 let frac_1_pi: f32 = Float::frac_1_pi();
870 let frac_2_pi: f32 = Float::frac_2_pi();
871 let frac_2_sqrtpi: f32 = Float::frac_2_sqrtpi();
872 let sqrt2: f32 = Float::sqrt2();
873 let frac_1_sqrt2: f32 = Float::frac_1_sqrt2();
874 let e: f32 = Float::e();
875 let log2_e: f32 = Float::log2_e();
876 let log10_e: f32 = Float::log10_e();
877 let ln_2: f32 = Float::ln_2();
878 let ln_10: f32 = Float::ln_10();
879
880 assert_approx_eq!(two_pi, 2f32 * pi);
881 assert_approx_eq!(frac_pi_2, pi / 2f32);
882 assert_approx_eq!(frac_pi_3, pi / 3f32);
883 assert_approx_eq!(frac_pi_4, pi / 4f32);
884 assert_approx_eq!(frac_pi_6, pi / 6f32);
885 assert_approx_eq!(frac_pi_8, pi / 8f32);
886 assert_approx_eq!(frac_1_pi, 1f32 / pi);
887 assert_approx_eq!(frac_2_pi, 2f32 / pi);
888 assert_approx_eq!(frac_2_sqrtpi, 2f32 / pi.sqrt());
889 assert_approx_eq!(sqrt2, 2f32.sqrt());
890 assert_approx_eq!(frac_1_sqrt2, 1f32 / 2f32.sqrt());
891 assert_approx_eq!(log2_e, e.log2());
892 assert_approx_eq!(log10_e, e.log10());
893 assert_approx_eq!(ln_2, 2f32.ln());
894 assert_approx_eq!(ln_10, 10f32.ln());
895 }
896
897 #[test]
898 pub fn test_abs() {
899 assert_eq!(INFINITY.abs(), INFINITY);
900 assert_eq!(1f32.abs(), 1f32);
901 assert_eq!(0f32.abs(), 0f32);
902 assert_eq!((-0f32).abs(), 0f32);
903 assert_eq!((-1f32).abs(), 1f32);
904 assert_eq!(NEG_INFINITY.abs(), INFINITY);
905 assert_eq!((1f32/NEG_INFINITY).abs(), 0f32);
906 assert!(NAN.abs().is_nan());
907 }
908
909 #[test]
910 fn test_abs_sub() {
911 assert_eq!((-1f32).abs_sub(&1f32), 0f32);
912 assert_eq!(1f32.abs_sub(&1f32), 0f32);
913 assert_eq!(1f32.abs_sub(&0f32), 1f32);
914 assert_eq!(1f32.abs_sub(&-1f32), 2f32);
915 assert_eq!(NEG_INFINITY.abs_sub(&0f32), 0f32);
916 assert_eq!(INFINITY.abs_sub(&1f32), INFINITY);
917 assert_eq!(0f32.abs_sub(&NEG_INFINITY), INFINITY);
918 assert_eq!(0f32.abs_sub(&INFINITY), 0f32);
919 }
920
921 #[test]
922 fn test_abs_sub_nowin() {
923 assert!(NAN.abs_sub(&-1f32).is_nan());
924 assert!(1f32.abs_sub(&NAN).is_nan());
925 }
926
927 #[test]
928 fn test_signum() {
929 assert_eq!(INFINITY.signum(), 1f32);
930 assert_eq!(1f32.signum(), 1f32);
931 assert_eq!(0f32.signum(), 1f32);
932 assert_eq!((-0f32).signum(), -1f32);
933 assert_eq!((-1f32).signum(), -1f32);
934 assert_eq!(NEG_INFINITY.signum(), -1f32);
935 assert_eq!((1f32/NEG_INFINITY).signum(), -1f32);
936 assert!(NAN.signum().is_nan());
937 }
938
939 #[test]
940 fn test_is_positive() {
941 assert!(INFINITY.is_positive());
942 assert!(1f32.is_positive());
943 assert!(0f32.is_positive());
944 assert!(!(-0f32).is_positive());
945 assert!(!(-1f32).is_positive());
946 assert!(!NEG_INFINITY.is_positive());
947 assert!(!(1f32/NEG_INFINITY).is_positive());
948 assert!(!NAN.is_positive());
949 }
950
951 #[test]
952 fn test_is_negative() {
953 assert!(!INFINITY.is_negative());
954 assert!(!1f32.is_negative());
955 assert!(!0f32.is_negative());
956 assert!((-0f32).is_negative());
957 assert!((-1f32).is_negative());
958 assert!(NEG_INFINITY.is_negative());
959 assert!((1f32/NEG_INFINITY).is_negative());
960 assert!(!NAN.is_negative());
961 }
962
963 #[test]
964 fn test_is_normal() {
965 let nan: f32 = Float::nan();
966 let inf: f32 = Float::infinity();
967 let neg_inf: f32 = Float::neg_infinity();
968 let zero: f32 = Zero::zero();
969 let neg_zero: f32 = Float::neg_zero();
970 assert!(!nan.is_normal());
971 assert!(!inf.is_normal());
972 assert!(!neg_inf.is_normal());
973 assert!(!zero.is_normal());
974 assert!(!neg_zero.is_normal());
975 assert!(1f32.is_normal());
976 assert!(1e-37f32.is_normal());
977 assert!(!1e-38f32.is_normal());
978 }
979
980 #[test]
981 fn test_classify() {
982 let nan: f32 = Float::nan();
983 let inf: f32 = Float::infinity();
984 let neg_inf: f32 = Float::neg_infinity();
985 let zero: f32 = Zero::zero();
986 let neg_zero: f32 = Float::neg_zero();
987 assert_eq!(nan.classify(), FPNaN);
988 assert_eq!(inf.classify(), FPInfinite);
989 assert_eq!(neg_inf.classify(), FPInfinite);
990 assert_eq!(zero.classify(), FPZero);
991 assert_eq!(neg_zero.classify(), FPZero);
992 assert_eq!(1f32.classify(), FPNormal);
993 assert_eq!(1e-37f32.classify(), FPNormal);
994 assert_eq!(1e-38f32.classify(), FPSubnormal);
995 }
996
997 #[test]
998 fn test_ldexp() {
999 // We have to use from_str until base-2 exponents
1000 // are supported in floating-point literals
1001 let f1: f32 = from_str_hex("1p-123").unwrap();
1002 let f2: f32 = from_str_hex("1p-111").unwrap();
1003 assert_eq!(Float::ldexp(1f32, -123), f1);
1004 assert_eq!(Float::ldexp(1f32, -111), f2);
1005
1006 assert_eq!(Float::ldexp(0f32, -123), 0f32);
1007 assert_eq!(Float::ldexp(-0f32, -123), -0f32);
1008
1009 let inf: f32 = Float::infinity();
1010 let neg_inf: f32 = Float::neg_infinity();
1011 let nan: f32 = Float::nan();
1012 assert_eq!(Float::ldexp(inf, -123), inf);
1013 assert_eq!(Float::ldexp(neg_inf, -123), neg_inf);
1014 assert!(Float::ldexp(nan, -123).is_nan());
1015 }
1016
1017 #[test]
1018 fn test_frexp() {
1019 // We have to use from_str until base-2 exponents
1020 // are supported in floating-point literals
1021 let f1: f32 = from_str_hex("1p-123").unwrap();
1022 let f2: f32 = from_str_hex("1p-111").unwrap();
1023 let (x1, exp1) = f1.frexp();
1024 let (x2, exp2) = f2.frexp();
1025 assert_eq!((x1, exp1), (0.5f32, -122));
1026 assert_eq!((x2, exp2), (0.5f32, -110));
1027 assert_eq!(Float::ldexp(x1, exp1), f1);
1028 assert_eq!(Float::ldexp(x2, exp2), f2);
1029
1030 assert_eq!(0f32.frexp(), (0f32, 0));
1031 assert_eq!((-0f32).frexp(), (-0f32, 0));
1032 }
1033
1034 #[test] #[ignore(cfg(windows))] // FIXME #8755
1035 fn test_frexp_nowin() {
1036 let inf: f32 = Float::infinity();
1037 let neg_inf: f32 = Float::neg_infinity();
1038 let nan: f32 = Float::nan();
1039 assert_eq!(match inf.frexp() { (x, _) => x }, inf)
1040 assert_eq!(match neg_inf.frexp() { (x, _) => x }, neg_inf)
1041 assert!(match nan.frexp() { (x, _) => x.is_nan() })
1042 }
1043
1044 #[test]
1045 fn test_integer_decode() {
1046 assert_eq!(3.14159265359f32.integer_decode(), (13176795u64, -22i16, 1i8));
1047 assert_eq!((-8573.5918555f32).integer_decode(), (8779358u64, -10i16, -1i8));
1048 assert_eq!(2f32.powf(100.0).integer_decode(), (8388608u64, 77i16, 1i8));
1049 assert_eq!(0f32.integer_decode(), (0u64, -150i16, 1i8));
1050 assert_eq!((-0f32).integer_decode(), (0u64, -150i16, -1i8));
1051 assert_eq!(INFINITY.integer_decode(), (8388608u64, 105i16, 1i8));
1052 assert_eq!(NEG_INFINITY.integer_decode(), (8388608u64, 105i16, -1i8));
1053 assert_eq!(NAN.integer_decode(), (12582912u64, 105i16, 1i8));
1054 }
1055 }
libstd/num/f32.rs:594:10-594:10 -fn- definition:
pub fn to_str_exp_digits(num: f32, dig: uint, upper: bool) -> ~str {
let (r, _) = strconv::float_to_str_common(
num, 10u, true, strconv::SignNeg, strconv::DigMax(dig), strconv::ExpDec, upper);
references:- 2libstd/fmt/mod.rs:
1202: Some(i) => ::$ty::to_str_exp_exact(self.abs(), i, true),
1203: None => ::$ty::to_str_exp_digits(self.abs(), 6, true)
1204: };
libstd/num/f32.rs:579:10-579:10 -fn- definition:
pub fn to_str_exp_exact(num: f32, dig: uint, upper: bool) -> ~str {
let (r, _) = strconv::float_to_str_common(
num, 10u, true, strconv::SignNeg, strconv::DigExact(dig), strconv::ExpDec, upper);
references:- 2libstd/fmt/mod.rs:
1190: let s = match fmt.precision {
1191: Some(i) => ::$ty::to_str_exp_exact(self.abs(), i, false),
1192: None => ::$ty::to_str_exp_digits(self.abs(), 6, false)
--
1201: let s = match fmt.precision {
1202: Some(i) => ::$ty::to_str_exp_exact(self.abs(), i, true),
1203: None => ::$ty::to_str_exp_digits(self.abs(), 6, true)