1 // Copyright 2015 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.
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.
11 #![allow(overflowing_literals)]
13 use std::{i64, f32, f64};
15 use core::num::dec2flt::{to_f32, to_f64};
20 // Take an float literal, turn it into a string in various ways (that are all trusted
21 // to be correct) and see if those strings are parsed back to the value of the literal.
22 // Requires a *polymorphic literal*, i.e. one that can serve as f64 as well as f32.
23 macro_rules! test_literal {
27 let inputs = &[stringify!($x).into(), format!("{:?}", x64), format!("{:e}", x64)];
30 assert_eq!(to_f64(input), Ok(x64));
31 assert_eq!(to_f32(input), Ok(x32));
32 let neg_input = &format!("-{}", input);
33 assert_eq!(to_f64(neg_input), Ok(-x64));
34 assert_eq!(to_f32(neg_input), Ok(-x32));
45 test_literal!(12345.);
46 test_literal!(0.9999999);
47 test_literal!(2.2250738585072014e-308);
51 fn special_code_paths() {
52 test_literal!(36893488147419103229.0); // 2^65 - 3, triggers half-to-even with even significand
53 test_literal!(101e-33); // Triggers the tricky underflow case in AlgorithmM (for f32)
54 test_literal!(1e23); // Triggers AlgorithmR
55 test_literal!(2075e23); // Triggers another path through AlgorithmR
56 test_literal!(8713e-23); // ... and yet another.
62 test_literal!(123456789.34567e250);
63 test_literal!(943794359898089732078308743689303290943794359843568973207830874368930329.);
68 test_literal!(5e-324);
69 test_literal!(91e-324);
70 test_literal!(1e-322);
71 test_literal!(13245643e-320);
72 test_literal!(2.22507385851e-308);
73 test_literal!(2.1e-308);
74 test_literal!(4.9406564584124654e-324);
82 test_literal!(1.7976931348624e308);
88 test_literal!(1e-325);
89 test_literal!(1e-326);
90 test_literal!(1e-500);
94 fn fast_path_correct() {
95 // This number triggers the fast path and is handled incorrectly when compiling on
96 // x86 without SSE2 (i.e., using the x87 FPU stack).
97 test_literal!(1.448997445238699);
102 assert_eq!(to_f64("."), Ok(0.0));
107 assert!(to_f64("NaN").unwrap().is_nan());
108 assert!(to_f32("NaN").unwrap().is_nan());
113 assert_eq!(to_f64("inf"), Ok(f64::INFINITY));
114 assert_eq!(to_f64("-inf"), Ok(f64::NEG_INFINITY));
115 assert_eq!(to_f32("inf"), Ok(f32::INFINITY));
116 assert_eq!(to_f32("-inf"), Ok(f32::NEG_INFINITY));
120 fn massive_exponent() {
122 assert_eq!(to_f64(&format!("1e{}000", max)), Ok(f64::INFINITY));
123 assert_eq!(to_f64(&format!("1e-{}000", max)), Ok(0.0));
124 assert_eq!(to_f64(&format!("1e{}000", max)), Ok(f64::INFINITY));
128 fn bench_0(b: &mut test::Bencher) {
129 b.iter(|| to_f64("0.0"));
133 fn bench_42(b: &mut test::Bencher) {
134 b.iter(|| to_f64("42"));
138 fn bench_huge_int(b: &mut test::Bencher) {
140 b.iter(|| to_f64("170141183460469231731687303715884105727"));
144 fn bench_short_decimal(b: &mut test::Bencher) {
145 b.iter(|| to_f64("1234.5678"));
149 fn bench_pi_long(b: &mut test::Bencher) {
150 b.iter(|| to_f64("3.14159265358979323846264338327950288"));
154 fn bench_pi_short(b: &mut test::Bencher) {
155 b.iter(|| to_f64("3.141592653589793"))
159 fn bench_1e150(b: &mut test::Bencher) {
160 b.iter(|| to_f64("1e150"));
164 fn bench_long_decimal_and_exp(b: &mut test::Bencher) {
165 b.iter(|| to_f64("727501488517303786137132964064381141071e-123"));
169 fn bench_min_subnormal(b: &mut test::Bencher) {
170 b.iter(|| to_f64("5e-324"));
174 fn bench_min_normal(b: &mut test::Bencher) {
175 b.iter(|| to_f64("2.2250738585072014e-308"));
179 fn bench_max(b: &mut test::Bencher) {
180 b.iter(|| to_f64("1.7976931348623157e308"));