Skip to content

Commit b7f49ca

Browse files
committed
Auto merge of #28539 - rkruppe:shuffle-num-internals, r=alexcrichton
Move private bignum module to core::num, because it is not only used in flt2dec. Extract private 80-bit soft-float into new core::num module for the same reason.
2 parents 79d259e + cd67ec3 commit b7f49ca

File tree

16 files changed

+106
-79
lines changed

16 files changed

+106
-79
lines changed

src/libcore/num/flt2dec/bignum.rs renamed to src/libcore/num/bignum.rs

+13-7
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,12 @@
1919
//! inputs, but we don't do so to avoid the code bloat. Each bignum is still
2020
//! tracked for the actual usages, so it normally doesn't matter.
2121
22+
// This module is only for dec2flt and flt2dec, and only public because of libcoretest.
23+
// It is not intended to ever be stabilized.
24+
#![doc(hidden)]
25+
#![unstable(feature = "core_private_bignum",
26+
reason = "internal routines only exposed for testing",
27+
issue = "0")]
2228
#![macro_use]
2329

2430
use prelude::v1::*;
@@ -194,7 +200,7 @@ macro_rules! define_bignum {
194200
/// Adds `other` to itself and returns its own mutable reference.
195201
pub fn add<'a>(&'a mut self, other: &$name) -> &'a mut $name {
196202
use cmp;
197-
use num::flt2dec::bignum::FullOps;
203+
use num::bignum::FullOps;
198204

199205
let mut sz = cmp::max(self.size, other.size);
200206
let mut carry = false;
@@ -212,7 +218,7 @@ macro_rules! define_bignum {
212218
}
213219

214220
pub fn add_small(&mut self, other: $ty) -> &mut $name {
215-
use num::flt2dec::bignum::FullOps;
221+
use num::bignum::FullOps;
216222

217223
let (mut carry, v) = self.base[0].full_add(other, false);
218224
self.base[0] = v;
@@ -232,7 +238,7 @@ macro_rules! define_bignum {
232238
/// Subtracts `other` from itself and returns its own mutable reference.
233239
pub fn sub<'a>(&'a mut self, other: &$name) -> &'a mut $name {
234240
use cmp;
235-
use num::flt2dec::bignum::FullOps;
241+
use num::bignum::FullOps;
236242

237243
let sz = cmp::max(self.size, other.size);
238244
let mut noborrow = true;
@@ -249,7 +255,7 @@ macro_rules! define_bignum {
249255
/// Multiplies itself by a digit-sized `other` and returns its own
250256
/// mutable reference.
251257
pub fn mul_small(&mut self, other: $ty) -> &mut $name {
252-
use num::flt2dec::bignum::FullOps;
258+
use num::bignum::FullOps;
253259

254260
let mut sz = self.size;
255261
let mut carry = 0;
@@ -310,7 +316,7 @@ macro_rules! define_bignum {
310316
/// Multiplies itself by `5^e` and returns its own mutable reference.
311317
pub fn mul_pow5(&mut self, mut e: usize) -> &mut $name {
312318
use mem;
313-
use num::flt2dec::bignum::SMALL_POW5;
319+
use num::bignum::SMALL_POW5;
314320

315321
// There are exactly n trailing zeros on 2^n, and the only relevant digit sizes
316322
// are consecutive powers of two, so this is well suited index for the table.
@@ -341,7 +347,7 @@ macro_rules! define_bignum {
341347
pub fn mul_digits<'a>(&'a mut self, other: &[$ty]) -> &'a mut $name {
342348
// the internal routine. works best when aa.len() <= bb.len().
343349
fn mul_inner(ret: &mut [$ty; $n], aa: &[$ty], bb: &[$ty]) -> usize {
344-
use num::flt2dec::bignum::FullOps;
350+
use num::bignum::FullOps;
345351

346352
let mut retsz = 0;
347353
for (i, &a) in aa.iter().enumerate() {
@@ -378,7 +384,7 @@ macro_rules! define_bignum {
378384
/// Divides itself by a digit-sized `other` and returns its own
379385
/// mutable reference *and* the remainder.
380386
pub fn div_rem_small(&mut self, other: $ty) -> (&mut $name, $ty) {
381-
use num::flt2dec::bignum::FullOps;
387+
use num::bignum::FullOps;
382388

383389
assert!(other > 0);
384390

src/libcore/num/dec2flt/algorithm.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,13 @@
1010

1111
//! The various algorithms from the paper.
1212
13-
use num::flt2dec::strategy::grisu::Fp;
1413
use prelude::v1::*;
1514
use cmp::min;
1615
use cmp::Ordering::{Less, Equal, Greater};
17-
use super::table;
18-
use super::rawfp::{self, Unpacked, RawFloat, fp_to_float, next_float, prev_float};
19-
use super::num::{self, Big};
16+
use num::diy_float::Fp;
17+
use num::dec2flt::table;
18+
use num::dec2flt::rawfp::{self, Unpacked, RawFloat, fp_to_float, next_float, prev_float};
19+
use num::dec2flt::num::{self, Big};
2020

2121
/// Number of significand bits in Fp
2222
const P: u32 = 64;

src/libcore/num/dec2flt/mod.rs

-3
Original file line numberDiff line numberDiff line change
@@ -86,9 +86,6 @@
8686
//! "such that the exponent +/- the number of decimal digits fits into a 64 bit integer".
8787
//! Larger exponents are accepted, but we don't do arithmetic with them, they are immediately
8888
//! turned into {positive,negative} {zero,infinity}.
89-
//!
90-
//! FIXME: this uses several things from core::num::flt2dec, which is nonsense. Those things
91-
//! should be moved into core::num::<something else>.
9289
9390
#![doc(hidden)]
9491
#![unstable(feature = "dec2flt",

src/libcore/num/dec2flt/num.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,8 @@
1414

1515
use prelude::v1::*;
1616
use cmp::Ordering::{self, Less, Equal, Greater};
17-
use num::flt2dec::bignum::Big32x40;
1817

19-
pub type Big = Big32x40;
18+
pub use num::bignum::Big32x40 as Big;
2019

2120
/// Test whether truncating all bits less significant than `ones_place` introduces
2221
/// a relative error less, equal, or greater than 0.5 ULP.

src/libcore/num/dec2flt/rawfp.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,10 @@ use cmp::Ordering::{Less, Equal, Greater};
3333
use ops::{Mul, Div, Neg};
3434
use fmt::{Debug, LowerExp};
3535
use mem::transmute;
36-
use num::flt2dec::strategy::grisu::Fp;
36+
use num::diy_float::Fp;
3737
use num::FpCategory::{Infinite, Zero, Subnormal, Normal, Nan};
3838
use num::Float;
39-
use super::num::{self, Big};
39+
use num::dec2flt::num::{self, Big};
4040

4141
#[derive(Copy, Clone, Debug)]
4242
pub struct Unpacked {

src/libcore/num/diy_float.rs

+71
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
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.
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+
//! Extended precision "soft float", for internal use only.
12+
13+
// This module is only for dec2flt and flt2dec, and only public because of libcoretest.
14+
// It is not intended to ever be stabilized.
15+
#![doc(hidden)]
16+
#![unstable(feature = "core_private_diy_float",
17+
reason = "internal routines only exposed for testing",
18+
issue = "0")]
19+
20+
/// A custom 64-bit floating point type, representing `f * 2^e`.
21+
#[derive(Copy, Clone, Debug)]
22+
#[doc(hidden)]
23+
pub struct Fp {
24+
/// The integer mantissa.
25+
pub f: u64,
26+
/// The exponent in base 2.
27+
pub e: i16,
28+
}
29+
30+
impl Fp {
31+
/// Returns a correctly rounded product of itself and `other`.
32+
pub fn mul(&self, other: &Fp) -> Fp {
33+
const MASK: u64 = 0xffffffff;
34+
let a = self.f >> 32;
35+
let b = self.f & MASK;
36+
let c = other.f >> 32;
37+
let d = other.f & MASK;
38+
let ac = a * c;
39+
let bc = b * c;
40+
let ad = a * d;
41+
let bd = b * d;
42+
let tmp = (bd >> 32) + (ad & MASK) + (bc & MASK) + (1 << 31) /* round */;
43+
let f = ac + (ad >> 32) + (bc >> 32) + (tmp >> 32);
44+
let e = self.e + other.e + 64;
45+
Fp { f: f, e: e }
46+
}
47+
48+
/// Normalizes itself so that the resulting mantissa is at least `2^63`.
49+
pub fn normalize(&self) -> Fp {
50+
let mut f = self.f;
51+
let mut e = self.e;
52+
if f >> (64 - 32) == 0 { f <<= 32; e -= 32; }
53+
if f >> (64 - 16) == 0 { f <<= 16; e -= 16; }
54+
if f >> (64 - 8) == 0 { f <<= 8; e -= 8; }
55+
if f >> (64 - 4) == 0 { f <<= 4; e -= 4; }
56+
if f >> (64 - 2) == 0 { f <<= 2; e -= 2; }
57+
if f >> (64 - 1) == 0 { f <<= 1; e -= 1; }
58+
debug_assert!(f >= (1 >> 63));
59+
Fp { f: f, e: e }
60+
}
61+
62+
/// Normalizes itself to have the shared exponent.
63+
/// It can only decrease the exponent (and thus increase the mantissa).
64+
pub fn normalize_to(&self, e: i16) -> Fp {
65+
let edelta = self.e - e;
66+
assert!(edelta >= 0);
67+
let edelta = edelta as usize;
68+
assert_eq!(self.f << edelta >> edelta, self.f);
69+
Fp { f: self.f << edelta, e: e }
70+
}
71+
}

src/libcore/num/flt2dec/mod.rs

-1
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,6 @@ use slice::bytes;
136136
pub use self::decoder::{decode, DecodableFloat, FullDecoded, Decoded};
137137

138138
pub mod estimator;
139-
pub mod bignum;
140139
pub mod decoder;
141140

142141
/// Digit-generation algorithms.

src/libcore/num/flt2dec/strategy/dragon.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ use cmp::Ordering;
2121

2222
use num::flt2dec::{Decoded, MAX_SIG_DIGITS, round_up};
2323
use num::flt2dec::estimator::estimate_scaling_factor;
24-
use num::flt2dec::bignum::Digit32 as Digit;
25-
use num::flt2dec::bignum::Big32x40 as Big;
24+
use num::bignum::Digit32 as Digit;
25+
use num::bignum::Big32x40 as Big;
2626

2727
static POW10: [Digit; 10] = [1, 10, 100, 1000, 10000, 100000,
2828
1000000, 10000000, 100000000, 1000000000];

src/libcore/num/flt2dec/strategy/grisu.rs

+1-52
Original file line numberDiff line numberDiff line change
@@ -18,60 +18,9 @@ Rust adaptation of Grisu3 algorithm described in [1]. It uses about
1818

1919
use prelude::v1::*;
2020

21+
use num::diy_float::Fp;
2122
use num::flt2dec::{Decoded, MAX_SIG_DIGITS, round_up};
2223

23-
/// A custom 64-bit floating point type, representing `f * 2^e`.
24-
#[derive(Copy, Clone, Debug)]
25-
#[doc(hidden)]
26-
pub struct Fp {
27-
/// The integer mantissa.
28-
pub f: u64,
29-
/// The exponent in base 2.
30-
pub e: i16,
31-
}
32-
33-
impl Fp {
34-
/// Returns a correctly rounded product of itself and `other`.
35-
pub fn mul(&self, other: &Fp) -> Fp {
36-
const MASK: u64 = 0xffffffff;
37-
let a = self.f >> 32;
38-
let b = self.f & MASK;
39-
let c = other.f >> 32;
40-
let d = other.f & MASK;
41-
let ac = a * c;
42-
let bc = b * c;
43-
let ad = a * d;
44-
let bd = b * d;
45-
let tmp = (bd >> 32) + (ad & MASK) + (bc & MASK) + (1 << 31) /* round */;
46-
let f = ac + (ad >> 32) + (bc >> 32) + (tmp >> 32);
47-
let e = self.e + other.e + 64;
48-
Fp { f: f, e: e }
49-
}
50-
51-
/// Normalizes itself so that the resulting mantissa is at least `2^63`.
52-
pub fn normalize(&self) -> Fp {
53-
let mut f = self.f;
54-
let mut e = self.e;
55-
if f >> (64 - 32) == 0 { f <<= 32; e -= 32; }
56-
if f >> (64 - 16) == 0 { f <<= 16; e -= 16; }
57-
if f >> (64 - 8) == 0 { f <<= 8; e -= 8; }
58-
if f >> (64 - 4) == 0 { f <<= 4; e -= 4; }
59-
if f >> (64 - 2) == 0 { f <<= 2; e -= 2; }
60-
if f >> (64 - 1) == 0 { f <<= 1; e -= 1; }
61-
debug_assert!(f >= (1 >> 63));
62-
Fp { f: f, e: e }
63-
}
64-
65-
/// Normalizes itself to have the shared exponent.
66-
/// It can only decrease the exponent (and thus increase the mantissa).
67-
pub fn normalize_to(&self, e: i16) -> Fp {
68-
let edelta = self.e - e;
69-
assert!(edelta >= 0);
70-
let edelta = edelta as usize;
71-
assert_eq!(self.f << edelta >> edelta, self.f);
72-
Fp { f: self.f << edelta, e: e }
73-
}
74-
}
7524

7625
// see the comments in `format_shortest_opt` for the rationale.
7726
#[doc(hidden)] pub const ALPHA: i16 = -60;

src/libcore/num/mod.rs

+4
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,12 @@ use slice::SliceExt;
4343
pub struct Wrapping<T>(#[stable(feature = "rust1", since = "1.0.0")] pub T);
4444

4545
pub mod wrapping;
46+
47+
// All these modules are technically private and only exposed for libcoretest:
4648
pub mod flt2dec;
4749
pub mod dec2flt;
50+
pub mod bignum;
51+
pub mod diy_float;
4852

4953
/// Types that have a "zero" value.
5054
///

src/libcoretest/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
#![feature(const_fn)]
1616
#![feature(core)]
1717
#![feature(core_float)]
18+
#![feature(core_private_bignum)]
19+
#![feature(core_private_diy_float)]
1820
#![feature(dec2flt)]
1921
#![feature(decode_utf16)]
2022
#![feature(fixed_size_array)]

src/libcoretest/num/flt2dec/bignum.rs renamed to src/libcoretest/num/bignum.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
// except according to those terms.
1010

1111
use std::prelude::v1::*;
12-
use core::num::flt2dec::bignum::tests::Big8x3 as Big;
12+
use core::num::bignum::tests::Big8x3 as Big;
1313

1414
#[test]
1515
#[should_panic]

src/libcoretest/num/dec2flt/rawfp.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,14 @@
99
// except according to those terms.
1010

1111
use std::f64;
12-
use core::num::flt2dec::strategy::grisu::Fp;
12+
use core::num::diy_float::Fp;
1313
use core::num::dec2flt::rawfp::{fp_to_float, prev_float, next_float, round_normal};
1414

1515
#[test]
1616
fn fp_to_float_half_to_even() {
1717
fn is_normalized(sig: u64) -> bool {
18-
// intentionally written without {min,max}_sig() as a sanity check
19-
sig >> 52 == 1 && sig >> 53 == 0
18+
// intentionally written without {min,max}_sig() as a sanity check
19+
sig >> 52 == 1 && sig >> 53 == 0
2020
}
2121

2222
fn conv(sig: u64) -> u64 {

src/libcoretest/num/flt2dec/mod.rs

-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ use core::num::flt2dec::{to_shortest_str, to_shortest_exp_str,
2323
pub use test::Bencher;
2424

2525
mod estimator;
26-
mod bignum;
2726
mod strategy {
2827
mod dragon;
2928
mod grisu;

src/libcoretest/num/flt2dec/strategy/dragon.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use std::prelude::v1::*;
1212
use std::{i16, f64};
1313
use super::super::*;
1414
use core::num::flt2dec::*;
15-
use core::num::flt2dec::bignum::Big32x40 as Big;
15+
use core::num::bignum::Big32x40 as Big;
1616
use core::num::flt2dec::strategy::dragon::*;
1717

1818
#[test]

src/libcoretest/num/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ mod u64;
3131

3232
mod flt2dec;
3333
mod dec2flt;
34+
mod bignum;
3435

3536
/// Helper function for testing numeric operations
3637
pub fn test_num<T>(ten: T, two: T) where

0 commit comments

Comments
 (0)