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.
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 use {ieee, Category, ExpInt, Float, Round, ParseError, StatusAnd};
13 use std::cmp::Ordering;
18 #[derive(Copy, Clone, PartialEq, PartialOrd, Debug)]
19 pub struct DoubleFloat<F>(F, F);
20 pub type DoubleDouble = DoubleFloat<ieee::Double>;
22 // These are legacy semantics for the Fallback, inaccrurate implementation of
23 // IBM double-double, if the accurate DoubleDouble doesn't handle the
24 // operation. It's equivalent to having an IEEE number with consecutive 106
25 // bits of mantissa and 11 bits of exponent.
27 // It's not equivalent to IBM double-double. For example, a legit IBM
28 // double-double, 1 + epsilon:
30 // 1 + epsilon = 1 + (1 >> 1076)
32 // is not representable by a consecutive 106 bits of mantissa.
34 // Currently, these semantics are used in the following way:
36 // DoubleDouble -> (Double, Double) ->
37 // DoubleDouble's Fallback -> IEEE operations
39 // FIXME: Implement all operations in DoubleDouble, and delete these
41 // FIXME(eddyb) This shouldn't need to be `pub`, it's only used in bounds.
42 pub struct FallbackS<F>(F);
43 type Fallback<F> = ieee::IeeeFloat<FallbackS<F>>;
44 impl<F: Float> ieee::Semantics for FallbackS<F> {
45 // Forbid any conversion to/from bits.
46 const BITS: usize = 0;
47 const PRECISION: usize = F::PRECISION * 2;
48 const MAX_EXP: ExpInt = F::MAX_EXP as ExpInt;
49 const MIN_EXP: ExpInt = F::MIN_EXP as ExpInt + F::PRECISION as ExpInt;
52 float_common_impls!(DoubleFloat<F>);
54 impl<F: Float> Neg for DoubleFloat<F> {
56 fn neg(self) -> Self {
57 panic!("NYI Neg::neg");
62 impl<F: Float> fmt::Display for DoubleFloat<F> {
63 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
64 panic!("NYI Display::fmt");
69 impl<F: Float> Float for DoubleFloat<F> {
70 const BITS: usize = F::BITS * 2;
71 const PRECISION: usize = Fallback::<F>::PRECISION;
72 const MAX_EXP: ExpInt = Fallback::<F>::MAX_EXP;
73 const MIN_EXP: ExpInt = Fallback::<F>::MIN_EXP;
75 const ZERO: Self = DoubleFloat(F::ZERO, F::ZERO);
77 const INFINITY: Self = DoubleFloat(F::INFINITY, F::ZERO);
79 // FIXME(eddyb) remove when qnan becomes const fn.
80 const NAN: Self = DoubleFloat(F::NAN, F::ZERO);
82 fn qnan(payload: Option<u128>) -> Self {
86 fn snan(payload: Option<u128>) -> Self {
90 fn largest() -> Self {
94 const SMALLEST: Self = DoubleFloat(F::SMALLEST, F::ZERO);
96 fn smallest_normalized() -> Self {
97 panic!("NYI smallest_normalized")
100 fn add_r(self, rhs: Self, round: Round) -> StatusAnd<Self> {
104 fn mul_r(self, rhs: Self, round: Round) -> StatusAnd<Self> {
108 fn mul_add_r(self, multiplicand: Self, addend: Self, round: Round) -> StatusAnd<Self> {
109 panic!("NYI mul_add_r")
112 fn div_r(self, rhs: Self, round: Round) -> StatusAnd<Self> {
116 fn c_fmod(self, rhs: Self) -> StatusAnd<Self> {
120 fn round_to_integral(self, round: Round) -> StatusAnd<Self> {
121 panic!("NYI round_to_integral")
124 fn next_up(self) -> StatusAnd<Self> {
125 panic!("NYI next_up")
128 fn from_bits(input: u128) -> Self {
129 panic!("NYI from_bits")
132 fn from_u128_r(input: u128, round: Round) -> StatusAnd<Self> {
133 panic!("NYI from_u128_r")
136 fn from_str_r(s: &str, round: Round) -> Result<StatusAnd<Self>, ParseError> {
137 panic!("NYI from_str_r")
140 fn to_bits(self) -> u128 {
141 panic!("NYI to_bits")
144 fn to_u128_r(self, width: usize, round: Round, is_exact: &mut bool) -> StatusAnd<u128> {
145 panic!("NYI to_u128_r");
148 fn cmp_abs_normal(self, rhs: Self) -> Ordering {
149 panic!("NYI cmp_abs_normal")
152 fn bitwise_eq(self, rhs: Self) -> bool {
153 panic!("NYI bitwise_eq")
156 fn is_negative(self) -> bool {
157 panic!("NYI is_negative")
160 fn is_denormal(self) -> bool {
161 panic!("NYI is_denormal")
164 fn is_signaling(self) -> bool {
165 panic!("NYI is_signaling")
168 fn category(self) -> Category {
169 panic!("NYI category")
172 fn get_exact_inverse(self) -> Option<Self> {
173 panic!("NYI get_exact_inverse")
176 fn ilogb(self) -> ExpInt {
180 fn scalbn_r(self, exp: ExpInt, round: Round) -> Self {
184 fn frexp_r(self, exp: &mut ExpInt, round: Round) -> Self {