(index<- ) ./libstd/num/float.rs
1 // Copyright 2012 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 //! Operations and constants for `float`
12
13 // Even though this module exports everything defined in it,
14 // because it contains re-exports, we also have to explicitly
15 // export locally defined things. That's a bit annoying.
16
17
18 // export when m_float == c_double
19
20
21 // PORT this must match in width according to architecture
22
23 #[allow(missing_doc)];
24 #[allow(non_uppercase_statics)];
25
26 use default::Default;
27 use num::{Zero, One, strconv};
28 use num::FPCategory;
29 use num;
30 use prelude::*;
31 use to_str;
32
33 pub static NaN: float = 0.0/0.0;
34
35 pub static infinity: float = 1.0/0.0;
36
37 pub static neg_infinity: float = -1.0/0.0;
38
39 /* Module: consts */
40 pub mod consts {
41 // FIXME (requires Issue #1433 to fix): replace with mathematical
42 // constants from cmath.
43 /// Archimedes' constant
44 pub static pi: float = 3.14159265358979323846264338327950288;
45
46 /// pi/2.0
47 pub static frac_pi_2: float = 1.57079632679489661923132169163975144;
48
49 /// pi/4.0
50 pub static frac_pi_4: float = 0.785398163397448309615660845819875721;
51
52 /// 1.0/pi
53 pub static frac_1_pi: float = 0.318309886183790671537767526745028724;
54
55 /// 2.0/pi
56 pub static frac_2_pi: float = 0.636619772367581343075535053490057448;
57
58 /// 2.0/sqrt(pi)
59 pub static frac_2_sqrtpi: float = 1.12837916709551257389615890312154517;
60
61 /// sqrt(2.0)
62 pub static sqrt2: float = 1.41421356237309504880168872420969808;
63
64 /// 1.0/sqrt(2.0)
65 pub static frac_1_sqrt2: float = 0.707106781186547524400844362104849039;
66
67 /// Euler's number
68 pub static e: float = 2.71828182845904523536028747135266250;
69
70 /// log2(e)
71 pub static log2_e: float = 1.44269504088896340735992468100189214;
72
73 /// log10(e)
74 pub static log10_e: float = 0.434294481903251827651128918916605082;
75
76 /// ln(2.0)
77 pub static ln_2: float = 0.693147180559945309417232121458176568;
78
79 /// ln(10.0)
80 pub static ln_10: float = 2.30258509299404568401799145468436421;
81 }
82
83 //
84 // Section: String Conversions
85 //
86
87 ///
88 /// Converts a float to a string
89 ///
90 /// # Arguments
91 ///
92 /// * num - The float value
93 ///
94 #[inline]
95 pub fn to_str(num: float) -> ~str {
96 let (r, _) = strconv::float_to_str_common(
97 num, 10u, true, strconv::SignNeg, strconv::DigAll);
98 r
99 }
100
101 ///
102 /// Converts a float to a string in hexadecimal format
103 ///
104 /// # Arguments
105 ///
106 /// * num - The float value
107 ///
108 #[inline]
109 pub fn to_str_hex(num: float) -> ~str {
110 let (r, _) = strconv::float_to_str_common(
111 num, 16u, true, strconv::SignNeg, strconv::DigAll);
112 r
113 }
114
115 ///
116 /// Converts a float to a string in a given radix, and a flag indicating
117 /// whether it's a special value
118 ///
119 /// # Arguments
120 ///
121 /// * num - The float value
122 /// * radix - The base to use
123 ///
124 #[inline]
125 pub fn to_str_radix_special(num: float, radix: uint) -> (~str, bool) {
126 strconv::float_to_str_common(num, radix, true,
127 strconv::SignNeg, strconv::DigAll)
128 }
129
130 ///
131 /// Converts a float to a string with exactly the number of
132 /// provided significant digits
133 ///
134 /// # Arguments
135 ///
136 /// * num - The float value
137 /// * digits - The number of significant digits
138 ///
139 #[inline]
140 pub fn to_str_exact(num: float, digits: uint) -> ~str {
141 let (r, _) = strconv::float_to_str_common(
142 num, 10u, true, strconv::SignNeg, strconv::DigExact(digits));
143 r
144 }
145
146 ///
147 /// Converts a float to a string with a maximum number of
148 /// significant digits
149 ///
150 /// # Arguments
151 ///
152 /// * num - The float value
153 /// * digits - The number of significant digits
154 ///
155 #[inline]
156 pub fn to_str_digits(num: float, digits: uint) -> ~str {
157 let (r, _) = strconv::float_to_str_common(
158 num, 10u, true, strconv::SignNeg, strconv::DigMax(digits));
159 r
160 }
161
162 impl to_str::ToStr for float {
163 #[inline]
164 fn to_str(&self) -> ~str { to_str_digits(*self, 8) }
165 }
166
167 impl num::ToStrRadix for float {
168 /// Converts a float to a string in a given radix
169 ///
170 /// # Arguments
171 ///
172 /// * num - The float value
173 /// * radix - The base to use
174 ///
175 /// # Failure
176 ///
177 /// Fails if called on a special value like `inf`, `-inf` or `NaN` due to
178 /// possible misinterpretation of the result at higher bases. If those values
179 /// are expected, use `to_str_radix_special()` instead.
180 #[inline]
181 fn to_str_radix(&self, radix: uint) -> ~str {
182 let (r, special) = strconv::float_to_str_common(
183 *self, radix, true, strconv::SignNeg, strconv::DigAll);
184 if special { fail!("number has a special value, \
185 try to_str_radix_special() if those are expected") }
186 r
187 }
188 }
189
190 ///
191 /// Convert a string in base 16 to a float.
192 /// Accepts a optional binary exponent.
193 ///
194 /// This function accepts strings such as
195 ///
196 /// * 'a4.fe'
197 /// * '+a4.fe', equivalent to 'a4.fe'
198 /// * '-a4.fe'
199 /// * '2b.aP128', or equivalently, '2b.ap128'
200 /// * '2b.aP-128'
201 /// * '.' (understood as 0)
202 /// * 'c.'
203 /// * '.c', or, equivalently, '0.c'
204 /// * '+inf', 'inf', '-inf', 'NaN'
205 ///
206 /// Leading and trailing whitespace represent an error.
207 ///
208 /// # Arguments
209 ///
210 /// * num - A string
211 ///
212 /// # Return value
213 ///
214 /// `none` if the string did not represent a valid number. Otherwise,
215 /// `Some(n)` where `n` is the floating-point number represented by `[num]`.
216 ///
217 #[inline]
218 pub fn from_str_hex(num: &str) -> Option<float> {
219 strconv::from_str_common(num, 16u, true, true, true,
220 strconv::ExpBin, false, false)
221 }
222
223 impl FromStr for float {
224 ///
225 /// Convert a string in base 10 to a float.
226 /// Accepts a optional decimal exponent.
227 ///
228 /// This function accepts strings such as
229 ///
230 /// * '3.14'
231 /// * '+3.14', equivalent to '3.14'
232 /// * '-3.14'
233 /// * '2.5E10', or equivalently, '2.5e10'
234 /// * '2.5E-10'
235 /// * '.' (understood as 0)
236 /// * '5.'
237 /// * '.5', or, equivalently, '0.5'
238 /// * '+inf', 'inf', '-inf', 'NaN'
239 ///
240 /// Leading and trailing whitespace represent an error.
241 ///
242 /// # Arguments
243 ///
244 /// * num - A string
245 ///
246 /// # Return value
247 ///
248 /// `none` if the string did not represent a valid number. Otherwise,
249 /// `Some(n)` where `n` is the floating-point number represented by `num`.
250 ///
251 #[inline]
252 fn from_str(val: &str) -> Option<float> {
253 strconv::from_str_common(val, 10u, true, true, true,
254 strconv::ExpDec, false, false)
255 }
256 }
257
258 impl num::FromStrRadix for float {
259 ///
260 /// Convert a string in an given base to a float.
261 ///
262 /// Due to possible conflicts, this function does **not** accept
263 /// the special values `inf`, `-inf`, `+inf` and `NaN`, **nor**
264 /// does it recognize exponents of any kind.
265 ///
266 /// Leading and trailing whitespace represent an error.
267 ///
268 /// # Arguments
269 ///
270 /// * num - A string
271 /// * radix - The base to use. Must lie in the range [2 .. 36]
272 ///
273 /// # Return value
274 ///
275 /// `none` if the string did not represent a valid number. Otherwise,
276 /// `Some(n)` where `n` is the floating-point number represented by `num`.
277 ///
278 #[inline]
279 fn from_str_radix(val: &str, radix: uint) -> Option<float> {
280 strconv::from_str_common(val, radix, true, true, false,
281 strconv::ExpNone, false, false)
282 }
283 }
284
285 //
286 // Section: Arithmetics
287 //
288
289 ///
290 /// Compute the exponentiation of an integer by another integer as a float
291 ///
292 /// # Arguments
293 ///
294 /// * x - The base
295 /// * pow - The exponent
296 ///
297 /// # Return value
298 ///
299 /// `NaN` if both `x` and `pow` are `0u`, otherwise `x^pow`
300 ///
301 pub fn pow_with_uint(base: uint, pow: uint) -> float {
302 if base == 0u {
303 if pow == 0u {
304 return NaN as float;
305 }
306 return 0.;
307 }
308 let mut my_pow = pow;
309 let mut total = 1f;
310 let mut multiplier = base as float;
311 while (my_pow > 0u) {
312 if my_pow % 2u == 1u {
313 total = total * multiplier;
314 }
315 my_pow /= 2u;
316 multiplier *= multiplier;
317 }
318 return total;
319 }
320
321 impl Num for float {}
322
323 #[cfg(not(test))]
324 impl Eq for float {
325 #[inline]
326 fn eq(&self, other: &float) -> bool { (*self) == (*other) }
327 }
328
329 #[cfg(not(test))]
330 impl ApproxEq<float> for float {
331 #[inline]
332 fn approx_epsilon() -> float { 1.0e-6 }
333
334 #[inline]
335 fn approx_eq(&self, other: &float) -> bool {
336 self.approx_eq_eps(other, &1.0e-6)
337 }
338
339 #[inline]
340 fn approx_eq_eps(&self, other: &float, approx_epsilon: &float) -> bool {
341 (*self - *other).abs() < *approx_epsilon
342 }
343 }
344
345 #[cfg(not(test))]
346 impl Ord for float {
347 #[inline]
348 fn lt(&self, other: &float) -> bool { (*self) < (*other) }
349 #[inline]
350 fn le(&self, other: &float) -> bool { (*self) <= (*other) }
351 #[inline]
352 fn ge(&self, other: &float) -> bool { (*self) >= (*other) }
353 #[inline]
354 fn gt(&self, other: &float) -> bool { (*self) > (*other) }
355 }
356
357 impl Orderable for float {
358 /// Returns `NaN` if either of the numbers are `NaN`.
359 #[inline]
360 fn min(&self, other: &float) -> float {
361 (*self as f64).min(&(*other as f64)) as float
362 }
363
364 /// Returns `NaN` if either of the numbers are `NaN`.
365 #[inline]
366 fn max(&self, other: &float) -> float {
367 (*self as f64).max(&(*other as f64)) as float
368 }
369
370 /// Returns the number constrained within the range `mn <= self <= mx`.
371 /// If any of the numbers are `NaN` then `NaN` is returned.
372 #[inline]
373 fn clamp(&self, mn: &float, mx: &float) -> float {
374 (*self as f64).clamp(&(*mn as f64), &(*mx as f64)) as float
375 }
376 }
377
378 impl Default for float {
379 #[inline]
380 fn default() -> float { 0.0 }
381 }
382
383 impl Zero for float {
384 #[inline]
385 fn zero() -> float { 0.0 }
386
387 /// Returns true if the number is equal to either `0.0` or `-0.0`
388 #[inline]
389 fn is_zero(&self) -> bool { *self == 0.0 || *self == -0.0 }
390 }
391
392 impl One for float {
393 #[inline]
394 fn one() -> float { 1.0 }
395 }
396
397 impl Round for float {
398 /// Round half-way cases toward `neg_infinity`
399 #[inline]
400 fn floor(&self) -> float { (*self as f64).floor() as float }
401
402 /// Round half-way cases toward `infinity`
403 #[inline]
404 fn ceil(&self) -> float { (*self as f64).ceil() as float }
405
406 /// Round half-way cases away from `0.0`
407 #[inline]
408 fn round(&self) -> float { (*self as f64).round() as float }
409
410 /// The integer part of the number (rounds towards `0.0`)
411 #[inline]
412 fn trunc(&self) -> float { (*self as f64).trunc() as float }
413
414 ///
415 /// The fractional part of the number, satisfying:
416 ///
417 /// ~~~ {.rust}
418 /// assert!(x == trunc(x) + fract(x))
419 /// ~~~
420 ///
421 #[inline]
422 fn fract(&self) -> float { *self - self.trunc() }
423 }
424
425 impl Fractional for float {
426 /// The reciprocal (multiplicative inverse) of the number
427 #[inline]
428 fn recip(&self) -> float { 1.0 / *self }
429 }
430
431 impl Algebraic for float {
432 #[inline]
433 fn pow(&self, n: &float) -> float {
434 (*self as f64).pow(&(*n as f64)) as float
435 }
436
437 #[inline]
438 fn sqrt(&self) -> float {
439 (*self as f64).sqrt() as float
440 }
441
442 #[inline]
443 fn rsqrt(&self) -> float {
444 (*self as f64).rsqrt() as float
445 }
446
447 #[inline]
448 fn cbrt(&self) -> float {
449 (*self as f64).cbrt() as float
450 }
451
452 #[inline]
453 fn hypot(&self, other: &float) -> float {
454 (*self as f64).hypot(&(*other as f64)) as float
455 }
456 }
457
458 impl Trigonometric for float {
459 #[inline]
460 fn sin(&self) -> float {
461 (*self as f64).sin() as float
462 }
463
464 #[inline]
465 fn cos(&self) -> float {
466 (*self as f64).cos() as float
467 }
468
469 #[inline]
470 fn tan(&self) -> float {
471 (*self as f64).tan() as float
472 }
473
474 #[inline]
475 fn asin(&self) -> float {
476 (*self as f64).asin() as float
477 }
478
479 #[inline]
480 fn acos(&self) -> float {
481 (*self as f64).acos() as float
482 }
483
484 #[inline]
485 fn atan(&self) -> float {
486 (*self as f64).atan() as float
487 }
488
489 #[inline]
490 fn atan2(&self, other: &float) -> float {
491 (*self as f64).atan2(&(*other as f64)) as float
492 }
493
494 /// Simultaneously computes the sine and cosine of the number
495 #[inline]
496 fn sin_cos(&self) -> (float, float) {
497 match (*self as f64).sin_cos() {
498 (s, c) => (s as float, c as float)
499 }
500 }
501 }
502
503 impl Exponential for float {
504 /// Returns the exponential of the number
505 #[inline]
506 fn exp(&self) -> float {
507 (*self as f64).exp() as float
508 }
509
510 /// Returns 2 raised to the power of the number
511 #[inline]
512 fn exp2(&self) -> float {
513 (*self as f64).exp2() as float
514 }
515
516 /// Returns the natural logarithm of the number
517 #[inline]
518 fn ln(&self) -> float {
519 (*self as f64).ln() as float
520 }
521
522 /// Returns the logarithm of the number with respect to an arbitrary base
523 #[inline]
524 fn log(&self, base: &float) -> float {
525 (*self as f64).log(&(*base as f64)) as float
526 }
527
528 /// Returns the base 2 logarithm of the number
529 #[inline]
530 fn log2(&self) -> float {
531 (*self as f64).log2() as float
532 }
533
534 /// Returns the base 10 logarithm of the number
535 #[inline]
536 fn log10(&self) -> float {
537 (*self as f64).log10() as float
538 }
539 }
540
541 impl Hyperbolic for float {
542 #[inline]
543 fn sinh(&self) -> float {
544 (*self as f64).sinh() as float
545 }
546
547 #[inline]
548 fn cosh(&self) -> float {
549 (*self as f64).cosh() as float
550 }
551
552 #[inline]
553 fn tanh(&self) -> float {
554 (*self as f64).tanh() as float
555 }
556
557 ///
558 /// Inverse hyperbolic sine
559 ///
560 /// # Returns
561 ///
562 /// - on success, the inverse hyperbolic sine of `self` will be returned
563 /// - `self` if `self` is `0.0`, `-0.0`, `infinity`, or `neg_infinity`
564 /// - `NaN` if `self` is `NaN`
565 ///
566 #[inline]
567 fn asinh(&self) -> float {
568 (*self as f64).asinh() as float
569 }
570
571 ///
572 /// Inverse hyperbolic cosine
573 ///
574 /// # Returns
575 ///
576 /// - on success, the inverse hyperbolic cosine of `self` will be returned
577 /// - `infinity` if `self` is `infinity`
578 /// - `NaN` if `self` is `NaN` or `self < 1.0` (including `neg_infinity`)
579 ///
580 #[inline]
581 fn acosh(&self) -> float {
582 (*self as f64).acosh() as float
583 }
584
585 ///
586 /// Inverse hyperbolic tangent
587 ///
588 /// # Returns
589 ///
590 /// - on success, the inverse hyperbolic tangent of `self` will be returned
591 /// - `self` if `self` is `0.0` or `-0.0`
592 /// - `infinity` if `self` is `1.0`
593 /// - `neg_infinity` if `self` is `-1.0`
594 /// - `NaN` if the `self` is `NaN` or outside the domain of `-1.0 <= self <= 1.0`
595 /// (including `infinity` and `neg_infinity`)
596 ///
597 #[inline]
598 fn atanh(&self) -> float {
599 (*self as f64).atanh() as float
600 }
601 }
602
603 impl Real for float {
604 /// Archimedes' constant
605 #[inline]
606 fn pi() -> float { 3.14159265358979323846264338327950288 }
607
608 /// 2.0 * pi
609 #[inline]
610 fn two_pi() -> float { 6.28318530717958647692528676655900576 }
611
612 /// pi / 2.0
613 #[inline]
614 fn frac_pi_2() -> float { 1.57079632679489661923132169163975144 }
615
616 /// pi / 3.0
617 #[inline]
618 fn frac_pi_3() -> float { 1.04719755119659774615421446109316763 }
619
620 /// pi / 4.0
621 #[inline]
622 fn frac_pi_4() -> float { 0.785398163397448309615660845819875721 }
623
624 /// pi / 6.0
625 #[inline]
626 fn frac_pi_6() -> float { 0.52359877559829887307710723054658381 }
627
628 /// pi / 8.0
629 #[inline]
630 fn frac_pi_8() -> float { 0.39269908169872415480783042290993786 }
631
632 /// 1.0 / pi
633 #[inline]
634 fn frac_1_pi() -> float { 0.318309886183790671537767526745028724 }
635
636 /// 2.0 / pi
637 #[inline]
638 fn frac_2_pi() -> float { 0.636619772367581343075535053490057448 }
639
640 /// 2 .0/ sqrt(pi)
641 #[inline]
642 fn frac_2_sqrtpi() -> float { 1.12837916709551257389615890312154517 }
643
644 /// sqrt(2.0)
645 #[inline]
646 fn sqrt2() -> float { 1.41421356237309504880168872420969808 }
647
648 /// 1.0 / sqrt(2.0)
649 #[inline]
650 fn frac_1_sqrt2() -> float { 0.707106781186547524400844362104849039 }
651
652 /// Euler's number
653 #[inline]
654 fn e() -> float { 2.71828182845904523536028747135266250 }
655
656 /// log2(e)
657 #[inline]
658 fn log2_e() -> float { 1.44269504088896340735992468100189214 }
659
660 /// log10(e)
661 #[inline]
662 fn log10_e() -> float { 0.434294481903251827651128918916605082 }
663
664 /// ln(2.0)
665 #[inline]
666 fn ln_2() -> float { 0.693147180559945309417232121458176568 }
667
668 /// ln(10.0)
669 #[inline]
670 fn ln_10() -> float { 2.30258509299404568401799145468436421 }
671
672 /// Converts to degrees, assuming the number is in radians
673 #[inline]
674 fn to_degrees(&self) -> float { (*self as f64).to_degrees() as float }
675
676 /// Converts to radians, assuming the number is in degrees
677 #[inline]
678 fn to_radians(&self) -> float { (*self as f64).to_radians() as float }
679 }
680
681 impl RealExt for float {
682 #[inline]
683 fn lgamma(&self) -> (int, float) {
684 let (sign, value) = (*self as f64).lgamma();
685 (sign, value as float)
686 }
687
688 #[inline]
689 fn tgamma(&self) -> float { (*self as f64).tgamma() as float }
690
691 #[inline]
692 fn j0(&self) -> float { (*self as f64).j0() as float }
693
694 #[inline]
695 fn j1(&self) -> float { (*self as f64).j1() as float }
696
697 #[inline]
698 fn jn(&self, n: int) -> float { (*self as f64).jn(n) as float }
699
700 #[inline]
701 fn y0(&self) -> float { (*self as f64).y0() as float }
702
703 #[inline]
704 fn y1(&self) -> float { (*self as f64).y1() as float }
705
706 #[inline]
707 fn yn(&self, n: int) -> float { (*self as f64).yn(n) as float }
708 }
709
710 #[cfg(not(test))]
711 impl Add<float,float> for float {
712 #[inline]
713 fn add(&self, other: &float) -> float { *self + *other }
714 }
715
716 #[cfg(not(test))]
717 impl Sub<float,float> for float {
718 #[inline]
719 fn sub(&self, other: &float) -> float { *self - *other }
720 }
721
722 #[cfg(not(test))]
723 impl Mul<float,float> for float {
724 #[inline]
725 fn mul(&self, other: &float) -> float { *self * *other }
726 }
727
728 #[cfg(not(test))]
729 impl Div<float,float> for float {
730 #[inline]
731 fn div(&self, other: &float) -> float { *self / *other }
732 }
733
734 #[cfg(not(test))]
735 impl Rem<float,float> for float {
736 #[inline]
737 fn rem(&self, other: &float) -> float { *self % *other }
738 }
739 #[cfg(not(test))]
740 impl Neg<float> for float {
741 #[inline]
742 fn neg(&self) -> float { -*self }
743 }
744
745 impl Signed for float {
746 /// Computes the absolute value. Returns `NaN` if the number is `NaN`.
747 #[inline]
748 fn abs(&self) -> float { (*self as f64).abs() as float }
749
750 ///
751 /// The positive difference of two numbers. Returns `0.0` if the number is less than or
752 /// equal to `other`, otherwise the difference between`self` and `other` is returned.
753 ///
754 #[inline]
755 fn abs_sub(&self, other: &float) -> float {
756 (*self as f64).abs_sub(&(*other as f64)) as float
757 }
758
759 ///
760 /// # Returns
761 ///
762 /// - `1.0` if the number is positive, `+0.0` or `infinity`
763 /// - `-1.0` if the number is negative, `-0.0` or `neg_infinity`
764 /// - `NaN` if the number is NaN
765 ///
766 #[inline]
767 fn signum(&self) -> float {
768 (*self as f64).signum() as float
769 }
770
771 /// Returns `true` if the number is positive, including `+0.0` and `infinity`
772 #[inline]
773 fn is_positive(&self) -> bool { *self > 0.0 || (1.0 / *self) == infinity }
774
775 /// Returns `true` if the number is negative, including `-0.0` and `neg_infinity`
776 #[inline]
777 fn is_negative(&self) -> bool { *self < 0.0 || (1.0 / *self) == neg_infinity }
778 }
779
780 impl Bounded for float {
781 #[inline]
782 fn min_value() -> float {
783 let x: f64 = Bounded::min_value();
784 x as float
785 }
786
787 #[inline]
788 fn max_value() -> float {
789 let x: f64 = Bounded::max_value();
790 x as float
791 }
792 }
793
794 impl Primitive for float {
795 #[inline]
796 fn bits(_: Option<float>) -> uint {
797 let bits: uint = Primitive::bits(Some(0f64));
798 bits
799 }
800
801 #[inline]
802 fn bytes(_: Option<float>) -> uint {
803 let bytes: uint = Primitive::bytes(Some(0f64));
804 bytes
805 }
806 }
807
808 impl Float for float {
809 #[inline]
810 fn nan() -> float {
811 let value: f64 = Float::nan();
812 value as float
813 }
814
815 #[inline]
816 fn infinity() -> float {
817 let value: f64 = Float::infinity();
818 value as float
819 }
820
821 #[inline]
822 fn neg_infinity() -> float {
823 let value: f64 = Float::neg_infinity();
824 value as float
825 }
826
827 #[inline]
828 fn neg_zero() -> float {
829 let value: f64 = Float::neg_zero();
830 value as float
831 }
832
833 /// Returns `true` if the number is NaN
834 #[inline]
835 fn is_nan(&self) -> bool { (*self as f64).is_nan() }
836
837 /// Returns `true` if the number is infinite
838 #[inline]
839 fn is_infinite(&self) -> bool { (*self as f64).is_infinite() }
840
841 /// Returns `true` if the number is neither infinite or NaN
842 #[inline]
843 fn is_finite(&self) -> bool { (*self as f64).is_finite() }
844
845 /// Returns `true` if the number is neither zero, infinite, subnormal or NaN
846 #[inline]
847 fn is_normal(&self) -> bool { (*self as f64).is_normal() }
848
849 /// Returns the floating point category of the number. If only one property is going to
850 /// be tested, it is generally faster to use the specific predicate instead.
851 #[inline]
852 fn classify(&self) -> FPCategory { (*self as f64).classify() }
853
854 #[inline]
855 fn mantissa_digits(_: Option<float>) -> uint {
856 Float::mantissa_digits(Some(0f64))
857 }
858
859 #[inline]
860 fn digits(_: Option<float>) -> uint {
861 Float::digits(Some(0f64))
862 }
863
864 #[inline]
865 fn epsilon() -> float {
866 let value: f64 = Float::epsilon();
867 value as float
868 }
869
870 #[inline]
871 fn min_exp(_: Option<float>) -> int {
872 Float::min_exp(Some(0f64))
873 }
874
875 #[inline]
876 fn max_exp(_: Option<float>) -> int {
877 Float::max_exp(Some(0f64))
878 }
879
880 #[inline]
881 fn min_10_exp(_: Option<float>) -> int {
882 Float::min_10_exp(Some(0f64))
883 }
884
885 #[inline]
886 fn max_10_exp(_: Option<float>) -> int {
887 Float::max_10_exp(Some(0f64))
888 }
889
890 /// Constructs a floating point number by multiplying `x` by 2 raised to the power of `exp`
891 #[inline]
892 fn ldexp(x: float, exp: int) -> float {
893 let value: f64 = Float::ldexp(x as f64, exp);
894 value as float
895 }
896
897 ///
898 /// Breaks the number into a normalized fraction and a base-2 exponent, satisfying:
899 ///
900 /// - `self = x * pow(2, exp)`
901 /// - `0.5 <= abs(x) < 1.0`
902 ///
903 #[inline]
904 fn frexp(&self) -> (float, int) {
905 match (*self as f64).frexp() {
906 (x, exp) => (x as float, exp)
907 }
908 }
909
910 ///
911 /// Returns the exponential of the number, minus `1`, in a way that is accurate
912 /// even if the number is close to zero
913 ///
914 #[inline]
915 fn exp_m1(&self) -> float {
916 (*self as f64).exp_m1() as float
917 }
918
919 ///
920 /// Returns the natural logarithm of the number plus `1` (`ln(1+n)`) more accurately
921 /// than if the operations were performed separately
922 ///
923 #[inline]
924 fn ln_1p(&self) -> float {
925 (*self as f64).ln_1p() as float
926 }
927
928 ///
929 /// Fused multiply-add. Computes `(self * a) + b` with only one rounding error. This
930 /// produces a more accurate result with better performance than a separate multiplication
931 /// operation followed by an add.
932 ///
933 #[inline]
934 fn mul_add(&self, a: float, b: float) -> float {
935 (*self as f64).mul_add(a as f64, b as f64) as float
936 }
937
938 /// Returns the next representable floating-point value in the direction of `other`
939 #[inline]
940 fn next_after(&self, other: float) -> float {
941 (*self as f64).next_after(other as f64) as float
942 }
943 }
944
945 #[cfg(test)]
946 mod tests {
947 use prelude::*;
948 use super::*;
949
950 use num::*;
951 use num;
952 use sys;
953
954 #[test]
955 fn test_num() {
956 num::test_num(10f, 2f);
957 }
958
959 #[test]
960 fn test_min() {
961 assert_eq!(1f.min(&2f), 1f);
962 assert_eq!(2f.min(&1f), 1f);
963 }
964
965 #[test]
966 fn test_max() {
967 assert_eq!(1f.max(&2f), 2f);
968 assert_eq!(2f.max(&1f), 2f);
969 }
970
971 #[test]
972 fn test_clamp() {
973 assert_eq!(1f.clamp(&2f, &4f), 2f);
974 assert_eq!(8f.clamp(&2f, &4f), 4f);
975 assert_eq!(3f.clamp(&2f, &4f), 3f);
976 let nan: float = Float::nan();
977 assert!(3f.clamp(&nan, &4f).is_nan());
978 assert!(3f.clamp(&2f, &nan).is_nan());
979 assert!(nan.clamp(&2f, &4f).is_nan());
980 }
981
982 #[test]
983 fn test_floor() {
984 assert_approx_eq!(1.0f.floor(), 1.0f);
985 assert_approx_eq!(1.3f.floor(), 1.0f);
986 assert_approx_eq!(1.5f.floor(), 1.0f);
987 assert_approx_eq!(1.7f.floor(), 1.0f);
988 assert_approx_eq!(0.0f.floor(), 0.0f);
989 assert_approx_eq!((-0.0f).floor(), -0.0f);
990 assert_approx_eq!((-1.0f).floor(), -1.0f);
991 assert_approx_eq!((-1.3f).floor(), -2.0f);
992 assert_approx_eq!((-1.5f).floor(), -2.0f);
993 assert_approx_eq!((-1.7f).floor(), -2.0f);
994 }
995
996 #[test]
997 fn test_ceil() {
998 assert_approx_eq!(1.0f.ceil(), 1.0f);
999 assert_approx_eq!(1.3f.ceil(), 2.0f);
1000 assert_approx_eq!(1.5f.ceil(), 2.0f);
1001 assert_approx_eq!(1.7f.ceil(), 2.0f);
1002 assert_approx_eq!(0.0f.ceil(), 0.0f);
1003 assert_approx_eq!((-0.0f).ceil(), -0.0f);
1004 assert_approx_eq!((-1.0f).ceil(), -1.0f);
1005 assert_approx_eq!((-1.3f).ceil(), -1.0f);
1006 assert_approx_eq!((-1.5f).ceil(), -1.0f);
1007 assert_approx_eq!((-1.7f).ceil(), -1.0f);
1008 }
1009
1010 #[test]
1011 fn test_round() {
1012 assert_approx_eq!(1.0f.round(), 1.0f);
1013 assert_approx_eq!(1.3f.round(), 1.0f);
1014 assert_approx_eq!(1.5f.round(), 2.0f);
1015 assert_approx_eq!(1.7f.round(), 2.0f);
1016 assert_approx_eq!(0.0f.round(), 0.0f);
1017 assert_approx_eq!((-0.0f).round(), -0.0f);
1018 assert_approx_eq!((-1.0f).round(), -1.0f);
1019 assert_approx_eq!((-1.3f).round(), -1.0f);
1020 assert_approx_eq!((-1.5f).round(), -2.0f);
1021 assert_approx_eq!((-1.7f).round(), -2.0f);
1022 }
1023
1024 #[test]
1025 fn test_trunc() {
1026 assert_approx_eq!(1.0f.trunc(), 1.0f);
1027 assert_approx_eq!(1.3f.trunc(), 1.0f);
1028 assert_approx_eq!(1.5f.trunc(), 1.0f);
1029 assert_approx_eq!(1.7f.trunc(), 1.0f);
1030 assert_approx_eq!(0.0f.trunc(), 0.0f);
1031 assert_approx_eq!((-0.0f).trunc(), -0.0f);
1032 assert_approx_eq!((-1.0f).trunc(), -1.0f);
1033 assert_approx_eq!((-1.3f).trunc(), -1.0f);
1034 assert_approx_eq!((-1.5f).trunc(), -1.0f);
1035 assert_approx_eq!((-1.7f).trunc(), -1.0f);
1036 }
1037
1038 #[test]
1039 fn test_fract() {
1040 assert_approx_eq!(1.0f.fract(), 0.0f);
1041 assert_approx_eq!(1.3f.fract(), 0.3f);
1042 assert_approx_eq!(1.5f.fract(), 0.5f);
1043 assert_approx_eq!(1.7f.fract(), 0.7f);
1044 assert_approx_eq!(0.0f.fract(), 0.0f);
1045 assert_approx_eq!((-0.0f).fract(), -0.0f);
1046 assert_approx_eq!((-1.0f).fract(), -0.0f);
1047 assert_approx_eq!((-1.3f).fract(), -0.3f);
1048 assert_approx_eq!((-1.5f).fract(), -0.5f);
1049 assert_approx_eq!((-1.7f).fract(), -0.7f);
1050 }
1051
1052 #[test]
1053 fn test_asinh() {
1054 assert_eq!(0.0f.asinh(), 0.0f);
1055 assert_eq!((-0.0f).asinh(), -0.0f);
1056
1057 let inf: float = Float::infinity();
1058 let neg_inf: float = Float::neg_infinity();
1059 let nan: float = Float::nan();
1060 assert_eq!(inf.asinh(), inf);
1061 assert_eq!(neg_inf.asinh(), neg_inf);
1062 assert!(nan.asinh().is_nan());
1063 assert_approx_eq!(2.0f.asinh(), 1.443635475178810342493276740273105f);
1064 assert_approx_eq!((-2.0f).asinh(), -1.443635475178810342493276740273105f);
1065 }
1066
1067 #[test]
1068 fn test_acosh() {
1069 assert_eq!(1.0f.acosh(), 0.0f);
1070 assert!(0.999f.acosh().is_nan());
1071
1072 let inf: float = Float::infinity();
1073 let neg_inf: float = Float::neg_infinity();
1074 let nan: float = Float::nan();
1075 assert_eq!(inf.acosh(), inf);
1076 assert!(neg_inf.acosh().is_nan());
1077 assert!(nan.acosh().is_nan());
1078 assert_approx_eq!(2.0f.acosh(), 1.31695789692481670862504634730796844f);
1079 assert_approx_eq!(3.0f.acosh(), 1.76274717403908605046521864995958461f);
1080 }
1081
1082 #[test]
1083 fn test_atanh() {
1084 assert_eq!(0.0f.atanh(), 0.0f);
1085 assert_eq!((-0.0f).atanh(), -0.0f);
1086
1087 let inf: float = Float::infinity();
1088 let neg_inf: float = Float::neg_infinity();
1089 let inf64: f64 = Float::infinity();
1090 let neg_inf64: f64 = Float::neg_infinity();
1091 let nan: float = Float::nan();
1092 assert_eq!(1.0f.atanh(), inf);
1093 assert_eq!((-1.0f).atanh(), neg_inf);
1094 assert!(2f64.atanh().atanh().is_nan());
1095 assert!((-2f64).atanh().atanh().is_nan());
1096 assert!(inf64.atanh().is_nan());
1097 assert!(neg_inf64.atanh().is_nan());
1098 assert!(nan.atanh().is_nan());
1099 assert_approx_eq!(0.5f.atanh(), 0.54930614433405484569762261846126285f);
1100 assert_approx_eq!((-0.5f).atanh(), -0.54930614433405484569762261846126285f);
1101 }
1102
1103 #[test]
1104 fn test_real_consts() {
1105 let pi: float = Real::pi();
1106 let two_pi: float = Real::two_pi();
1107 let frac_pi_2: float = Real::frac_pi_2();
1108 let frac_pi_3: float = Real::frac_pi_3();
1109 let frac_pi_4: float = Real::frac_pi_4();
1110 let frac_pi_6: float = Real::frac_pi_6();
1111 let frac_pi_8: float = Real::frac_pi_8();
1112 let frac_1_pi: float = Real::frac_1_pi();
1113 let frac_2_pi: float = Real::frac_2_pi();
1114 let frac_2_sqrtpi: float = Real::frac_2_sqrtpi();
1115 let sqrt2: float = Real::sqrt2();
1116 let frac_1_sqrt2: float = Real::frac_1_sqrt2();
1117 let e: float = Real::e();
1118 let log2_e: float = Real::log2_e();
1119 let log10_e: float = Real::log10_e();
1120 let ln_2: float = Real::ln_2();
1121 let ln_10: float = Real::ln_10();
1122
1123 assert_approx_eq!(two_pi, 2f * pi);
1124 assert_approx_eq!(frac_pi_2, pi / 2f);
1125 assert_approx_eq!(frac_pi_3, pi / 3f);
1126 assert_approx_eq!(frac_pi_4, pi / 4f);
1127 assert_approx_eq!(frac_pi_6, pi / 6f);
1128 assert_approx_eq!(frac_pi_8, pi / 8f);
1129 assert_approx_eq!(frac_1_pi, 1f / pi);
1130 assert_approx_eq!(frac_2_pi, 2f / pi);
1131 assert_approx_eq!(frac_2_sqrtpi, 2f / pi.sqrt());
1132 assert_approx_eq!(sqrt2, 2f.sqrt());
1133 assert_approx_eq!(frac_1_sqrt2, 1f / 2f.sqrt());
1134 assert_approx_eq!(log2_e, e.log2());
1135 assert_approx_eq!(log10_e, e.log10());
1136 assert_approx_eq!(ln_2, 2f.ln());
1137 assert_approx_eq!(ln_10, 10f.ln());
1138 }
1139
1140 #[test]
1141 fn test_abs() {
1142 assert_eq!(infinity.abs(), infinity);
1143 assert_eq!(1f.abs(), 1f);
1144 assert_eq!(0f.abs(), 0f);
1145 assert_eq!((-0f).abs(), 0f);
1146 assert_eq!((-1f).abs(), 1f);
1147 assert_eq!(neg_infinity.abs(), infinity);
1148 assert_eq!((1f/neg_infinity).abs(), 0f);
1149 assert!(NaN.abs().is_nan());
1150 }
1151
1152 #[test]
1153 fn test_abs_sub() {
1154 assert_eq!((-1f).abs_sub(&1f), 0f);
1155 assert_eq!(1f.abs_sub(&1f), 0f);
1156 assert_eq!(1f.abs_sub(&0f), 1f);
1157 assert_eq!(1f.abs_sub(&-1f), 2f);
1158 assert_eq!(neg_infinity.abs_sub(&0f), 0f);
1159 assert_eq!(infinity.abs_sub(&1f), infinity);
1160 assert_eq!(0f.abs_sub(&neg_infinity), infinity);
1161 assert_eq!(0f.abs_sub(&infinity), 0f);
1162 }
1163
1164 #[test] #[ignore(cfg(windows))] // FIXME #8663
1165 fn test_abs_sub_nowin() {
1166 assert!(NaN.abs_sub(&-1f).is_nan());
1167 assert!(1f.abs_sub(&NaN).is_nan());
1168 }
1169
1170 #[test]
1171 fn test_signum() {
1172 assert_eq!(infinity.signum(), 1f);
1173 assert_eq!(1f.signum(), 1f);
1174 assert_eq!(0f.signum(), 1f);
1175 assert_eq!((-0f).signum(), -1f);
1176 assert_eq!((-1f).signum(), -1f);
1177 assert_eq!(neg_infinity.signum(), -1f);
1178 assert_eq!((1f/neg_infinity).signum(), -1f);
1179 assert!(NaN.signum().is_nan());
1180 }
1181
1182 #[test]
1183 fn test_is_positive() {
1184 assert!(infinity.is_positive());
1185 assert!(1f.is_positive());
1186 assert!(0f.is_positive());
1187 assert!(!(-0f).is_positive());
1188 assert!(!(-1f).is_positive());
1189 assert!(!neg_infinity.is_positive());
1190 assert!(!(1f/neg_infinity).is_positive());
1191 assert!(!NaN.is_positive());
1192 }
1193
1194 #[test]
1195 fn test_is_negative() {
1196 assert!(!infinity.is_negative());
1197 assert!(!1f.is_negative());
1198 assert!(!0f.is_negative());
1199 assert!((-0f).is_negative());
1200 assert!((-1f).is_negative());
1201 assert!(neg_infinity.is_negative());
1202 assert!((1f/neg_infinity).is_negative());
1203 assert!(!NaN.is_negative());
1204 }
1205
1206 #[test]
1207 fn test_approx_eq() {
1208 assert!(1.0f.approx_eq(&1f));
1209 assert!(0.9999999f.approx_eq(&1f));
1210 assert!(1.000001f.approx_eq_eps(&1f, &1.0e-5));
1211 assert!(1.0000001f.approx_eq_eps(&1f, &1.0e-6));
1212 assert!(!1.0000001f.approx_eq_eps(&1f, &1.0e-7));
1213 }
1214
1215 #[test]
1216 fn test_primitive() {
1217 let none: Option<float> = None;
1218 assert_eq!(Primitive::bits(none), sys::size_of::<float>() * 8);
1219 assert_eq!(Primitive::bytes(none), sys::size_of::<float>());
1220 }
1221
1222 #[test]
1223 fn test_is_normal() {
1224 let nan: float = Float::nan();
1225 let inf: float = Float::infinity();
1226 let neg_inf: float = Float::neg_infinity();
1227 let zero: float = Zero::zero();
1228 let neg_zero: float = Float::neg_zero();
1229 assert!(!nan.is_normal());
1230 assert!(!inf.is_normal());
1231 assert!(!neg_inf.is_normal());
1232 assert!(!zero.is_normal());
1233 assert!(!neg_zero.is_normal());
1234 assert!(1f.is_normal());
1235 assert!(1e-307f.is_normal());
1236 assert!(!1e-308f.is_normal());
1237 }
1238
1239 #[test]
1240 fn test_classify() {
1241 let nan: float = Float::nan();
1242 let inf: float = Float::infinity();
1243 let neg_inf: float = Float::neg_infinity();
1244 let zero: float = Zero::zero();
1245 let neg_zero: float = Float::neg_zero();
1246 assert_eq!(nan.classify(), FPNaN);
1247 assert_eq!(inf.classify(), FPInfinite);
1248 assert_eq!(neg_inf.classify(), FPInfinite);
1249 assert_eq!(zero.classify(), FPZero);
1250 assert_eq!(neg_zero.classify(), FPZero);
1251 assert_eq!(1f.classify(), FPNormal);
1252 assert_eq!(1e-307f.classify(), FPNormal);
1253 assert_eq!(1e-308f.classify(), FPSubnormal);
1254 }
1255
1256 #[test]
1257 fn test_ldexp() {
1258 // We have to use from_str until base-2 exponents
1259 // are supported in floating-point literals
1260 let f1: float = from_str_hex("1p-123").unwrap();
1261 let f2: float = from_str_hex("1p-111").unwrap();
1262 assert_eq!(Float::ldexp(1f, -123), f1);
1263 assert_eq!(Float::ldexp(1f, -111), f2);
1264
1265 assert_eq!(Float::ldexp(0f, -123), 0f);
1266 assert_eq!(Float::ldexp(-0f, -123), -0f);
1267
1268 let inf: float = Float::infinity();
1269 let neg_inf: float = Float::neg_infinity();
1270 let nan: float = Float::nan();
1271 assert_eq!(Float::ldexp(inf, -123), inf);
1272 assert_eq!(Float::ldexp(neg_inf, -123), neg_inf);
1273 assert!(Float::ldexp(nan, -123).is_nan());
1274 }
1275
1276 #[test]
1277 fn test_frexp() {
1278 // We have to use from_str until base-2 exponents
1279 // are supported in floating-point literals
1280 let f1: float = from_str_hex("1p-123").unwrap();
1281 let f2: float = from_str_hex("1p-111").unwrap();
1282 let (x1, exp1) = f1.frexp();
1283 let (x2, exp2) = f2.frexp();
1284 assert_eq!((x1, exp1), (0.5f, -122));
1285 assert_eq!((x2, exp2), (0.5f, -110));
1286 assert_eq!(Float::ldexp(x1, exp1), f1);
1287 assert_eq!(Float::ldexp(x2, exp2), f2);
1288
1289 assert_eq!(0f.frexp(), (0f, 0));
1290 assert_eq!((-0f).frexp(), (-0f, 0));
1291 }
1292
1293 #[test] #[ignore(cfg(windows))] // FIXME #8755
1294 fn test_frexp_nowin() {
1295 let inf: float = Float::infinity();
1296 let neg_inf: float = Float::neg_infinity();
1297 let nan: float = Float::nan();
1298 assert_eq!(match inf.frexp() { (x, _) => x }, inf);
1299 assert_eq!(match neg_inf.frexp() { (x, _) => x }, neg_inf);
1300 assert!(match nan.frexp() { (x, _) => x.is_nan() })
1301 }
1302
1303 #[test]
1304 pub fn test_to_str_exact_do_decimal() {
1305 let s = to_str_exact(5.0, 4u);
1306 assert_eq!(s, ~"5.0000");
1307 }
1308
1309 #[test]
1310 pub fn test_from_str() {
1311 assert_eq!(from_str::<float>("3"), Some(3.));
1312 assert_eq!(from_str::<float>("3.14"), Some(3.14));
1313 assert_eq!(from_str::<float>("+3.14"), Some(3.14));
1314 assert_eq!(from_str::<float>("-3.14"), Some(-3.14));
1315 assert_eq!(from_str::<float>("2.5E10"), Some(25000000000.));
1316 assert_eq!(from_str::<float>("2.5e10"), Some(25000000000.));
1317 assert_eq!(from_str::<float>("25000000000.E-10"), Some(2.5));
1318 assert_eq!(from_str::<float>("."), Some(0.));
1319 assert_eq!(from_str::<float>(".e1"), Some(0.));
1320 assert_eq!(from_str::<float>(".e-1"), Some(0.));
1321 assert_eq!(from_str::<float>("5."), Some(5.));
1322 assert_eq!(from_str::<float>(".5"), Some(0.5));
1323 assert_eq!(from_str::<float>("0.5"), Some(0.5));
1324 assert_eq!(from_str::<float>("-.5"), Some(-0.5));
1325 assert_eq!(from_str::<float>("-5"), Some(-5.));
1326 assert_eq!(from_str::<float>("inf"), Some(infinity));
1327 assert_eq!(from_str::<float>("+inf"), Some(infinity));
1328 assert_eq!(from_str::<float>("-inf"), Some(neg_infinity));
1329 // note: NaN != NaN, hence this slightly complex test
1330 match from_str::<float>("NaN") {
1331 Some(f) => assert!(f.is_nan()),
1332 None => fail!()
1333 }
1334 // note: -0 == 0, hence these slightly more complex tests
1335 match from_str::<float>("-0") {
1336 Some(v) if v.is_zero() => assert!(v.is_negative()),
1337 _ => fail!()
1338 }
1339 match from_str::<float>("0") {
1340 Some(v) if v.is_zero() => assert!(v.is_positive()),
1341 _ => fail!()
1342 }
1343
1344 assert!(from_str::<float>("").is_none());
1345 assert!(from_str::<float>("x").is_none());
1346 assert!(from_str::<float>(" ").is_none());
1347 assert!(from_str::<float>(" ").is_none());
1348 assert!(from_str::<float>("e").is_none());
1349 assert!(from_str::<float>("E").is_none());
1350 assert!(from_str::<float>("E1").is_none());
1351 assert!(from_str::<float>("1e1e1").is_none());
1352 assert!(from_str::<float>("1e1.1").is_none());
1353 assert!(from_str::<float>("1e1-1").is_none());
1354 }
1355
1356 #[test]
1357 pub fn test_from_str_hex() {
1358 assert_eq!(from_str_hex("a4"), Some(164.));
1359 assert_eq!(from_str_hex("a4.fe"), Some(164.9921875));
1360 assert_eq!(from_str_hex("-a4.fe"), Some(-164.9921875));
1361 assert_eq!(from_str_hex("+a4.fe"), Some(164.9921875));
1362 assert_eq!(from_str_hex("ff0P4"), Some(0xff00 as float));
1363 assert_eq!(from_str_hex("ff0p4"), Some(0xff00 as float));
1364 assert_eq!(from_str_hex("ff0p-4"), Some(0xff as float));
1365 assert_eq!(from_str_hex("."), Some(0.));
1366 assert_eq!(from_str_hex(".p1"), Some(0.));
1367 assert_eq!(from_str_hex(".p-1"), Some(0.));
1368 assert_eq!(from_str_hex("f."), Some(15.));
1369 assert_eq!(from_str_hex(".f"), Some(0.9375));
1370 assert_eq!(from_str_hex("0.f"), Some(0.9375));
1371 assert_eq!(from_str_hex("-.f"), Some(-0.9375));
1372 assert_eq!(from_str_hex("-f"), Some(-15.));
1373 assert_eq!(from_str_hex("inf"), Some(infinity));
1374 assert_eq!(from_str_hex("+inf"), Some(infinity));
1375 assert_eq!(from_str_hex("-inf"), Some(neg_infinity));
1376 // note: NaN != NaN, hence this slightly complex test
1377 match from_str_hex("NaN") {
1378 Some(f) => assert!(f.is_nan()),
1379 None => fail!()
1380 }
1381 // note: -0 == 0, hence these slightly more complex tests
1382 match from_str_hex("-0") {
1383 Some(v) if v.is_zero() => assert!(v.is_negative()),
1384 _ => fail!()
1385 }
1386 match from_str_hex("0") {
1387 Some(v) if v.is_zero() => assert!(v.is_positive()),
1388 _ => fail!()
1389 }
1390 assert_eq!(from_str_hex("e"), Some(14.));
1391 assert_eq!(from_str_hex("E"), Some(14.));
1392 assert_eq!(from_str_hex("E1"), Some(225.));
1393 assert_eq!(from_str_hex("1e1e1"), Some(123361.));
1394 assert_eq!(from_str_hex("1e1.1"), Some(481.0625));
1395
1396 assert!(from_str_hex("").is_none());
1397 assert!(from_str_hex("x").is_none());
1398 assert!(from_str_hex(" ").is_none());
1399 assert!(from_str_hex(" ").is_none());
1400 assert!(from_str_hex("p").is_none());
1401 assert!(from_str_hex("P").is_none());
1402 assert!(from_str_hex("P1").is_none());
1403 assert!(from_str_hex("1p1p1").is_none());
1404 assert!(from_str_hex("1p1.1").is_none());
1405 assert!(from_str_hex("1p1-1").is_none());
1406 }
1407
1408 #[test]
1409 pub fn test_to_str_hex() {
1410 assert_eq!(to_str_hex(164.), ~"a4");
1411 assert_eq!(to_str_hex(164.9921875), ~"a4.fe");
1412 assert_eq!(to_str_hex(-164.9921875), ~"-a4.fe");
1413 assert_eq!(to_str_hex(0xff00 as float), ~"ff00");
1414 assert_eq!(to_str_hex(-(0xff00 as float)), ~"-ff00");
1415 assert_eq!(to_str_hex(0.), ~"0");
1416 assert_eq!(to_str_hex(15.), ~"f");
1417 assert_eq!(to_str_hex(-15.), ~"-f");
1418 assert_eq!(to_str_hex(0.9375), ~"0.f");
1419 assert_eq!(to_str_hex(-0.9375), ~"-0.f");
1420 assert_eq!(to_str_hex(infinity), ~"inf");
1421 assert_eq!(to_str_hex(neg_infinity), ~"-inf");
1422 assert_eq!(to_str_hex(NaN), ~"NaN");
1423 assert_eq!(to_str_hex(0.), ~"0");
1424 assert_eq!(to_str_hex(-0.), ~"-0");
1425 }
1426
1427 #[test]
1428 pub fn test_to_str_radix() {
1429 assert_eq!(36.0f.to_str_radix(36u), ~"10");
1430 assert_eq!(8.125f.to_str_radix(2u), ~"1000.001");
1431 }
1432
1433 #[test]
1434 pub fn test_from_str_radix() {
1435 assert_eq!(from_str_radix("10", 36u), Some(36.));
1436 assert_eq!(from_str_radix("1000.001", 2u), Some(8.125));
1437 }
1438
1439 #[test]
1440 pub fn test_to_str_inf() {
1441 assert_eq!(to_str_digits(infinity, 10u), ~"inf");
1442 assert_eq!(to_str_digits(-infinity, 10u), ~"-inf");
1443 }
1444 }