|
| 1 | +// Copyright 2017 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 | +// ignore-emscripten u128 not supported |
| 12 | + |
| 13 | +#![feature(test, i128, i128_type)] |
| 14 | +#![deny(overflowing_literals)] |
| 15 | +extern crate test; |
| 16 | + |
| 17 | +use std::f32; |
| 18 | +use std::u128; |
| 19 | +use test::black_box; |
| 20 | + |
| 21 | +macro_rules! test { |
| 22 | + ($val:expr, $src_ty:ident -> $dest_ty:ident, $expected:expr) => ({ |
| 23 | + { |
| 24 | + const X: $src_ty = $val; |
| 25 | + const Y: $dest_ty = X as $dest_ty; |
| 26 | + assert_eq!(Y, $expected, |
| 27 | + "const eval {} -> {}", stringify!($src_ty), stringify!($dest_ty)); |
| 28 | + } |
| 29 | + // black_box disables constant evaluation to test run-time conversions: |
| 30 | + assert_eq!(black_box::<$src_ty>($val) as $dest_ty, $expected, |
| 31 | + "run-time {} -> {}", stringify!($src_ty), stringify!($dest_ty)); |
| 32 | + }); |
| 33 | +} |
| 34 | + |
| 35 | +pub fn main() { |
| 36 | + // nextDown(f32::MAX) = 2^128 - 2 * 2^104 |
| 37 | + const SECOND_LARGEST_F32: f32 = 340282326356119256160033759537265639424.; |
| 38 | + |
| 39 | + // f32::MAX - 0.5 ULP and smaller should be rounded down |
| 40 | + test!(0xfffffe00000000000000000000000000, u128 -> f32, SECOND_LARGEST_F32); |
| 41 | + test!(0xfffffe7fffffffffffffffffffffffff, u128 -> f32, SECOND_LARGEST_F32); |
| 42 | + test!(0xfffffe80000000000000000000000000, u128 -> f32, SECOND_LARGEST_F32); |
| 43 | + // numbers within < 0.5 ULP of f32::MAX it should be rounded to f32::MAX |
| 44 | + test!(0xfffffe80000000000000000000000001, u128 -> f32, f32::MAX); |
| 45 | + test!(0xfffffeffffffffffffffffffffffffff, u128 -> f32, f32::MAX); |
| 46 | + test!(0xffffff00000000000000000000000000, u128 -> f32, f32::MAX); |
| 47 | + test!(0xffffff00000000000000000000000001, u128 -> f32, f32::MAX); |
| 48 | + test!(0xffffff7fffffffffffffffffffffffff, u128 -> f32, f32::MAX); |
| 49 | + // f32::MAX + 0.5 ULP and greater should be rounded to infinity |
| 50 | + test!(0xffffff80000000000000000000000000, u128 -> f32, f32::INFINITY); |
| 51 | + test!(0xffffff80000000f00000000000000000, u128 -> f32, f32::INFINITY); |
| 52 | + test!(0xffffff87ffffffffffffffff00000001, u128 -> f32, f32::INFINITY); |
| 53 | + |
| 54 | + // u128->f64 should not be affected by the u128->f32 checks |
| 55 | + test!(0xffffff80000000000000000000000000, u128 -> f64, |
| 56 | + 340282356779733661637539395458142568448.0); |
| 57 | + test!(u128::MAX, u128 -> f64, 340282366920938463463374607431768211455.0); |
| 58 | +} |
0 commit comments