]> git.lizzy.rs Git - rust.git/blob - src/librustc_apfloat/ieee.rs
tests: prefer edition: directives to compile-flags:--edition.
[rust.git] / src / librustc_apfloat / ieee.rs
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 use {Category, ExpInt, IEK_INF, IEK_NAN, IEK_ZERO};
12 use {Float, FloatConvert, ParseError, Round, Status, StatusAnd};
13
14 use std::cmp::{self, Ordering};
15 use std::convert::TryFrom;
16 use std::fmt::{self, Write};
17 use std::marker::PhantomData;
18 use std::mem;
19 use std::ops::Neg;
20
21 #[must_use]
22 pub struct IeeeFloat<S> {
23     /// Absolute significand value (including the integer bit).
24     sig: [Limb; 1],
25
26     /// The signed unbiased exponent of the value.
27     exp: ExpInt,
28
29     /// What kind of floating point number this is.
30     category: Category,
31
32     /// Sign bit of the number.
33     sign: bool,
34
35     marker: PhantomData<S>,
36 }
37
38 /// Fundamental unit of big integer arithmetic, but also
39 /// large to store the largest significands by itself.
40 type Limb = u128;
41 const LIMB_BITS: usize = 128;
42 fn limbs_for_bits(bits: usize) -> usize {
43     (bits + LIMB_BITS - 1) / LIMB_BITS
44 }
45
46 /// Enum that represents what fraction of the LSB truncated bits of an fp number
47 /// represent.
48 ///
49 /// This essentially combines the roles of guard and sticky bits.
50 #[must_use]
51 #[derive(Copy, Clone, PartialEq, Eq, Debug)]
52 enum Loss {
53     // Example of truncated bits:
54     ExactlyZero, // 000000
55     LessThanHalf, // 0xxxxx  x's not all zero
56     ExactlyHalf, // 100000
57     MoreThanHalf, // 1xxxxx  x's not all zero
58 }
59
60 /// Represents floating point arithmetic semantics.
61 pub trait Semantics: Sized {
62     /// Total number of bits in the in-memory format.
63     const BITS: usize;
64
65     /// Number of bits in the significand. This includes the integer bit.
66     const PRECISION: usize;
67
68     /// The largest E such that 2<sup>E</sup> is representable; this matches the
69     /// definition of IEEE 754.
70     const MAX_EXP: ExpInt;
71
72     /// The smallest E such that 2<sup>E</sup> is a normalized number; this
73     /// matches the definition of IEEE 754.
74     const MIN_EXP: ExpInt = -Self::MAX_EXP + 1;
75
76     /// The significand bit that marks NaN as quiet.
77     const QNAN_BIT: usize = Self::PRECISION - 2;
78
79     /// The significand bitpattern to mark a NaN as quiet.
80     /// NOTE: for X87DoubleExtended we need to set two bits instead of 2.
81     const QNAN_SIGNIFICAND: Limb = 1 << Self::QNAN_BIT;
82
83     fn from_bits(bits: u128) -> IeeeFloat<Self> {
84         assert!(Self::BITS > Self::PRECISION);
85
86         let sign = bits & (1 << (Self::BITS - 1));
87         let exponent = (bits & !sign) >> (Self::PRECISION - 1);
88         let mut r = IeeeFloat {
89             sig: [bits & ((1 << (Self::PRECISION - 1)) - 1)],
90             // Convert the exponent from its bias representation to a signed integer.
91             exp: (exponent as ExpInt) - Self::MAX_EXP,
92             category: Category::Zero,
93             sign: sign != 0,
94             marker: PhantomData,
95         };
96
97         if r.exp == Self::MIN_EXP - 1 && r.sig == [0] {
98             // Exponent, significand meaningless.
99             r.category = Category::Zero;
100         } else if r.exp == Self::MAX_EXP + 1 && r.sig == [0] {
101             // Exponent, significand meaningless.
102             r.category = Category::Infinity;
103         } else if r.exp == Self::MAX_EXP + 1 && r.sig != [0] {
104             // Sign, exponent, significand meaningless.
105             r.category = Category::NaN;
106         } else {
107             r.category = Category::Normal;
108             if r.exp == Self::MIN_EXP - 1 {
109                 // Denormal.
110                 r.exp = Self::MIN_EXP;
111             } else {
112                 // Set integer bit.
113                 sig::set_bit(&mut r.sig, Self::PRECISION - 1);
114             }
115         }
116
117         r
118     }
119
120     fn to_bits(x: IeeeFloat<Self>) -> u128 {
121         assert!(Self::BITS > Self::PRECISION);
122
123         // Split integer bit from significand.
124         let integer_bit = sig::get_bit(&x.sig, Self::PRECISION - 1);
125         let mut significand = x.sig[0] & ((1 << (Self::PRECISION - 1)) - 1);
126         let exponent = match x.category {
127             Category::Normal => {
128                 if x.exp == Self::MIN_EXP && !integer_bit {
129                     // Denormal.
130                     Self::MIN_EXP - 1
131                 } else {
132                     x.exp
133                 }
134             }
135             Category::Zero => {
136                 // FIXME(eddyb) Maybe we should guarantee an invariant instead?
137                 significand = 0;
138                 Self::MIN_EXP - 1
139             }
140             Category::Infinity => {
141                 // FIXME(eddyb) Maybe we should guarantee an invariant instead?
142                 significand = 0;
143                 Self::MAX_EXP + 1
144             }
145             Category::NaN => Self::MAX_EXP + 1,
146         };
147
148         // Convert the exponent from a signed integer to its bias representation.
149         let exponent = (exponent + Self::MAX_EXP) as u128;
150
151         ((x.sign as u128) << (Self::BITS - 1)) | (exponent << (Self::PRECISION - 1)) | significand
152     }
153 }
154
155 impl<S> Copy for IeeeFloat<S> {}
156 impl<S> Clone for IeeeFloat<S> {
157     fn clone(&self) -> Self {
158         *self
159     }
160 }
161
162 macro_rules! ieee_semantics {
163     ($($name:ident = $sem:ident($bits:tt : $exp_bits:tt)),*) => {
164         $(pub struct $sem;)*
165         $(pub type $name = IeeeFloat<$sem>;)*
166         $(impl Semantics for $sem {
167             const BITS: usize = $bits;
168             const PRECISION: usize = ($bits - 1 - $exp_bits) + 1;
169             const MAX_EXP: ExpInt = (1 << ($exp_bits - 1)) - 1;
170         })*
171     }
172 }
173
174 ieee_semantics! {
175     Half = HalfS(16:5),
176     Single = SingleS(32:8),
177     Double = DoubleS(64:11),
178     Quad = QuadS(128:15)
179 }
180
181 pub struct X87DoubleExtendedS;
182 pub type X87DoubleExtended = IeeeFloat<X87DoubleExtendedS>;
183 impl Semantics for X87DoubleExtendedS {
184     const BITS: usize = 80;
185     const PRECISION: usize = 64;
186     const MAX_EXP: ExpInt = (1 << (15 - 1)) - 1;
187
188     /// For x87 extended precision, we want to make a NaN, not a
189     /// pseudo-NaN. Maybe we should expose the ability to make
190     /// pseudo-NaNs?
191     const QNAN_SIGNIFICAND: Limb = 0b11 << Self::QNAN_BIT;
192
193     /// Integer bit is explicit in this format. Intel hardware (387 and later)
194     /// does not support these bit patterns:
195     ///  exponent = all 1's, integer bit 0, significand 0 ("pseudoinfinity")
196     ///  exponent = all 1's, integer bit 0, significand nonzero ("pseudoNaN")
197     ///  exponent = 0, integer bit 1 ("pseudodenormal")
198     ///  exponent!=0 nor all 1's, integer bit 0 ("unnormal")
199     /// At the moment, the first two are treated as NaNs, the second two as Normal.
200     fn from_bits(bits: u128) -> IeeeFloat<Self> {
201         let sign = bits & (1 << (Self::BITS - 1));
202         let exponent = (bits & !sign) >> Self::PRECISION;
203         let mut r = IeeeFloat {
204             sig: [bits & ((1 << (Self::PRECISION - 1)) - 1)],
205             // Convert the exponent from its bias representation to a signed integer.
206             exp: (exponent as ExpInt) - Self::MAX_EXP,
207             category: Category::Zero,
208             sign: sign != 0,
209             marker: PhantomData,
210         };
211
212         if r.exp == Self::MIN_EXP - 1 && r.sig == [0] {
213             // Exponent, significand meaningless.
214             r.category = Category::Zero;
215         } else if r.exp == Self::MAX_EXP + 1 && r.sig == [1 << (Self::PRECISION - 1)] {
216             // Exponent, significand meaningless.
217             r.category = Category::Infinity;
218         } else if r.exp == Self::MAX_EXP + 1 && r.sig != [1 << (Self::PRECISION - 1)] {
219             // Sign, exponent, significand meaningless.
220             r.category = Category::NaN;
221         } else {
222             r.category = Category::Normal;
223             if r.exp == Self::MIN_EXP - 1 {
224                 // Denormal.
225                 r.exp = Self::MIN_EXP;
226             }
227         }
228
229         r
230     }
231
232     fn to_bits(x: IeeeFloat<Self>) -> u128 {
233         // Get integer bit from significand.
234         let integer_bit = sig::get_bit(&x.sig, Self::PRECISION - 1);
235         let mut significand = x.sig[0] & ((1 << Self::PRECISION) - 1);
236         let exponent = match x.category {
237             Category::Normal => {
238                 if x.exp == Self::MIN_EXP && !integer_bit {
239                     // Denormal.
240                     Self::MIN_EXP - 1
241                 } else {
242                     x.exp
243                 }
244             }
245             Category::Zero => {
246                 // FIXME(eddyb) Maybe we should guarantee an invariant instead?
247                 significand = 0;
248                 Self::MIN_EXP - 1
249             }
250             Category::Infinity => {
251                 // FIXME(eddyb) Maybe we should guarantee an invariant instead?
252                 significand = 1 << (Self::PRECISION - 1);
253                 Self::MAX_EXP + 1
254             }
255             Category::NaN => Self::MAX_EXP + 1,
256         };
257
258         // Convert the exponent from a signed integer to its bias representation.
259         let exponent = (exponent + Self::MAX_EXP) as u128;
260
261         ((x.sign as u128) << (Self::BITS - 1)) | (exponent << Self::PRECISION) | significand
262     }
263 }
264
265 float_common_impls!(IeeeFloat<S>);
266
267 impl<S: Semantics> PartialEq for IeeeFloat<S> {
268     fn eq(&self, rhs: &Self) -> bool {
269         self.partial_cmp(rhs) == Some(Ordering::Equal)
270     }
271 }
272
273 impl<S: Semantics> PartialOrd for IeeeFloat<S> {
274     fn partial_cmp(&self, rhs: &Self) -> Option<Ordering> {
275         match (self.category, rhs.category) {
276             (Category::NaN, _) |
277             (_, Category::NaN) => None,
278
279             (Category::Infinity, Category::Infinity) => Some((!self.sign).cmp(&(!rhs.sign))),
280
281             (Category::Zero, Category::Zero) => Some(Ordering::Equal),
282
283             (Category::Infinity, _) |
284             (Category::Normal, Category::Zero) => Some((!self.sign).cmp(&self.sign)),
285
286             (_, Category::Infinity) |
287             (Category::Zero, Category::Normal) => Some(rhs.sign.cmp(&(!rhs.sign))),
288
289             (Category::Normal, Category::Normal) => {
290                 // Two normal numbers. Do they have the same sign?
291                 Some((!self.sign).cmp(&(!rhs.sign)).then_with(|| {
292                     // Compare absolute values; invert result if negative.
293                     let result = self.cmp_abs_normal(*rhs);
294
295                     if self.sign { result.reverse() } else { result }
296                 }))
297             }
298         }
299     }
300 }
301
302 impl<S> Neg for IeeeFloat<S> {
303     type Output = Self;
304     fn neg(mut self) -> Self {
305         self.sign = !self.sign;
306         self
307     }
308 }
309
310 /// Prints this value as a decimal string.
311 ///
312 /// \param precision The maximum number of digits of
313 ///   precision to output. If there are fewer digits available,
314 ///   zero padding will not be used unless the value is
315 ///   integral and small enough to be expressed in
316 ///   precision digits. 0 means to use the natural
317 ///   precision of the number.
318 /// \param width The maximum number of zeros to
319 ///   consider inserting before falling back to scientific
320 ///   notation. 0 means to always use scientific notation.
321 ///
322 /// \param alternate Indicate whether to remove the trailing zero in
323 ///   fraction part or not. Also setting this parameter to true forces
324 ///   producing of output more similar to default printf behavior.
325 ///   Specifically the lower e is used as exponent delimiter and exponent
326 ///   always contains no less than two digits.
327 ///
328 /// Number       precision    width      Result
329 /// ------       ---------    -----      ------
330 /// 1.01E+4              5        2       10100
331 /// 1.01E+4              4        2       1.01E+4
332 /// 1.01E+4              5        1       1.01E+4
333 /// 1.01E-2              5        2       0.0101
334 /// 1.01E-2              4        2       0.0101
335 /// 1.01E-2              4        1       1.01E-2
336 impl<S: Semantics> fmt::Display for IeeeFloat<S> {
337     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
338         let width = f.width().unwrap_or(3);
339         let alternate = f.alternate();
340
341         match self.category {
342             Category::Infinity => {
343                 if self.sign {
344                     return f.write_str("-Inf");
345                 } else {
346                     return f.write_str("+Inf");
347                 }
348             }
349
350             Category::NaN => return f.write_str("NaN"),
351
352             Category::Zero => {
353                 if self.sign {
354                     f.write_char('-')?;
355                 }
356
357                 if width == 0 {
358                     if alternate {
359                         f.write_str("0.0")?;
360                         if let Some(n) = f.precision() {
361                             for _ in 1..n {
362                                 f.write_char('0')?;
363                             }
364                         }
365                         f.write_str("e+00")?;
366                     } else {
367                         f.write_str("0.0E+0")?;
368                     }
369                 } else {
370                     f.write_char('0')?;
371                 }
372                 return Ok(());
373             }
374
375             Category::Normal => {}
376         }
377
378         if self.sign {
379             f.write_char('-')?;
380         }
381
382         // We use enough digits so the number can be round-tripped back to an
383         // APFloat. The formula comes from "How to Print Floating-Point Numbers
384         // Accurately" by Steele and White.
385         // FIXME: Using a formula based purely on the precision is conservative;
386         // we can print fewer digits depending on the actual value being printed.
387
388         // precision = 2 + floor(S::PRECISION / lg_2(10))
389         let precision = f.precision().unwrap_or(2 + S::PRECISION * 59 / 196);
390
391         // Decompose the number into an APInt and an exponent.
392         let mut exp = self.exp - (S::PRECISION as ExpInt - 1);
393         let mut sig = vec![self.sig[0]];
394
395         // Ignore trailing binary zeros.
396         let trailing_zeros = sig[0].trailing_zeros();
397         let _: Loss = sig::shift_right(&mut sig, &mut exp, trailing_zeros as usize);
398
399         // Change the exponent from 2^e to 10^e.
400         if exp == 0 {
401             // Nothing to do.
402         } else if exp > 0 {
403             // Just shift left.
404             let shift = exp as usize;
405             sig.resize(limbs_for_bits(S::PRECISION + shift), 0);
406             sig::shift_left(&mut sig, &mut exp, shift);
407         } else {
408             // exp < 0
409             let mut texp = -exp as usize;
410
411             // We transform this using the identity:
412             //   (N)(2^-e) == (N)(5^e)(10^-e)
413
414             // Multiply significand by 5^e.
415             //   N * 5^0101 == N * 5^(1*1) * 5^(0*2) * 5^(1*4) * 5^(0*8)
416             let mut sig_scratch = vec![];
417             let mut p5 = vec![];
418             let mut p5_scratch = vec![];
419             while texp != 0 {
420                 if p5.is_empty() {
421                     p5.push(5);
422                 } else {
423                     p5_scratch.resize(p5.len() * 2, 0);
424                     let _: Loss =
425                         sig::mul(&mut p5_scratch, &mut 0, &p5, &p5, p5.len() * 2 * LIMB_BITS);
426                     while p5_scratch.last() == Some(&0) {
427                         p5_scratch.pop();
428                     }
429                     mem::swap(&mut p5, &mut p5_scratch);
430                 }
431                 if texp & 1 != 0 {
432                     sig_scratch.resize(sig.len() + p5.len(), 0);
433                     let _: Loss = sig::mul(
434                         &mut sig_scratch,
435                         &mut 0,
436                         &sig,
437                         &p5,
438                         (sig.len() + p5.len()) * LIMB_BITS,
439                     );
440                     while sig_scratch.last() == Some(&0) {
441                         sig_scratch.pop();
442                     }
443                     mem::swap(&mut sig, &mut sig_scratch);
444                 }
445                 texp >>= 1;
446             }
447         }
448
449         // Fill the buffer.
450         let mut buffer = vec![];
451
452         // Ignore digits from the significand until it is no more
453         // precise than is required for the desired precision.
454         // 196/59 is a very slight overestimate of lg_2(10).
455         let required = (precision * 196 + 58) / 59;
456         let mut discard_digits = sig::omsb(&sig).saturating_sub(required) * 59 / 196;
457         let mut in_trail = true;
458         while !sig.is_empty() {
459             // Perform short division by 10 to extract the rightmost digit.
460             // rem <- sig % 10
461             // sig <- sig / 10
462             let mut rem = 0;
463
464             // Use 64-bit division and remainder, with 32-bit chunks from sig.
465             sig::each_chunk(&mut sig, 32, |chunk| {
466                 let chunk = chunk as u32;
467                 let combined = ((rem as u64) << 32) | (chunk as u64);
468                 rem = (combined % 10) as u8;
469                 (combined / 10) as u32 as Limb
470             });
471
472             // Reduce the sigificand to avoid wasting time dividing 0's.
473             while sig.last() == Some(&0) {
474                 sig.pop();
475             }
476
477             let digit = rem;
478
479             // Ignore digits we don't need.
480             if discard_digits > 0 {
481                 discard_digits -= 1;
482                 exp += 1;
483                 continue;
484             }
485
486             // Drop trailing zeros.
487             if in_trail && digit == 0 {
488                 exp += 1;
489             } else {
490                 in_trail = false;
491                 buffer.push(b'0' + digit);
492             }
493         }
494
495         assert!(!buffer.is_empty(), "no characters in buffer!");
496
497         // Drop down to precision.
498         // FIXME: don't do more precise calculations above than are required.
499         if buffer.len() > precision {
500             // The most significant figures are the last ones in the buffer.
501             let mut first_sig = buffer.len() - precision;
502
503             // Round.
504             // FIXME: this probably shouldn't use 'round half up'.
505
506             // Rounding down is just a truncation, except we also want to drop
507             // trailing zeros from the new result.
508             if buffer[first_sig - 1] < b'5' {
509                 while first_sig < buffer.len() && buffer[first_sig] == b'0' {
510                     first_sig += 1;
511                 }
512             } else {
513                 // Rounding up requires a decimal add-with-carry. If we continue
514                 // the carry, the newly-introduced zeros will just be truncated.
515                 for x in &mut buffer[first_sig..] {
516                     if *x == b'9' {
517                         first_sig += 1;
518                     } else {
519                         *x += 1;
520                         break;
521                     }
522                 }
523             }
524
525             exp += first_sig as ExpInt;
526             buffer.drain(..first_sig);
527
528             // If we carried through, we have exactly one digit of precision.
529             if buffer.is_empty() {
530                 buffer.push(b'1');
531             }
532         }
533
534         let digits = buffer.len();
535
536         // Check whether we should use scientific notation.
537         let scientific = if width == 0 {
538             true
539         } else if exp >= 0 {
540             // 765e3 --> 765000
541             //              ^^^
542             // But we shouldn't make the number look more precise than it is.
543             exp as usize > width || digits + exp as usize > precision
544         } else {
545             // Power of the most significant digit.
546             let msd = exp + (digits - 1) as ExpInt;
547             if msd >= 0 {
548                 // 765e-2 == 7.65
549                 false
550             } else {
551                 // 765e-5 == 0.00765
552                 //           ^ ^^
553                 -msd as usize > width
554             }
555         };
556
557         // Scientific formatting is pretty straightforward.
558         if scientific {
559             exp += digits as ExpInt - 1;
560
561             f.write_char(buffer[digits - 1] as char)?;
562             f.write_char('.')?;
563             let truncate_zero = !alternate;
564             if digits == 1 && truncate_zero {
565                 f.write_char('0')?;
566             } else {
567                 for &d in buffer[..digits - 1].iter().rev() {
568                     f.write_char(d as char)?;
569                 }
570             }
571             // Fill with zeros up to precision.
572             if !truncate_zero && precision > digits - 1 {
573                 for _ in 0..precision - digits + 1 {
574                     f.write_char('0')?;
575                 }
576             }
577             // For alternate we use lower 'e'.
578             f.write_char(if alternate { 'e' } else { 'E' })?;
579
580             // Exponent always at least two digits if we do not truncate zeros.
581             if truncate_zero {
582                 write!(f, "{:+}", exp)?;
583             } else {
584                 write!(f, "{:+03}", exp)?;
585             }
586
587             return Ok(());
588         }
589
590         // Non-scientific, positive exponents.
591         if exp >= 0 {
592             for &d in buffer.iter().rev() {
593                 f.write_char(d as char)?;
594             }
595             for _ in 0..exp {
596                 f.write_char('0')?;
597             }
598             return Ok(());
599         }
600
601         // Non-scientific, negative exponents.
602         let unit_place = -exp as usize;
603         if unit_place < digits {
604             for &d in buffer[unit_place..].iter().rev() {
605                 f.write_char(d as char)?;
606             }
607             f.write_char('.')?;
608             for &d in buffer[..unit_place].iter().rev() {
609                 f.write_char(d as char)?;
610             }
611         } else {
612             f.write_str("0.")?;
613             for _ in digits..unit_place {
614                 f.write_char('0')?;
615             }
616             for &d in buffer.iter().rev() {
617                 f.write_char(d as char)?;
618             }
619         }
620
621         Ok(())
622     }
623 }
624
625 impl<S: Semantics> fmt::Debug for IeeeFloat<S> {
626     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
627         write!(f, "{}({:?} | {}{:?} * 2^{})",
628                self, self.category,
629                if self.sign { "-" } else { "+" },
630                self.sig,
631                self.exp)
632     }
633 }
634
635 impl<S: Semantics> Float for IeeeFloat<S> {
636     const BITS: usize = S::BITS;
637     const PRECISION: usize = S::PRECISION;
638     const MAX_EXP: ExpInt = S::MAX_EXP;
639     const MIN_EXP: ExpInt = S::MIN_EXP;
640
641     const ZERO: Self = IeeeFloat {
642         sig: [0],
643         exp: S::MIN_EXP - 1,
644         category: Category::Zero,
645         sign: false,
646         marker: PhantomData,
647     };
648
649     const INFINITY: Self = IeeeFloat {
650         sig: [0],
651         exp: S::MAX_EXP + 1,
652         category: Category::Infinity,
653         sign: false,
654         marker: PhantomData,
655     };
656
657     // FIXME(eddyb) remove when qnan becomes const fn.
658     const NAN: Self = IeeeFloat {
659         sig: [S::QNAN_SIGNIFICAND],
660         exp: S::MAX_EXP + 1,
661         category: Category::NaN,
662         sign: false,
663         marker: PhantomData,
664     };
665
666     fn qnan(payload: Option<u128>) -> Self {
667         IeeeFloat {
668             sig: [
669                 S::QNAN_SIGNIFICAND |
670                     payload.map_or(0, |payload| {
671                         // Zero out the excess bits of the significand.
672                         payload & ((1 << S::QNAN_BIT) - 1)
673                     }),
674             ],
675             exp: S::MAX_EXP + 1,
676             category: Category::NaN,
677             sign: false,
678             marker: PhantomData,
679         }
680     }
681
682     fn snan(payload: Option<u128>) -> Self {
683         let mut snan = Self::qnan(payload);
684
685         // We always have to clear the QNaN bit to make it an SNaN.
686         sig::clear_bit(&mut snan.sig, S::QNAN_BIT);
687
688         // If there are no bits set in the payload, we have to set
689         // *something* to make it a NaN instead of an infinity;
690         // conventionally, this is the next bit down from the QNaN bit.
691         if snan.sig[0] & !S::QNAN_SIGNIFICAND == 0 {
692             sig::set_bit(&mut snan.sig, S::QNAN_BIT - 1);
693         }
694
695         snan
696     }
697
698     fn largest() -> Self {
699         // We want (in interchange format):
700         //   exponent = 1..10
701         //   significand = 1..1
702         IeeeFloat {
703             sig: [(1 << S::PRECISION) - 1],
704             exp: S::MAX_EXP,
705             category: Category::Normal,
706             sign: false,
707             marker: PhantomData,
708         }
709     }
710
711     // We want (in interchange format):
712     //   exponent = 0..0
713     //   significand = 0..01
714     const SMALLEST: Self = IeeeFloat {
715         sig: [1],
716         exp: S::MIN_EXP,
717         category: Category::Normal,
718         sign: false,
719         marker: PhantomData,
720     };
721
722     fn smallest_normalized() -> Self {
723         // We want (in interchange format):
724         //   exponent = 0..0
725         //   significand = 10..0
726         IeeeFloat {
727             sig: [1 << (S::PRECISION - 1)],
728             exp: S::MIN_EXP,
729             category: Category::Normal,
730             sign: false,
731             marker: PhantomData,
732         }
733     }
734
735     fn add_r(mut self, rhs: Self, round: Round) -> StatusAnd<Self> {
736         let status = match (self.category, rhs.category) {
737             (Category::Infinity, Category::Infinity) => {
738                 // Differently signed infinities can only be validly
739                 // subtracted.
740                 if self.sign != rhs.sign {
741                     self = Self::NAN;
742                     Status::INVALID_OP
743                 } else {
744                     Status::OK
745                 }
746             }
747
748             // Sign may depend on rounding mode; handled below.
749             (_, Category::Zero) |
750             (Category::NaN, _) |
751             (Category::Infinity, Category::Normal) => Status::OK,
752
753             (Category::Zero, _) |
754             (_, Category::NaN) |
755             (_, Category::Infinity) => {
756                 self = rhs;
757                 Status::OK
758             }
759
760             // This return code means it was not a simple case.
761             (Category::Normal, Category::Normal) => {
762                 let loss = sig::add_or_sub(
763                     &mut self.sig,
764                     &mut self.exp,
765                     &mut self.sign,
766                     &mut [rhs.sig[0]],
767                     rhs.exp,
768                     rhs.sign,
769                 );
770                 let status;
771                 self = unpack!(status=, self.normalize(round, loss));
772
773                 // Can only be zero if we lost no fraction.
774                 assert!(self.category != Category::Zero || loss == Loss::ExactlyZero);
775
776                 status
777             }
778         };
779
780         // If two numbers add (exactly) to zero, IEEE 754 decrees it is a
781         // positive zero unless rounding to minus infinity, except that
782         // adding two like-signed zeroes gives that zero.
783         if self.category == Category::Zero &&
784             (rhs.category != Category::Zero || self.sign != rhs.sign)
785         {
786             self.sign = round == Round::TowardNegative;
787         }
788
789         status.and(self)
790     }
791
792     fn mul_r(mut self, rhs: Self, round: Round) -> StatusAnd<Self> {
793         self.sign ^= rhs.sign;
794
795         match (self.category, rhs.category) {
796             (Category::NaN, _) => {
797                 self.sign = false;
798                 Status::OK.and(self)
799             }
800
801             (_, Category::NaN) => {
802                 self.sign = false;
803                 self.category = Category::NaN;
804                 self.sig = rhs.sig;
805                 Status::OK.and(self)
806             }
807
808             (Category::Zero, Category::Infinity) |
809             (Category::Infinity, Category::Zero) => Status::INVALID_OP.and(Self::NAN),
810
811             (_, Category::Infinity) |
812             (Category::Infinity, _) => {
813                 self.category = Category::Infinity;
814                 Status::OK.and(self)
815             }
816
817             (Category::Zero, _) |
818             (_, Category::Zero) => {
819                 self.category = Category::Zero;
820                 Status::OK.and(self)
821             }
822
823             (Category::Normal, Category::Normal) => {
824                 self.exp += rhs.exp;
825                 let mut wide_sig = [0; 2];
826                 let loss = sig::mul(
827                     &mut wide_sig,
828                     &mut self.exp,
829                     &self.sig,
830                     &rhs.sig,
831                     S::PRECISION,
832                 );
833                 self.sig = [wide_sig[0]];
834                 let mut status;
835                 self = unpack!(status=, self.normalize(round, loss));
836                 if loss != Loss::ExactlyZero {
837                     status |= Status::INEXACT;
838                 }
839                 status.and(self)
840             }
841         }
842     }
843
844     fn mul_add_r(mut self, multiplicand: Self, addend: Self, round: Round) -> StatusAnd<Self> {
845         // If and only if all arguments are normal do we need to do an
846         // extended-precision calculation.
847         if !self.is_finite_non_zero() || !multiplicand.is_finite_non_zero() || !addend.is_finite() {
848             let mut status;
849             self = unpack!(status=, self.mul_r(multiplicand, round));
850
851             // FS can only be Status::OK or Status::INVALID_OP. There is no more work
852             // to do in the latter case. The IEEE-754R standard says it is
853             // implementation-defined in this case whether, if ADDEND is a
854             // quiet NaN, we raise invalid op; this implementation does so.
855             //
856             // If we need to do the addition we can do so with normal
857             // precision.
858             if status == Status::OK {
859                 self = unpack!(status=, self.add_r(addend, round));
860             }
861             return status.and(self);
862         }
863
864         // Post-multiplication sign, before addition.
865         self.sign ^= multiplicand.sign;
866
867         // Allocate space for twice as many bits as the original significand, plus one
868         // extra bit for the addition to overflow into.
869         assert!(limbs_for_bits(S::PRECISION * 2 + 1) <= 2);
870         let mut wide_sig = sig::widening_mul(self.sig[0], multiplicand.sig[0]);
871
872         let mut loss = Loss::ExactlyZero;
873         let mut omsb = sig::omsb(&wide_sig);
874         self.exp += multiplicand.exp;
875
876         // Assume the operands involved in the multiplication are single-precision
877         // FP, and the two multiplicants are:
878         //     lhs = a23 . a22 ... a0 * 2^e1
879         //     rhs = b23 . b22 ... b0 * 2^e2
880         // the result of multiplication is:
881         //     lhs = c48 c47 c46 . c45 ... c0 * 2^(e1+e2)
882         // Note that there are three significant bits at the left-hand side of the
883         // radix point: two for the multiplication, and an overflow bit for the
884         // addition (that will always be zero at this point). Move the radix point
885         // toward left by two bits, and adjust exponent accordingly.
886         self.exp += 2;
887
888         if addend.is_non_zero() {
889             // Normalize our MSB to one below the top bit to allow for overflow.
890             let ext_precision = 2 * S::PRECISION + 1;
891             if omsb != ext_precision - 1 {
892                 assert!(ext_precision > omsb);
893                 sig::shift_left(&mut wide_sig, &mut self.exp, (ext_precision - 1) - omsb);
894             }
895
896             // The intermediate result of the multiplication has "2 * S::PRECISION"
897             // signicant bit; adjust the addend to be consistent with mul result.
898             let mut ext_addend_sig = [addend.sig[0], 0];
899
900             // Extend the addend significand to ext_precision - 1. This guarantees
901             // that the high bit of the significand is zero (same as wide_sig),
902             // so the addition will overflow (if it does overflow at all) into the top bit.
903             sig::shift_left(
904                 &mut ext_addend_sig,
905                 &mut 0,
906                 ext_precision - 1 - S::PRECISION,
907             );
908             loss = sig::add_or_sub(
909                 &mut wide_sig,
910                 &mut self.exp,
911                 &mut self.sign,
912                 &mut ext_addend_sig,
913                 addend.exp + 1,
914                 addend.sign,
915             );
916
917             omsb = sig::omsb(&wide_sig);
918         }
919
920         // Convert the result having "2 * S::PRECISION" significant-bits back to the one
921         // having "S::PRECISION" significant-bits. First, move the radix point from
922         // poision "2*S::PRECISION - 1" to "S::PRECISION - 1". The exponent need to be
923         // adjusted by "2*S::PRECISION - 1" - "S::PRECISION - 1" = "S::PRECISION".
924         self.exp -= S::PRECISION as ExpInt + 1;
925
926         // In case MSB resides at the left-hand side of radix point, shift the
927         // mantissa right by some amount to make sure the MSB reside right before
928         // the radix point (i.e. "MSB . rest-significant-bits").
929         if omsb > S::PRECISION {
930             let bits = omsb - S::PRECISION;
931             loss = sig::shift_right(&mut wide_sig, &mut self.exp, bits).combine(loss);
932         }
933
934         self.sig[0] = wide_sig[0];
935
936         let mut status;
937         self = unpack!(status=, self.normalize(round, loss));
938         if loss != Loss::ExactlyZero {
939             status |= Status::INEXACT;
940         }
941
942         // If two numbers add (exactly) to zero, IEEE 754 decrees it is a
943         // positive zero unless rounding to minus infinity, except that
944         // adding two like-signed zeroes gives that zero.
945         if self.category == Category::Zero && !status.intersects(Status::UNDERFLOW) &&
946             self.sign != addend.sign
947         {
948             self.sign = round == Round::TowardNegative;
949         }
950
951         status.and(self)
952     }
953
954     fn div_r(mut self, rhs: Self, round: Round) -> StatusAnd<Self> {
955         self.sign ^= rhs.sign;
956
957         match (self.category, rhs.category) {
958             (Category::NaN, _) => {
959                 self.sign = false;
960                 Status::OK.and(self)
961             }
962
963             (_, Category::NaN) => {
964                 self.category = Category::NaN;
965                 self.sig = rhs.sig;
966                 self.sign = false;
967                 Status::OK.and(self)
968             }
969
970             (Category::Infinity, Category::Infinity) |
971             (Category::Zero, Category::Zero) => Status::INVALID_OP.and(Self::NAN),
972
973             (Category::Infinity, _) |
974             (Category::Zero, _) => Status::OK.and(self),
975
976             (Category::Normal, Category::Infinity) => {
977                 self.category = Category::Zero;
978                 Status::OK.and(self)
979             }
980
981             (Category::Normal, Category::Zero) => {
982                 self.category = Category::Infinity;
983                 Status::DIV_BY_ZERO.and(self)
984             }
985
986             (Category::Normal, Category::Normal) => {
987                 self.exp -= rhs.exp;
988                 let dividend = self.sig[0];
989                 let loss = sig::div(
990                     &mut self.sig,
991                     &mut self.exp,
992                     &mut [dividend],
993                     &mut [rhs.sig[0]],
994                     S::PRECISION,
995                 );
996                 let mut status;
997                 self = unpack!(status=, self.normalize(round, loss));
998                 if loss != Loss::ExactlyZero {
999                     status |= Status::INEXACT;
1000                 }
1001                 status.and(self)
1002             }
1003         }
1004     }
1005
1006     fn c_fmod(mut self, rhs: Self) -> StatusAnd<Self> {
1007         match (self.category, rhs.category) {
1008             (Category::NaN, _) |
1009             (Category::Zero, Category::Infinity) |
1010             (Category::Zero, Category::Normal) |
1011             (Category::Normal, Category::Infinity) => Status::OK.and(self),
1012
1013             (_, Category::NaN) => {
1014                 self.sign = false;
1015                 self.category = Category::NaN;
1016                 self.sig = rhs.sig;
1017                 Status::OK.and(self)
1018             }
1019
1020             (Category::Infinity, _) |
1021             (_, Category::Zero) => Status::INVALID_OP.and(Self::NAN),
1022
1023             (Category::Normal, Category::Normal) => {
1024                 while self.is_finite_non_zero() && rhs.is_finite_non_zero() &&
1025                     self.cmp_abs_normal(rhs) != Ordering::Less
1026                 {
1027                     let mut v = rhs.scalbn(self.ilogb() - rhs.ilogb());
1028                     if self.cmp_abs_normal(v) == Ordering::Less {
1029                         v = v.scalbn(-1);
1030                     }
1031                     v.sign = self.sign;
1032
1033                     let status;
1034                     self = unpack!(status=, self - v);
1035                     assert_eq!(status, Status::OK);
1036                 }
1037                 Status::OK.and(self)
1038             }
1039         }
1040     }
1041
1042     fn round_to_integral(self, round: Round) -> StatusAnd<Self> {
1043         // If the exponent is large enough, we know that this value is already
1044         // integral, and the arithmetic below would potentially cause it to saturate
1045         // to +/-Inf. Bail out early instead.
1046         if self.is_finite_non_zero() && self.exp + 1 >= S::PRECISION as ExpInt {
1047             return Status::OK.and(self);
1048         }
1049
1050         // The algorithm here is quite simple: we add 2^(p-1), where p is the
1051         // precision of our format, and then subtract it back off again. The choice
1052         // of rounding modes for the addition/subtraction determines the rounding mode
1053         // for our integral rounding as well.
1054         // NOTE: When the input value is negative, we do subtraction followed by
1055         // addition instead.
1056         assert!(S::PRECISION <= 128);
1057         let mut status;
1058         let magic_const = unpack!(status=, Self::from_u128(1 << (S::PRECISION - 1)));
1059         let magic_const = magic_const.copy_sign(self);
1060
1061         if status != Status::OK {
1062             return status.and(self);
1063         }
1064
1065         let mut r = self;
1066         r = unpack!(status=, r.add_r(magic_const, round));
1067         if status != Status::OK && status != Status::INEXACT {
1068             return status.and(self);
1069         }
1070
1071         // Restore the input sign to handle 0.0/-0.0 cases correctly.
1072         r.sub_r(magic_const, round).map(|r| r.copy_sign(self))
1073     }
1074
1075     fn next_up(mut self) -> StatusAnd<Self> {
1076         // Compute nextUp(x), handling each float category separately.
1077         match self.category {
1078             Category::Infinity => {
1079                 if self.sign {
1080                     // nextUp(-inf) = -largest
1081                     Status::OK.and(-Self::largest())
1082                 } else {
1083                     // nextUp(+inf) = +inf
1084                     Status::OK.and(self)
1085                 }
1086             }
1087             Category::NaN => {
1088                 // IEEE-754R 2008 6.2 Par 2: nextUp(sNaN) = qNaN. Set Invalid flag.
1089                 // IEEE-754R 2008 6.2: nextUp(qNaN) = qNaN. Must be identity so we do not
1090                 //                     change the payload.
1091                 if self.is_signaling() {
1092                     // For consistency, propagate the sign of the sNaN to the qNaN.
1093                     Status::INVALID_OP.and(Self::NAN.copy_sign(self))
1094                 } else {
1095                     Status::OK.and(self)
1096                 }
1097             }
1098             Category::Zero => {
1099                 // nextUp(pm 0) = +smallest
1100                 Status::OK.and(Self::SMALLEST)
1101             }
1102             Category::Normal => {
1103                 // nextUp(-smallest) = -0
1104                 if self.is_smallest() && self.sign {
1105                     return Status::OK.and(-Self::ZERO);
1106                 }
1107
1108                 // nextUp(largest) == INFINITY
1109                 if self.is_largest() && !self.sign {
1110                     return Status::OK.and(Self::INFINITY);
1111                 }
1112
1113                 // Excluding the integral bit. This allows us to test for binade boundaries.
1114                 let sig_mask = (1 << (S::PRECISION - 1)) - 1;
1115
1116                 // nextUp(normal) == normal + inc.
1117                 if self.sign {
1118                     // If we are negative, we need to decrement the significand.
1119
1120                     // We only cross a binade boundary that requires adjusting the exponent
1121                     // if:
1122                     //   1. exponent != S::MIN_EXP. This implies we are not in the
1123                     //   smallest binade or are dealing with denormals.
1124                     //   2. Our significand excluding the integral bit is all zeros.
1125                     let crossing_binade_boundary = self.exp != S::MIN_EXP &&
1126                         self.sig[0] & sig_mask == 0;
1127
1128                     // Decrement the significand.
1129                     //
1130                     // We always do this since:
1131                     //   1. If we are dealing with a non-binade decrement, by definition we
1132                     //   just decrement the significand.
1133                     //   2. If we are dealing with a normal -> normal binade decrement, since
1134                     //   we have an explicit integral bit the fact that all bits but the
1135                     //   integral bit are zero implies that subtracting one will yield a
1136                     //   significand with 0 integral bit and 1 in all other spots. Thus we
1137                     //   must just adjust the exponent and set the integral bit to 1.
1138                     //   3. If we are dealing with a normal -> denormal binade decrement,
1139                     //   since we set the integral bit to 0 when we represent denormals, we
1140                     //   just decrement the significand.
1141                     sig::decrement(&mut self.sig);
1142
1143                     if crossing_binade_boundary {
1144                         // Our result is a normal number. Do the following:
1145                         // 1. Set the integral bit to 1.
1146                         // 2. Decrement the exponent.
1147                         sig::set_bit(&mut self.sig, S::PRECISION - 1);
1148                         self.exp -= 1;
1149                     }
1150                 } else {
1151                     // If we are positive, we need to increment the significand.
1152
1153                     // We only cross a binade boundary that requires adjusting the exponent if
1154                     // the input is not a denormal and all of said input's significand bits
1155                     // are set. If all of said conditions are true: clear the significand, set
1156                     // the integral bit to 1, and increment the exponent. If we have a
1157                     // denormal always increment since moving denormals and the numbers in the
1158                     // smallest normal binade have the same exponent in our representation.
1159                     let crossing_binade_boundary = !self.is_denormal() &&
1160                         self.sig[0] & sig_mask == sig_mask;
1161
1162                     if crossing_binade_boundary {
1163                         self.sig = [0];
1164                         sig::set_bit(&mut self.sig, S::PRECISION - 1);
1165                         assert_ne!(
1166                             self.exp,
1167                             S::MAX_EXP,
1168                             "We can not increment an exponent beyond the MAX_EXP \
1169                              allowed by the given floating point semantics."
1170                         );
1171                         self.exp += 1;
1172                     } else {
1173                         sig::increment(&mut self.sig);
1174                     }
1175                 }
1176                 Status::OK.and(self)
1177             }
1178         }
1179     }
1180
1181     fn from_bits(input: u128) -> Self {
1182         // Dispatch to semantics.
1183         S::from_bits(input)
1184     }
1185
1186     fn from_u128_r(input: u128, round: Round) -> StatusAnd<Self> {
1187         IeeeFloat {
1188             sig: [input],
1189             exp: S::PRECISION as ExpInt - 1,
1190             category: Category::Normal,
1191             sign: false,
1192             marker: PhantomData,
1193         }.normalize(round, Loss::ExactlyZero)
1194     }
1195
1196     fn from_str_r(mut s: &str, mut round: Round) -> Result<StatusAnd<Self>, ParseError> {
1197         if s.is_empty() {
1198             return Err(ParseError("Invalid string length"));
1199         }
1200
1201         // Handle special cases.
1202         match s {
1203             "inf" | "INFINITY" => return Ok(Status::OK.and(Self::INFINITY)),
1204             "-inf" | "-INFINITY" => return Ok(Status::OK.and(-Self::INFINITY)),
1205             "nan" | "NaN" => return Ok(Status::OK.and(Self::NAN)),
1206             "-nan" | "-NaN" => return Ok(Status::OK.and(-Self::NAN)),
1207             _ => {}
1208         }
1209
1210         // Handle a leading minus sign.
1211         let minus = s.starts_with("-");
1212         if minus || s.starts_with("+") {
1213             s = &s[1..];
1214             if s.is_empty() {
1215                 return Err(ParseError("String has no digits"));
1216             }
1217         }
1218
1219         // Adjust the rounding mode for the absolute value below.
1220         if minus {
1221             round = -round;
1222         }
1223
1224         let r = if s.starts_with("0x") || s.starts_with("0X") {
1225             s = &s[2..];
1226             if s.is_empty() {
1227                 return Err(ParseError("Invalid string"));
1228             }
1229             Self::from_hexadecimal_string(s, round)?
1230         } else {
1231             Self::from_decimal_string(s, round)?
1232         };
1233
1234         Ok(r.map(|r| if minus { -r } else { r }))
1235     }
1236
1237     fn to_bits(self) -> u128 {
1238         // Dispatch to semantics.
1239         S::to_bits(self)
1240     }
1241
1242     fn to_u128_r(self, width: usize, round: Round, is_exact: &mut bool) -> StatusAnd<u128> {
1243         // The result of trying to convert a number too large.
1244         let overflow = if self.sign {
1245             // Negative numbers cannot be represented as unsigned.
1246             0
1247         } else {
1248             // Largest unsigned integer of the given width.
1249             !0 >> (128 - width)
1250         };
1251
1252         *is_exact = false;
1253
1254         match self.category {
1255             Category::NaN => Status::INVALID_OP.and(0),
1256
1257             Category::Infinity => Status::INVALID_OP.and(overflow),
1258
1259             Category::Zero => {
1260                 // Negative zero can't be represented as an int.
1261                 *is_exact = !self.sign;
1262                 Status::OK.and(0)
1263             }
1264
1265             Category::Normal => {
1266                 let mut r = 0;
1267
1268                 // Step 1: place our absolute value, with any fraction truncated, in
1269                 // the destination.
1270                 let truncated_bits = if self.exp < 0 {
1271                     // Our absolute value is less than one; truncate everything.
1272                     // For exponent -1 the integer bit represents .5, look at that.
1273                     // For smaller exponents leftmost truncated bit is 0.
1274                     S::PRECISION - 1 + (-self.exp) as usize
1275                 } else {
1276                     // We want the most significant (exponent + 1) bits; the rest are
1277                     // truncated.
1278                     let bits = self.exp as usize + 1;
1279
1280                     // Hopelessly large in magnitude?
1281                     if bits > width {
1282                         return Status::INVALID_OP.and(overflow);
1283                     }
1284
1285                     if bits < S::PRECISION {
1286                         // We truncate (S::PRECISION - bits) bits.
1287                         r = self.sig[0] >> (S::PRECISION - bits);
1288                         S::PRECISION - bits
1289                     } else {
1290                         // We want at least as many bits as are available.
1291                         r = self.sig[0] << (bits - S::PRECISION);
1292                         0
1293                     }
1294                 };
1295
1296                 // Step 2: work out any lost fraction, and increment the absolute
1297                 // value if we would round away from zero.
1298                 let mut loss = Loss::ExactlyZero;
1299                 if truncated_bits > 0 {
1300                     loss = Loss::through_truncation(&self.sig, truncated_bits);
1301                     if loss != Loss::ExactlyZero &&
1302                         self.round_away_from_zero(round, loss, truncated_bits)
1303                     {
1304                         r = r.wrapping_add(1);
1305                         if r == 0 {
1306                             return Status::INVALID_OP.and(overflow); // Overflow.
1307                         }
1308                     }
1309                 }
1310
1311                 // Step 3: check if we fit in the destination.
1312                 if r > overflow {
1313                     return Status::INVALID_OP.and(overflow);
1314                 }
1315
1316                 if loss == Loss::ExactlyZero {
1317                     *is_exact = true;
1318                     Status::OK.and(r)
1319                 } else {
1320                     Status::INEXACT.and(r)
1321                 }
1322             }
1323         }
1324     }
1325
1326     fn cmp_abs_normal(self, rhs: Self) -> Ordering {
1327         assert!(self.is_finite_non_zero());
1328         assert!(rhs.is_finite_non_zero());
1329
1330         // If exponents are equal, do an unsigned comparison of the significands.
1331         self.exp.cmp(&rhs.exp).then_with(
1332             || sig::cmp(&self.sig, &rhs.sig),
1333         )
1334     }
1335
1336     fn bitwise_eq(self, rhs: Self) -> bool {
1337         if self.category != rhs.category || self.sign != rhs.sign {
1338             return false;
1339         }
1340
1341         if self.category == Category::Zero || self.category == Category::Infinity {
1342             return true;
1343         }
1344
1345         if self.is_finite_non_zero() && self.exp != rhs.exp {
1346             return false;
1347         }
1348
1349         self.sig == rhs.sig
1350     }
1351
1352     fn is_negative(self) -> bool {
1353         self.sign
1354     }
1355
1356     fn is_denormal(self) -> bool {
1357         self.is_finite_non_zero() && self.exp == S::MIN_EXP &&
1358             !sig::get_bit(&self.sig, S::PRECISION - 1)
1359     }
1360
1361     fn is_signaling(self) -> bool {
1362         // IEEE-754R 2008 6.2.1: A signaling NaN bit string should be encoded with the
1363         // first bit of the trailing significand being 0.
1364         self.is_nan() && !sig::get_bit(&self.sig, S::QNAN_BIT)
1365     }
1366
1367     fn category(self) -> Category {
1368         self.category
1369     }
1370
1371     fn get_exact_inverse(self) -> Option<Self> {
1372         // Special floats and denormals have no exact inverse.
1373         if !self.is_finite_non_zero() {
1374             return None;
1375         }
1376
1377         // Check that the number is a power of two by making sure that only the
1378         // integer bit is set in the significand.
1379         if self.sig != [1 << (S::PRECISION - 1)] {
1380             return None;
1381         }
1382
1383         // Get the inverse.
1384         let mut reciprocal = Self::from_u128(1).value;
1385         let status;
1386         reciprocal = unpack!(status=, reciprocal / self);
1387         if status != Status::OK {
1388             return None;
1389         }
1390
1391         // Avoid multiplication with a denormal, it is not safe on all platforms and
1392         // may be slower than a normal division.
1393         if reciprocal.is_denormal() {
1394             return None;
1395         }
1396
1397         assert!(reciprocal.is_finite_non_zero());
1398         assert_eq!(reciprocal.sig, [1 << (S::PRECISION - 1)]);
1399
1400         Some(reciprocal)
1401     }
1402
1403     fn ilogb(mut self) -> ExpInt {
1404         if self.is_nan() {
1405             return IEK_NAN;
1406         }
1407         if self.is_zero() {
1408             return IEK_ZERO;
1409         }
1410         if self.is_infinite() {
1411             return IEK_INF;
1412         }
1413         if !self.is_denormal() {
1414             return self.exp;
1415         }
1416
1417         let sig_bits = (S::PRECISION - 1) as ExpInt;
1418         self.exp += sig_bits;
1419         self = self.normalize(Round::NearestTiesToEven, Loss::ExactlyZero)
1420             .value;
1421         self.exp - sig_bits
1422     }
1423
1424     fn scalbn_r(mut self, exp: ExpInt, round: Round) -> Self {
1425         // If exp is wildly out-of-scale, simply adding it to self.exp will
1426         // overflow; clamp it to a safe range before adding, but ensure that the range
1427         // is large enough that the clamp does not change the result. The range we
1428         // need to support is the difference between the largest possible exponent and
1429         // the normalized exponent of half the smallest denormal.
1430
1431         let sig_bits = (S::PRECISION - 1) as i32;
1432         let max_change = S::MAX_EXP as i32 - (S::MIN_EXP as i32 - sig_bits) + 1;
1433
1434         // Clamp to one past the range ends to let normalize handle overflow.
1435         let exp_change = cmp::min(cmp::max(exp as i32, -max_change - 1), max_change);
1436         self.exp = self.exp.saturating_add(exp_change as ExpInt);
1437         self = self.normalize(round, Loss::ExactlyZero).value;
1438         if self.is_nan() {
1439             sig::set_bit(&mut self.sig, S::QNAN_BIT);
1440         }
1441         self
1442     }
1443
1444     fn frexp_r(mut self, exp: &mut ExpInt, round: Round) -> Self {
1445         *exp = self.ilogb();
1446
1447         // Quiet signalling nans.
1448         if *exp == IEK_NAN {
1449             sig::set_bit(&mut self.sig, S::QNAN_BIT);
1450             return self;
1451         }
1452
1453         if *exp == IEK_INF {
1454             return self;
1455         }
1456
1457         // 1 is added because frexp is defined to return a normalized fraction in
1458         // +/-[0.5, 1.0), rather than the usual +/-[1.0, 2.0).
1459         if *exp == IEK_ZERO {
1460             *exp = 0;
1461         } else {
1462             *exp += 1;
1463         }
1464         self.scalbn_r(-*exp, round)
1465     }
1466 }
1467
1468 impl<S: Semantics, T: Semantics> FloatConvert<IeeeFloat<T>> for IeeeFloat<S> {
1469     fn convert_r(self, round: Round, loses_info: &mut bool) -> StatusAnd<IeeeFloat<T>> {
1470         let mut r = IeeeFloat {
1471             sig: self.sig,
1472             exp: self.exp,
1473             category: self.category,
1474             sign: self.sign,
1475             marker: PhantomData,
1476         };
1477
1478         // x86 has some unusual NaNs which cannot be represented in any other
1479         // format; note them here.
1480         fn is_x87_double_extended<S: Semantics>() -> bool {
1481             S::QNAN_SIGNIFICAND == X87DoubleExtendedS::QNAN_SIGNIFICAND
1482         }
1483         let x87_special_nan = is_x87_double_extended::<S>() && !is_x87_double_extended::<T>() &&
1484             r.category == Category::NaN &&
1485             (r.sig[0] & S::QNAN_SIGNIFICAND) != S::QNAN_SIGNIFICAND;
1486
1487         // If this is a truncation of a denormal number, and the target semantics
1488         // has larger exponent range than the source semantics (this can happen
1489         // when truncating from PowerPC double-double to double format), the
1490         // right shift could lose result mantissa bits. Adjust exponent instead
1491         // of performing excessive shift.
1492         let mut shift = T::PRECISION as ExpInt - S::PRECISION as ExpInt;
1493         if shift < 0 && r.is_finite_non_zero() {
1494             let mut exp_change = sig::omsb(&r.sig) as ExpInt - S::PRECISION as ExpInt;
1495             if r.exp + exp_change < T::MIN_EXP {
1496                 exp_change = T::MIN_EXP - r.exp;
1497             }
1498             if exp_change < shift {
1499                 exp_change = shift;
1500             }
1501             if exp_change < 0 {
1502                 shift -= exp_change;
1503                 r.exp += exp_change;
1504             }
1505         }
1506
1507         // If this is a truncation, perform the shift.
1508         let loss = if shift < 0 && (r.is_finite_non_zero() || r.category == Category::NaN) {
1509             sig::shift_right(&mut r.sig, &mut 0, -shift as usize)
1510         } else {
1511             Loss::ExactlyZero
1512         };
1513
1514         // If this is an extension, perform the shift.
1515         if shift > 0 && (r.is_finite_non_zero() || r.category == Category::NaN) {
1516             sig::shift_left(&mut r.sig, &mut 0, shift as usize);
1517         }
1518
1519         let status;
1520         if r.is_finite_non_zero() {
1521             r = unpack!(status=, r.normalize(round, loss));
1522             *loses_info = status != Status::OK;
1523         } else if r.category == Category::NaN {
1524             *loses_info = loss != Loss::ExactlyZero || x87_special_nan;
1525
1526             // For x87 extended precision, we want to make a NaN, not a special NaN if
1527             // the input wasn't special either.
1528             if !x87_special_nan && is_x87_double_extended::<T>() {
1529                 sig::set_bit(&mut r.sig, T::PRECISION - 1);
1530             }
1531
1532             // gcc forces the Quiet bit on, which means (float)(double)(float_sNan)
1533             // does not give you back the same bits. This is dubious, and we
1534             // don't currently do it. You're really supposed to get
1535             // an invalid operation signal at runtime, but nobody does that.
1536             status = Status::OK;
1537         } else {
1538             *loses_info = false;
1539             status = Status::OK;
1540         }
1541
1542         status.and(r)
1543     }
1544 }
1545
1546 impl<S: Semantics> IeeeFloat<S> {
1547     /// Handle positive overflow. We either return infinity or
1548     /// the largest finite number. For negative overflow,
1549     /// negate the `round` argument before calling.
1550     fn overflow_result(round: Round) -> StatusAnd<Self> {
1551         match round {
1552             // Infinity?
1553             Round::NearestTiesToEven | Round::NearestTiesToAway | Round::TowardPositive => {
1554                 (Status::OVERFLOW | Status::INEXACT).and(Self::INFINITY)
1555             }
1556             // Otherwise we become the largest finite number.
1557             Round::TowardNegative | Round::TowardZero => Status::INEXACT.and(Self::largest()),
1558         }
1559     }
1560
1561     /// Returns TRUE if, when truncating the current number, with BIT the
1562     /// new LSB, with the given lost fraction and rounding mode, the result
1563     /// would need to be rounded away from zero (i.e., by increasing the
1564     /// signficand). This routine must work for Category::Zero of both signs, and
1565     /// Category::Normal numbers.
1566     fn round_away_from_zero(&self, round: Round, loss: Loss, bit: usize) -> bool {
1567         // NaNs and infinities should not have lost fractions.
1568         assert!(self.is_finite_non_zero() || self.is_zero());
1569
1570         // Current callers never pass this so we don't handle it.
1571         assert_ne!(loss, Loss::ExactlyZero);
1572
1573         match round {
1574             Round::NearestTiesToAway => loss == Loss::ExactlyHalf || loss == Loss::MoreThanHalf,
1575             Round::NearestTiesToEven => {
1576                 if loss == Loss::MoreThanHalf {
1577                     return true;
1578                 }
1579
1580                 // Our zeros don't have a significand to test.
1581                 if loss == Loss::ExactlyHalf && self.category != Category::Zero {
1582                     return sig::get_bit(&self.sig, bit);
1583                 }
1584
1585                 false
1586             }
1587             Round::TowardZero => false,
1588             Round::TowardPositive => !self.sign,
1589             Round::TowardNegative => self.sign,
1590         }
1591     }
1592
1593     fn normalize(mut self, round: Round, mut loss: Loss) -> StatusAnd<Self> {
1594         if !self.is_finite_non_zero() {
1595             return Status::OK.and(self);
1596         }
1597
1598         // Before rounding normalize the exponent of Category::Normal numbers.
1599         let mut omsb = sig::omsb(&self.sig);
1600
1601         if omsb > 0 {
1602             // OMSB is numbered from 1. We want to place it in the integer
1603             // bit numbered PRECISION if possible, with a compensating change in
1604             // the exponent.
1605             let mut final_exp = self.exp.saturating_add(
1606                 omsb as ExpInt - S::PRECISION as ExpInt,
1607             );
1608
1609             // If the resulting exponent is too high, overflow according to
1610             // the rounding mode.
1611             if final_exp > S::MAX_EXP {
1612                 let round = if self.sign { -round } else { round };
1613                 return Self::overflow_result(round).map(|r| r.copy_sign(self));
1614             }
1615
1616             // Subnormal numbers have exponent MIN_EXP, and their MSB
1617             // is forced based on that.
1618             if final_exp < S::MIN_EXP {
1619                 final_exp = S::MIN_EXP;
1620             }
1621
1622             // Shifting left is easy as we don't lose precision.
1623             if final_exp < self.exp {
1624                 assert_eq!(loss, Loss::ExactlyZero);
1625
1626                 let exp_change = (self.exp - final_exp) as usize;
1627                 sig::shift_left(&mut self.sig, &mut self.exp, exp_change);
1628
1629                 return Status::OK.and(self);
1630             }
1631
1632             // Shift right and capture any new lost fraction.
1633             if final_exp > self.exp {
1634                 let exp_change = (final_exp - self.exp) as usize;
1635                 loss = sig::shift_right(&mut self.sig, &mut self.exp, exp_change).combine(loss);
1636
1637                 // Keep OMSB up-to-date.
1638                 omsb = omsb.saturating_sub(exp_change);
1639             }
1640         }
1641
1642         // Now round the number according to round given the lost
1643         // fraction.
1644
1645         // As specified in IEEE 754, since we do not trap we do not report
1646         // underflow for exact results.
1647         if loss == Loss::ExactlyZero {
1648             // Canonicalize zeros.
1649             if omsb == 0 {
1650                 self.category = Category::Zero;
1651             }
1652
1653             return Status::OK.and(self);
1654         }
1655
1656         // Increment the significand if we're rounding away from zero.
1657         if self.round_away_from_zero(round, loss, 0) {
1658             if omsb == 0 {
1659                 self.exp = S::MIN_EXP;
1660             }
1661
1662             // We should never overflow.
1663             assert_eq!(sig::increment(&mut self.sig), 0);
1664             omsb = sig::omsb(&self.sig);
1665
1666             // Did the significand increment overflow?
1667             if omsb == S::PRECISION + 1 {
1668                 // Renormalize by incrementing the exponent and shifting our
1669                 // significand right one. However if we already have the
1670                 // maximum exponent we overflow to infinity.
1671                 if self.exp == S::MAX_EXP {
1672                     self.category = Category::Infinity;
1673
1674                     return (Status::OVERFLOW | Status::INEXACT).and(self);
1675                 }
1676
1677                 let _: Loss = sig::shift_right(&mut self.sig, &mut self.exp, 1);
1678
1679                 return Status::INEXACT.and(self);
1680             }
1681         }
1682
1683         // The normal case - we were and are not denormal, and any
1684         // significand increment above didn't overflow.
1685         if omsb == S::PRECISION {
1686             return Status::INEXACT.and(self);
1687         }
1688
1689         // We have a non-zero denormal.
1690         assert!(omsb < S::PRECISION);
1691
1692         // Canonicalize zeros.
1693         if omsb == 0 {
1694             self.category = Category::Zero;
1695         }
1696
1697         // The Category::Zero case is a denormal that underflowed to zero.
1698         (Status::UNDERFLOW | Status::INEXACT).and(self)
1699     }
1700
1701     fn from_hexadecimal_string(s: &str, round: Round) -> Result<StatusAnd<Self>, ParseError> {
1702         let mut r = IeeeFloat {
1703             sig: [0],
1704             exp: 0,
1705             category: Category::Normal,
1706             sign: false,
1707             marker: PhantomData,
1708         };
1709
1710         let mut any_digits = false;
1711         let mut has_exp = false;
1712         let mut bit_pos = LIMB_BITS as isize;
1713         let mut loss = None;
1714
1715         // Without leading or trailing zeros, irrespective of the dot.
1716         let mut first_sig_digit = None;
1717         let mut dot = s.len();
1718
1719         for (p, c) in s.char_indices() {
1720             // Skip leading zeros and any (hexa)decimal point.
1721             if c == '.' {
1722                 if dot != s.len() {
1723                     return Err(ParseError("String contains multiple dots"));
1724                 }
1725                 dot = p;
1726             } else if let Some(hex_value) = c.to_digit(16) {
1727                 any_digits = true;
1728
1729                 if first_sig_digit.is_none() {
1730                     if hex_value == 0 {
1731                         continue;
1732                     }
1733                     first_sig_digit = Some(p);
1734                 }
1735
1736                 // Store the number while we have space.
1737                 bit_pos -= 4;
1738                 if bit_pos >= 0 {
1739                     r.sig[0] |= (hex_value as Limb) << bit_pos;
1740                 // If zero or one-half (the hexadecimal digit 8) are followed
1741                 // by non-zero, they're a little more than zero or one-half.
1742                 } else if let Some(ref mut loss) = loss {
1743                     if hex_value != 0 {
1744                         if *loss == Loss::ExactlyZero {
1745                             *loss = Loss::LessThanHalf;
1746                         }
1747                         if *loss == Loss::ExactlyHalf {
1748                             *loss = Loss::MoreThanHalf;
1749                         }
1750                     }
1751                 } else {
1752                     loss = Some(match hex_value {
1753                         0 => Loss::ExactlyZero,
1754                         1..=7 => Loss::LessThanHalf,
1755                         8 => Loss::ExactlyHalf,
1756                         9..=15 => Loss::MoreThanHalf,
1757                         _ => unreachable!(),
1758                     });
1759                 }
1760             } else if c == 'p' || c == 'P' {
1761                 if !any_digits {
1762                     return Err(ParseError("Significand has no digits"));
1763                 }
1764
1765                 if dot == s.len() {
1766                     dot = p;
1767                 }
1768
1769                 let mut chars = s[p + 1..].chars().peekable();
1770
1771                 // Adjust for the given exponent.
1772                 let exp_minus = chars.peek() == Some(&'-');
1773                 if exp_minus || chars.peek() == Some(&'+') {
1774                     chars.next();
1775                 }
1776
1777                 for c in chars {
1778                     if let Some(value) = c.to_digit(10) {
1779                         has_exp = true;
1780                         r.exp = r.exp.saturating_mul(10).saturating_add(value as ExpInt);
1781                     } else {
1782                         return Err(ParseError("Invalid character in exponent"));
1783                     }
1784                 }
1785                 if !has_exp {
1786                     return Err(ParseError("Exponent has no digits"));
1787                 }
1788
1789                 if exp_minus {
1790                     r.exp = -r.exp;
1791                 }
1792
1793                 break;
1794             } else {
1795                 return Err(ParseError("Invalid character in significand"));
1796             }
1797         }
1798         if !any_digits {
1799             return Err(ParseError("Significand has no digits"));
1800         }
1801
1802         // Hex floats require an exponent but not a hexadecimal point.
1803         if !has_exp {
1804             return Err(ParseError("Hex strings require an exponent"));
1805         }
1806
1807         // Ignore the exponent if we are zero.
1808         let first_sig_digit = match first_sig_digit {
1809             Some(p) => p,
1810             None => return Ok(Status::OK.and(Self::ZERO)),
1811         };
1812
1813         // Calculate the exponent adjustment implicit in the number of
1814         // significant digits and adjust for writing the significand starting
1815         // at the most significant nibble.
1816         let exp_adjustment = if dot > first_sig_digit {
1817             ExpInt::try_from(dot - first_sig_digit).unwrap()
1818         } else {
1819             -ExpInt::try_from(first_sig_digit - dot - 1).unwrap()
1820         };
1821         let exp_adjustment = exp_adjustment
1822             .saturating_mul(4)
1823             .saturating_sub(1)
1824             .saturating_add(S::PRECISION as ExpInt)
1825             .saturating_sub(LIMB_BITS as ExpInt);
1826         r.exp = r.exp.saturating_add(exp_adjustment);
1827
1828         Ok(r.normalize(round, loss.unwrap_or(Loss::ExactlyZero)))
1829     }
1830
1831     fn from_decimal_string(s: &str, round: Round) -> Result<StatusAnd<Self>, ParseError> {
1832         // Given a normal decimal floating point number of the form
1833         //
1834         //   dddd.dddd[eE][+-]ddd
1835         //
1836         // where the decimal point and exponent are optional, fill out the
1837         // variables below. Exponent is appropriate if the significand is
1838         // treated as an integer, and normalized_exp if the significand
1839         // is taken to have the decimal point after a single leading
1840         // non-zero digit.
1841         //
1842         // If the value is zero, first_sig_digit is None.
1843
1844         let mut any_digits = false;
1845         let mut dec_exp = 0i32;
1846
1847         // Without leading or trailing zeros, irrespective of the dot.
1848         let mut first_sig_digit = None;
1849         let mut last_sig_digit = 0;
1850         let mut dot = s.len();
1851
1852         for (p, c) in s.char_indices() {
1853             if c == '.' {
1854                 if dot != s.len() {
1855                     return Err(ParseError("String contains multiple dots"));
1856                 }
1857                 dot = p;
1858             } else if let Some(dec_value) = c.to_digit(10) {
1859                 any_digits = true;
1860
1861                 if dec_value != 0 {
1862                     if first_sig_digit.is_none() {
1863                         first_sig_digit = Some(p);
1864                     }
1865                     last_sig_digit = p;
1866                 }
1867             } else if c == 'e' || c == 'E' {
1868                 if !any_digits {
1869                     return Err(ParseError("Significand has no digits"));
1870                 }
1871
1872                 if dot == s.len() {
1873                     dot = p;
1874                 }
1875
1876                 let mut chars = s[p + 1..].chars().peekable();
1877
1878                 // Adjust for the given exponent.
1879                 let exp_minus = chars.peek() == Some(&'-');
1880                 if exp_minus || chars.peek() == Some(&'+') {
1881                     chars.next();
1882                 }
1883
1884                 any_digits = false;
1885                 for c in chars {
1886                     if let Some(value) = c.to_digit(10) {
1887                         any_digits = true;
1888                         dec_exp = dec_exp.saturating_mul(10).saturating_add(value as i32);
1889                     } else {
1890                         return Err(ParseError("Invalid character in exponent"));
1891                     }
1892                 }
1893                 if !any_digits {
1894                     return Err(ParseError("Exponent has no digits"));
1895                 }
1896
1897                 if exp_minus {
1898                     dec_exp = -dec_exp;
1899                 }
1900
1901                 break;
1902             } else {
1903                 return Err(ParseError("Invalid character in significand"));
1904             }
1905         }
1906         if !any_digits {
1907             return Err(ParseError("Significand has no digits"));
1908         }
1909
1910         // Test if we have a zero number allowing for non-zero exponents.
1911         let first_sig_digit = match first_sig_digit {
1912             Some(p) => p,
1913             None => return Ok(Status::OK.and(Self::ZERO)),
1914         };
1915
1916         // Adjust the exponents for any decimal point.
1917         if dot > last_sig_digit {
1918             dec_exp = dec_exp.saturating_add((dot - last_sig_digit - 1) as i32);
1919         } else {
1920             dec_exp = dec_exp.saturating_sub((last_sig_digit - dot) as i32);
1921         }
1922         let significand_digits = last_sig_digit - first_sig_digit + 1 -
1923             (dot > first_sig_digit && dot < last_sig_digit) as usize;
1924         let normalized_exp = dec_exp.saturating_add(significand_digits as i32 - 1);
1925
1926         // Handle the cases where exponents are obviously too large or too
1927         // small. Writing L for log 10 / log 2, a number d.ddddd*10^dec_exp
1928         // definitely overflows if
1929         //
1930         //       (dec_exp - 1) * L >= MAX_EXP
1931         //
1932         // and definitely underflows to zero where
1933         //
1934         //       (dec_exp + 1) * L <= MIN_EXP - PRECISION
1935         //
1936         // With integer arithmetic the tightest bounds for L are
1937         //
1938         //       93/28 < L < 196/59            [ numerator <= 256 ]
1939         //       42039/12655 < L < 28738/8651  [ numerator <= 65536 ]
1940
1941         // Check for MAX_EXP.
1942         if normalized_exp.saturating_sub(1).saturating_mul(42039) >= 12655 * S::MAX_EXP as i32 {
1943             // Overflow and round.
1944             return Ok(Self::overflow_result(round));
1945         }
1946
1947         // Check for MIN_EXP.
1948         if normalized_exp.saturating_add(1).saturating_mul(28738) <=
1949             8651 * (S::MIN_EXP as i32 - S::PRECISION as i32)
1950         {
1951             // Underflow to zero and round.
1952             let r = if round == Round::TowardPositive {
1953                 IeeeFloat::SMALLEST
1954             } else {
1955                 IeeeFloat::ZERO
1956             };
1957             return Ok((Status::UNDERFLOW | Status::INEXACT).and(r));
1958         }
1959
1960         // A tight upper bound on number of bits required to hold an
1961         // N-digit decimal integer is N * 196 / 59. Allocate enough space
1962         // to hold the full significand, and an extra limb required by
1963         // tcMultiplyPart.
1964         let max_limbs = limbs_for_bits(1 + 196 * significand_digits / 59);
1965         let mut dec_sig = Vec::with_capacity(max_limbs);
1966
1967         // Convert to binary efficiently - we do almost all multiplication
1968         // in a Limb. When this would overflow do we do a single
1969         // bignum multiplication, and then revert again to multiplication
1970         // in a Limb.
1971         let mut chars = s[first_sig_digit..last_sig_digit + 1].chars();
1972         loop {
1973             let mut val = 0;
1974             let mut multiplier = 1;
1975
1976             loop {
1977                 let dec_value = match chars.next() {
1978                     Some('.') => continue,
1979                     Some(c) => c.to_digit(10).unwrap(),
1980                     None => break,
1981                 };
1982
1983                 multiplier *= 10;
1984                 val = val * 10 + dec_value as Limb;
1985
1986                 // The maximum number that can be multiplied by ten with any
1987                 // digit added without overflowing a Limb.
1988                 if multiplier > (!0 - 9) / 10 {
1989                     break;
1990                 }
1991             }
1992
1993             // If we've consumed no digits, we're done.
1994             if multiplier == 1 {
1995                 break;
1996             }
1997
1998             // Multiply out the current limb.
1999             let mut carry = val;
2000             for x in &mut dec_sig {
2001                 let [low, mut high] = sig::widening_mul(*x, multiplier);
2002
2003                 // Now add carry.
2004                 let (low, overflow) = low.overflowing_add(carry);
2005                 high += overflow as Limb;
2006
2007                 *x = low;
2008                 carry = high;
2009             }
2010
2011             // If we had carry, we need another limb (likely but not guaranteed).
2012             if carry > 0 {
2013                 dec_sig.push(carry);
2014             }
2015         }
2016
2017         // Calculate pow(5, abs(dec_exp)) into `pow5_full`.
2018         // The *_calc Vec's are reused scratch space, as an optimization.
2019         let (pow5_full, mut pow5_calc, mut sig_calc, mut sig_scratch_calc) = {
2020             let mut power = dec_exp.abs() as usize;
2021
2022             const FIRST_EIGHT_POWERS: [Limb; 8] = [1, 5, 25, 125, 625, 3125, 15625, 78125];
2023
2024             let mut p5_scratch = vec![];
2025             let mut p5 = vec![FIRST_EIGHT_POWERS[4]];
2026
2027             let mut r_scratch = vec![];
2028             let mut r = vec![FIRST_EIGHT_POWERS[power & 7]];
2029             power >>= 3;
2030
2031             while power > 0 {
2032                 // Calculate pow(5,pow(2,n+3)).
2033                 p5_scratch.resize(p5.len() * 2, 0);
2034                 let _: Loss = sig::mul(&mut p5_scratch, &mut 0, &p5, &p5, p5.len() * 2 * LIMB_BITS);
2035                 while p5_scratch.last() == Some(&0) {
2036                     p5_scratch.pop();
2037                 }
2038                 mem::swap(&mut p5, &mut p5_scratch);
2039
2040                 if power & 1 != 0 {
2041                     r_scratch.resize(r.len() + p5.len(), 0);
2042                     let _: Loss = sig::mul(
2043                         &mut r_scratch,
2044                         &mut 0,
2045                         &r,
2046                         &p5,
2047                         (r.len() + p5.len()) * LIMB_BITS,
2048                     );
2049                     while r_scratch.last() == Some(&0) {
2050                         r_scratch.pop();
2051                     }
2052                     mem::swap(&mut r, &mut r_scratch);
2053                 }
2054
2055                 power >>= 1;
2056             }
2057
2058             (r, r_scratch, p5, p5_scratch)
2059         };
2060
2061         // Attempt dec_sig * 10^dec_exp with increasing precision.
2062         let mut attempt = 0;
2063         loop {
2064             let calc_precision = (LIMB_BITS << attempt) - 1;
2065             attempt += 1;
2066
2067             let calc_normal_from_limbs = |sig: &mut Vec<Limb>,
2068                                           limbs: &[Limb]|
2069              -> StatusAnd<ExpInt> {
2070                 sig.resize(limbs_for_bits(calc_precision), 0);
2071                 let (mut loss, mut exp) = sig::from_limbs(sig, limbs, calc_precision);
2072
2073                 // Before rounding normalize the exponent of Category::Normal numbers.
2074                 let mut omsb = sig::omsb(sig);
2075
2076                 assert_ne!(omsb, 0);
2077
2078                 // OMSB is numbered from 1. We want to place it in the integer
2079                 // bit numbered PRECISION if possible, with a compensating change in
2080                 // the exponent.
2081                 let final_exp = exp.saturating_add(omsb as ExpInt - calc_precision as ExpInt);
2082
2083                 // Shifting left is easy as we don't lose precision.
2084                 if final_exp < exp {
2085                     assert_eq!(loss, Loss::ExactlyZero);
2086
2087                     let exp_change = (exp - final_exp) as usize;
2088                     sig::shift_left(sig, &mut exp, exp_change);
2089
2090                     return Status::OK.and(exp);
2091                 }
2092
2093                 // Shift right and capture any new lost fraction.
2094                 if final_exp > exp {
2095                     let exp_change = (final_exp - exp) as usize;
2096                     loss = sig::shift_right(sig, &mut exp, exp_change).combine(loss);
2097
2098                     // Keep OMSB up-to-date.
2099                     omsb = omsb.saturating_sub(exp_change);
2100                 }
2101
2102                 assert_eq!(omsb, calc_precision);
2103
2104                 // Now round the number according to round given the lost
2105                 // fraction.
2106
2107                 // As specified in IEEE 754, since we do not trap we do not report
2108                 // underflow for exact results.
2109                 if loss == Loss::ExactlyZero {
2110                     return Status::OK.and(exp);
2111                 }
2112
2113                 // Increment the significand if we're rounding away from zero.
2114                 if loss == Loss::MoreThanHalf || loss == Loss::ExactlyHalf && sig::get_bit(sig, 0) {
2115                     // We should never overflow.
2116                     assert_eq!(sig::increment(sig), 0);
2117                     omsb = sig::omsb(sig);
2118
2119                     // Did the significand increment overflow?
2120                     if omsb == calc_precision + 1 {
2121                         let _: Loss = sig::shift_right(sig, &mut exp, 1);
2122
2123                         return Status::INEXACT.and(exp);
2124                     }
2125                 }
2126
2127                 // The normal case - we were and are not denormal, and any
2128                 // significand increment above didn't overflow.
2129                 Status::INEXACT.and(exp)
2130             };
2131
2132             let status;
2133             let mut exp = unpack!(status=,
2134                 calc_normal_from_limbs(&mut sig_calc, &dec_sig));
2135             let pow5_status;
2136             let pow5_exp = unpack!(pow5_status=,
2137                 calc_normal_from_limbs(&mut pow5_calc, &pow5_full));
2138
2139             // Add dec_exp, as 10^n = 5^n * 2^n.
2140             exp += dec_exp as ExpInt;
2141
2142             let mut used_bits = S::PRECISION;
2143             let mut truncated_bits = calc_precision - used_bits;
2144
2145             let half_ulp_err1 = (status != Status::OK) as Limb;
2146             let (calc_loss, half_ulp_err2);
2147             if dec_exp >= 0 {
2148                 exp += pow5_exp;
2149
2150                 sig_scratch_calc.resize(sig_calc.len() + pow5_calc.len(), 0);
2151                 calc_loss = sig::mul(
2152                     &mut sig_scratch_calc,
2153                     &mut exp,
2154                     &sig_calc,
2155                     &pow5_calc,
2156                     calc_precision,
2157                 );
2158                 mem::swap(&mut sig_calc, &mut sig_scratch_calc);
2159
2160                 half_ulp_err2 = (pow5_status != Status::OK) as Limb;
2161             } else {
2162                 exp -= pow5_exp;
2163
2164                 sig_scratch_calc.resize(sig_calc.len(), 0);
2165                 calc_loss = sig::div(
2166                     &mut sig_scratch_calc,
2167                     &mut exp,
2168                     &mut sig_calc,
2169                     &mut pow5_calc,
2170                     calc_precision,
2171                 );
2172                 mem::swap(&mut sig_calc, &mut sig_scratch_calc);
2173
2174                 // Denormal numbers have less precision.
2175                 if exp < S::MIN_EXP {
2176                     truncated_bits += (S::MIN_EXP - exp) as usize;
2177                     used_bits = calc_precision.saturating_sub(truncated_bits);
2178                 }
2179                 // Extra half-ulp lost in reciprocal of exponent.
2180                 half_ulp_err2 = 2 *
2181                     (pow5_status != Status::OK || calc_loss != Loss::ExactlyZero) as Limb;
2182             }
2183
2184             // Both sig::mul and sig::div return the
2185             // result with the integer bit set.
2186             assert!(sig::get_bit(&sig_calc, calc_precision - 1));
2187
2188             // The error from the true value, in half-ulps, on multiplying two
2189             // floating point numbers, which differ from the value they
2190             // approximate by at most half_ulp_err1 and half_ulp_err2 half-ulps, is strictly less
2191             // than the returned value.
2192             //
2193             // See "How to Read Floating Point Numbers Accurately" by William D Clinger.
2194             assert!(
2195                 half_ulp_err1 < 2 || half_ulp_err2 < 2 || (half_ulp_err1 + half_ulp_err2 < 8)
2196             );
2197
2198             let inexact = (calc_loss != Loss::ExactlyZero) as Limb;
2199             let half_ulp_err = if half_ulp_err1 + half_ulp_err2 == 0 {
2200                 inexact * 2 // <= inexact half-ulps.
2201             } else {
2202                 inexact + 2 * (half_ulp_err1 + half_ulp_err2)
2203             };
2204
2205             let ulps_from_boundary = {
2206                 let bits = calc_precision - used_bits - 1;
2207
2208                 let i = bits / LIMB_BITS;
2209                 let limb = sig_calc[i] & (!0 >> (LIMB_BITS - 1 - bits % LIMB_BITS));
2210                 let boundary = match round {
2211                     Round::NearestTiesToEven | Round::NearestTiesToAway => 1 << (bits % LIMB_BITS),
2212                     _ => 0,
2213                 };
2214                 if i == 0 {
2215                     let delta = limb.wrapping_sub(boundary);
2216                     cmp::min(delta, delta.wrapping_neg())
2217                 } else if limb == boundary {
2218                     if !sig::is_all_zeros(&sig_calc[1..i]) {
2219                         !0 // A lot.
2220                     } else {
2221                         sig_calc[0]
2222                     }
2223                 } else if limb == boundary.wrapping_sub(1) {
2224                     if sig_calc[1..i].iter().any(|&x| x.wrapping_neg() != 1) {
2225                         !0 // A lot.
2226                     } else {
2227                         sig_calc[0].wrapping_neg()
2228                     }
2229                 } else {
2230                     !0 // A lot.
2231                 }
2232             };
2233
2234             // Are we guaranteed to round correctly if we truncate?
2235             if ulps_from_boundary.saturating_mul(2) >= half_ulp_err {
2236                 let mut r = IeeeFloat {
2237                     sig: [0],
2238                     exp,
2239                     category: Category::Normal,
2240                     sign: false,
2241                     marker: PhantomData,
2242                 };
2243                 sig::extract(&mut r.sig, &sig_calc, used_bits, calc_precision - used_bits);
2244                 // If we extracted less bits above we must adjust our exponent
2245                 // to compensate for the implicit right shift.
2246                 r.exp += (S::PRECISION - used_bits) as ExpInt;
2247                 let loss = Loss::through_truncation(&sig_calc, truncated_bits);
2248                 return Ok(r.normalize(round, loss));
2249             }
2250         }
2251     }
2252 }
2253
2254 impl Loss {
2255     /// Combine the effect of two lost fractions.
2256     fn combine(self, less_significant: Loss) -> Loss {
2257         let mut more_significant = self;
2258         if less_significant != Loss::ExactlyZero {
2259             if more_significant == Loss::ExactlyZero {
2260                 more_significant = Loss::LessThanHalf;
2261             } else if more_significant == Loss::ExactlyHalf {
2262                 more_significant = Loss::MoreThanHalf;
2263             }
2264         }
2265
2266         more_significant
2267     }
2268
2269     /// Return the fraction lost were a bignum truncated losing the least
2270     /// significant `bits` bits.
2271     fn through_truncation(limbs: &[Limb], bits: usize) -> Loss {
2272         if bits == 0 {
2273             return Loss::ExactlyZero;
2274         }
2275
2276         let half_bit = bits - 1;
2277         let half_limb = half_bit / LIMB_BITS;
2278         let (half_limb, rest) = if half_limb < limbs.len() {
2279             (limbs[half_limb], &limbs[..half_limb])
2280         } else {
2281             (0, limbs)
2282         };
2283         let half = 1 << (half_bit % LIMB_BITS);
2284         let has_half = half_limb & half != 0;
2285         let has_rest = half_limb & (half - 1) != 0 || !sig::is_all_zeros(rest);
2286
2287         match (has_half, has_rest) {
2288             (false, false) => Loss::ExactlyZero,
2289             (false, true) => Loss::LessThanHalf,
2290             (true, false) => Loss::ExactlyHalf,
2291             (true, true) => Loss::MoreThanHalf,
2292         }
2293     }
2294 }
2295
2296 /// Implementation details of IeeeFloat significands, such as big integer arithmetic.
2297 /// As a rule of thumb, no functions in this module should dynamically allocate.
2298 mod sig {
2299     use std::cmp::Ordering;
2300     use std::mem;
2301     use super::{ExpInt, Limb, LIMB_BITS, limbs_for_bits, Loss};
2302
2303     pub(super) fn is_all_zeros(limbs: &[Limb]) -> bool {
2304         limbs.iter().all(|&l| l == 0)
2305     }
2306
2307     /// One, not zero, based LSB. That is, returns 0 for a zeroed significand.
2308     pub(super) fn olsb(limbs: &[Limb]) -> usize {
2309         for (i, &limb) in limbs.iter().enumerate() {
2310             if limb != 0 {
2311                 return i * LIMB_BITS + limb.trailing_zeros() as usize + 1;
2312             }
2313         }
2314
2315         0
2316     }
2317
2318     /// One, not zero, based MSB. That is, returns 0 for a zeroed significand.
2319     pub(super) fn omsb(limbs: &[Limb]) -> usize {
2320         for (i, &limb) in limbs.iter().enumerate().rev() {
2321             if limb != 0 {
2322                 return (i + 1) * LIMB_BITS - limb.leading_zeros() as usize;
2323             }
2324         }
2325
2326         0
2327     }
2328
2329     /// Comparison (unsigned) of two significands.
2330     pub(super) fn cmp(a: &[Limb], b: &[Limb]) -> Ordering {
2331         assert_eq!(a.len(), b.len());
2332         for (a, b) in a.iter().zip(b).rev() {
2333             match a.cmp(b) {
2334                 Ordering::Equal => {}
2335                 o => return o,
2336             }
2337         }
2338
2339         Ordering::Equal
2340     }
2341
2342     /// Extract the given bit.
2343     pub(super) fn get_bit(limbs: &[Limb], bit: usize) -> bool {
2344         limbs[bit / LIMB_BITS] & (1 << (bit % LIMB_BITS)) != 0
2345     }
2346
2347     /// Set the given bit.
2348     pub(super) fn set_bit(limbs: &mut [Limb], bit: usize) {
2349         limbs[bit / LIMB_BITS] |= 1 << (bit % LIMB_BITS);
2350     }
2351
2352     /// Clear the given bit.
2353     pub(super) fn clear_bit(limbs: &mut [Limb], bit: usize) {
2354         limbs[bit / LIMB_BITS] &= !(1 << (bit % LIMB_BITS));
2355     }
2356
2357     /// Shift `dst` left `bits` bits, subtract `bits` from its exponent.
2358     pub(super) fn shift_left(dst: &mut [Limb], exp: &mut ExpInt, bits: usize) {
2359         if bits > 0 {
2360             // Our exponent should not underflow.
2361             *exp = exp.checked_sub(bits as ExpInt).unwrap();
2362
2363             // Jump is the inter-limb jump; shift is is intra-limb shift.
2364             let jump = bits / LIMB_BITS;
2365             let shift = bits % LIMB_BITS;
2366
2367             for i in (0..dst.len()).rev() {
2368                 let mut limb;
2369
2370                 if i < jump {
2371                     limb = 0;
2372                 } else {
2373                     // dst[i] comes from the two limbs src[i - jump] and, if we have
2374                     // an intra-limb shift, src[i - jump - 1].
2375                     limb = dst[i - jump];
2376                     if shift > 0 {
2377                         limb <<= shift;
2378                         if i > jump {
2379                             limb |= dst[i - jump - 1] >> (LIMB_BITS - shift);
2380                         }
2381                     }
2382                 }
2383
2384                 dst[i] = limb;
2385             }
2386         }
2387     }
2388
2389     /// Shift `dst` right `bits` bits noting lost fraction.
2390     pub(super) fn shift_right(dst: &mut [Limb], exp: &mut ExpInt, bits: usize) -> Loss {
2391         let loss = Loss::through_truncation(dst, bits);
2392
2393         if bits > 0 {
2394             // Our exponent should not overflow.
2395             *exp = exp.checked_add(bits as ExpInt).unwrap();
2396
2397             // Jump is the inter-limb jump; shift is is intra-limb shift.
2398             let jump = bits / LIMB_BITS;
2399             let shift = bits % LIMB_BITS;
2400
2401             // Perform the shift. This leaves the most significant `bits` bits
2402             // of the result at zero.
2403             for i in 0..dst.len() {
2404                 let mut limb;
2405
2406                 if i + jump >= dst.len() {
2407                     limb = 0;
2408                 } else {
2409                     limb = dst[i + jump];
2410                     if shift > 0 {
2411                         limb >>= shift;
2412                         if i + jump + 1 < dst.len() {
2413                             limb |= dst[i + jump + 1] << (LIMB_BITS - shift);
2414                         }
2415                     }
2416                 }
2417
2418                 dst[i] = limb;
2419             }
2420         }
2421
2422         loss
2423     }
2424
2425     /// Copy the bit vector of width `src_bits` from `src`, starting at bit SRC_LSB,
2426     /// to `dst`, such that the bit SRC_LSB becomes the least significant bit of `dst`.
2427     /// All high bits above `src_bits` in `dst` are zero-filled.
2428     pub(super) fn extract(dst: &mut [Limb], src: &[Limb], src_bits: usize, src_lsb: usize) {
2429         if src_bits == 0 {
2430             return;
2431         }
2432
2433         let dst_limbs = limbs_for_bits(src_bits);
2434         assert!(dst_limbs <= dst.len());
2435
2436         let src = &src[src_lsb / LIMB_BITS..];
2437         dst[..dst_limbs].copy_from_slice(&src[..dst_limbs]);
2438
2439         let shift = src_lsb % LIMB_BITS;
2440         let _: Loss = shift_right(&mut dst[..dst_limbs], &mut 0, shift);
2441
2442         // We now have (dst_limbs * LIMB_BITS - shift) bits from `src`
2443         // in `dst`.  If this is less that src_bits, append the rest, else
2444         // clear the high bits.
2445         let n = dst_limbs * LIMB_BITS - shift;
2446         if n < src_bits {
2447             let mask = (1 << (src_bits - n)) - 1;
2448             dst[dst_limbs - 1] |= (src[dst_limbs] & mask) << (n % LIMB_BITS);
2449         } else if n > src_bits && src_bits % LIMB_BITS > 0 {
2450             dst[dst_limbs - 1] &= (1 << (src_bits % LIMB_BITS)) - 1;
2451         }
2452
2453         // Clear high limbs.
2454         for x in &mut dst[dst_limbs..] {
2455             *x = 0;
2456         }
2457     }
2458
2459     /// We want the most significant PRECISION bits of `src`. There may not
2460     /// be that many; extract what we can.
2461     pub(super) fn from_limbs(dst: &mut [Limb], src: &[Limb], precision: usize) -> (Loss, ExpInt) {
2462         let omsb = omsb(src);
2463
2464         if precision <= omsb {
2465             extract(dst, src, precision, omsb - precision);
2466             (
2467                 Loss::through_truncation(src, omsb - precision),
2468                 omsb as ExpInt - 1,
2469             )
2470         } else {
2471             extract(dst, src, omsb, 0);
2472             (Loss::ExactlyZero, precision as ExpInt - 1)
2473         }
2474     }
2475
2476     /// For every consecutive chunk of `bits` bits from `limbs`,
2477     /// going from most significant to the least significant bits,
2478     /// call `f` to transform those bits and store the result back.
2479     pub(super) fn each_chunk<F: FnMut(Limb) -> Limb>(limbs: &mut [Limb], bits: usize, mut f: F) {
2480         assert_eq!(LIMB_BITS % bits, 0);
2481         for limb in limbs.iter_mut().rev() {
2482             let mut r = 0;
2483             for i in (0..LIMB_BITS / bits).rev() {
2484                 r |= f((*limb >> (i * bits)) & ((1 << bits) - 1)) << (i * bits);
2485             }
2486             *limb = r;
2487         }
2488     }
2489
2490     /// Increment in-place, return the carry flag.
2491     pub(super) fn increment(dst: &mut [Limb]) -> Limb {
2492         for x in dst {
2493             *x = x.wrapping_add(1);
2494             if *x != 0 {
2495                 return 0;
2496             }
2497         }
2498
2499         1
2500     }
2501
2502     /// Decrement in-place, return the borrow flag.
2503     pub(super) fn decrement(dst: &mut [Limb]) -> Limb {
2504         for x in dst {
2505             *x = x.wrapping_sub(1);
2506             if *x != !0 {
2507                 return 0;
2508             }
2509         }
2510
2511         1
2512     }
2513
2514     /// `a += b + c` where `c` is zero or one. Returns the carry flag.
2515     pub(super) fn add(a: &mut [Limb], b: &[Limb], mut c: Limb) -> Limb {
2516         assert!(c <= 1);
2517
2518         for (a, &b) in a.iter_mut().zip(b) {
2519             let (r, overflow) = a.overflowing_add(b);
2520             let (r, overflow2) = r.overflowing_add(c);
2521             *a = r;
2522             c = (overflow | overflow2) as Limb;
2523         }
2524
2525         c
2526     }
2527
2528     /// `a -= b + c` where `c` is zero or one. Returns the borrow flag.
2529     pub(super) fn sub(a: &mut [Limb], b: &[Limb], mut c: Limb) -> Limb {
2530         assert!(c <= 1);
2531
2532         for (a, &b) in a.iter_mut().zip(b) {
2533             let (r, overflow) = a.overflowing_sub(b);
2534             let (r, overflow2) = r.overflowing_sub(c);
2535             *a = r;
2536             c = (overflow | overflow2) as Limb;
2537         }
2538
2539         c
2540     }
2541
2542     /// `a += b` or `a -= b`. Does not preserve `b`.
2543     pub(super) fn add_or_sub(
2544         a_sig: &mut [Limb],
2545         a_exp: &mut ExpInt,
2546         a_sign: &mut bool,
2547         b_sig: &mut [Limb],
2548         b_exp: ExpInt,
2549         b_sign: bool,
2550     ) -> Loss {
2551         // Are we bigger exponent-wise than the RHS?
2552         let bits = *a_exp - b_exp;
2553
2554         // Determine if the operation on the absolute values is effectively
2555         // an addition or subtraction.
2556         // Subtraction is more subtle than one might naively expect.
2557         if *a_sign ^ b_sign {
2558             let (reverse, loss);
2559
2560             if bits == 0 {
2561                 reverse = cmp(a_sig, b_sig) == Ordering::Less;
2562                 loss = Loss::ExactlyZero;
2563             } else if bits > 0 {
2564                 loss = shift_right(b_sig, &mut 0, (bits - 1) as usize);
2565                 shift_left(a_sig, a_exp, 1);
2566                 reverse = false;
2567             } else {
2568                 loss = shift_right(a_sig, a_exp, (-bits - 1) as usize);
2569                 shift_left(b_sig, &mut 0, 1);
2570                 reverse = true;
2571             }
2572
2573             let borrow = (loss != Loss::ExactlyZero) as Limb;
2574             if reverse {
2575                 // The code above is intended to ensure that no borrow is necessary.
2576                 assert_eq!(sub(b_sig, a_sig, borrow), 0);
2577                 a_sig.copy_from_slice(b_sig);
2578                 *a_sign = !*a_sign;
2579             } else {
2580                 // The code above is intended to ensure that no borrow is necessary.
2581                 assert_eq!(sub(a_sig, b_sig, borrow), 0);
2582             }
2583
2584             // Invert the lost fraction - it was on the RHS and subtracted.
2585             match loss {
2586                 Loss::LessThanHalf => Loss::MoreThanHalf,
2587                 Loss::MoreThanHalf => Loss::LessThanHalf,
2588                 _ => loss,
2589             }
2590         } else {
2591             let loss = if bits > 0 {
2592                 shift_right(b_sig, &mut 0, bits as usize)
2593             } else {
2594                 shift_right(a_sig, a_exp, -bits as usize)
2595             };
2596             // We have a guard bit; generating a carry cannot happen.
2597             assert_eq!(add(a_sig, b_sig, 0), 0);
2598             loss
2599         }
2600     }
2601
2602     /// `[low, high] = a * b`.
2603     ///
2604     /// This cannot overflow, because
2605     ///
2606     /// `(n - 1) * (n - 1) + 2 * (n - 1) == (n - 1) * (n + 1)`
2607     ///
2608     /// which is less than n<sup>2</sup>.
2609     pub(super) fn widening_mul(a: Limb, b: Limb) -> [Limb; 2] {
2610         let mut wide = [0, 0];
2611
2612         if a == 0 || b == 0 {
2613             return wide;
2614         }
2615
2616         const HALF_BITS: usize = LIMB_BITS / 2;
2617
2618         let select = |limb, i| (limb >> (i * HALF_BITS)) & ((1 << HALF_BITS) - 1);
2619         for i in 0..2 {
2620             for j in 0..2 {
2621                 let mut x = [select(a, i) * select(b, j), 0];
2622                 shift_left(&mut x, &mut 0, (i + j) * HALF_BITS);
2623                 assert_eq!(add(&mut wide, &x, 0), 0);
2624             }
2625         }
2626
2627         wide
2628     }
2629
2630     /// `dst = a * b` (for normal `a` and `b`). Returns the lost fraction.
2631     pub(super) fn mul<'a>(
2632         dst: &mut [Limb],
2633         exp: &mut ExpInt,
2634         mut a: &'a [Limb],
2635         mut b: &'a [Limb],
2636         precision: usize,
2637     ) -> Loss {
2638         // Put the narrower number on the `a` for less loops below.
2639         if a.len() > b.len() {
2640             mem::swap(&mut a, &mut b);
2641         }
2642
2643         for x in &mut dst[..b.len()] {
2644             *x = 0;
2645         }
2646
2647         for i in 0..a.len() {
2648             let mut carry = 0;
2649             for j in 0..b.len() {
2650                 let [low, mut high] = widening_mul(a[i], b[j]);
2651
2652                 // Now add carry.
2653                 let (low, overflow) = low.overflowing_add(carry);
2654                 high += overflow as Limb;
2655
2656                 // And now `dst[i + j]`, and store the new low part there.
2657                 let (low, overflow) = low.overflowing_add(dst[i + j]);
2658                 high += overflow as Limb;
2659
2660                 dst[i + j] = low;
2661                 carry = high;
2662             }
2663             dst[i + b.len()] = carry;
2664         }
2665
2666         // Assume the operands involved in the multiplication are single-precision
2667         // FP, and the two multiplicants are:
2668         //     a = a23 . a22 ... a0 * 2^e1
2669         //     b = b23 . b22 ... b0 * 2^e2
2670         // the result of multiplication is:
2671         //     dst = c48 c47 c46 . c45 ... c0 * 2^(e1+e2)
2672         // Note that there are three significant bits at the left-hand side of the
2673         // radix point: two for the multiplication, and an overflow bit for the
2674         // addition (that will always be zero at this point). Move the radix point
2675         // toward left by two bits, and adjust exponent accordingly.
2676         *exp += 2;
2677
2678         // Convert the result having "2 * precision" significant-bits back to the one
2679         // having "precision" significant-bits. First, move the radix point from
2680         // poision "2*precision - 1" to "precision - 1". The exponent need to be
2681         // adjusted by "2*precision - 1" - "precision - 1" = "precision".
2682         *exp -= precision as ExpInt + 1;
2683
2684         // In case MSB resides at the left-hand side of radix point, shift the
2685         // mantissa right by some amount to make sure the MSB reside right before
2686         // the radix point (i.e. "MSB . rest-significant-bits").
2687         //
2688         // Note that the result is not normalized when "omsb < precision". So, the
2689         // caller needs to call IeeeFloat::normalize() if normalized value is
2690         // expected.
2691         let omsb = omsb(dst);
2692         if omsb <= precision {
2693             Loss::ExactlyZero
2694         } else {
2695             shift_right(dst, exp, omsb - precision)
2696         }
2697     }
2698
2699     /// `quotient = dividend / divisor`. Returns the lost fraction.
2700     /// Does not preserve `dividend` or `divisor`.
2701     pub(super) fn div(
2702         quotient: &mut [Limb],
2703         exp: &mut ExpInt,
2704         dividend: &mut [Limb],
2705         divisor: &mut [Limb],
2706         precision: usize,
2707     ) -> Loss {
2708
2709         // Normalize the divisor.
2710         let bits = precision - omsb(divisor);
2711         shift_left(divisor, &mut 0, bits);
2712         *exp += bits as ExpInt;
2713
2714         // Normalize the dividend.
2715         let bits = precision - omsb(dividend);
2716         shift_left(dividend, exp, bits);
2717
2718         // Division by 1.
2719         let olsb_divisor = olsb(divisor);
2720         if olsb_divisor == precision {
2721             quotient.copy_from_slice(dividend);
2722             return Loss::ExactlyZero;
2723         }
2724
2725         // Ensure the dividend >= divisor initially for the loop below.
2726         // Incidentally, this means that the division loop below is
2727         // guaranteed to set the integer bit to one.
2728         if cmp(dividend, divisor) == Ordering::Less {
2729             shift_left(dividend, exp, 1);
2730             assert_ne!(cmp(dividend, divisor), Ordering::Less)
2731         }
2732
2733         // Helper for figuring out the lost fraction.
2734         let lost_fraction = |dividend: &[Limb], divisor: &[Limb]| {
2735             match cmp(dividend, divisor) {
2736                 Ordering::Greater => Loss::MoreThanHalf,
2737                 Ordering::Equal => Loss::ExactlyHalf,
2738                 Ordering::Less => {
2739                     if is_all_zeros(dividend) {
2740                         Loss::ExactlyZero
2741                     } else {
2742                         Loss::LessThanHalf
2743                     }
2744                 }
2745             }
2746         };
2747
2748         // Try to perform a (much faster) short division for small divisors.
2749         let divisor_bits = precision - (olsb_divisor - 1);
2750         macro_rules! try_short_div {
2751             ($W:ty, $H:ty, $half:expr) => {
2752                 if divisor_bits * 2 <= $half {
2753                     // Extract the small divisor.
2754                     let _: Loss = shift_right(divisor, &mut 0, olsb_divisor - 1);
2755                     let divisor = divisor[0] as $H as $W;
2756
2757                     // Shift the dividend to produce a quotient with the unit bit set.
2758                     let top_limb = *dividend.last().unwrap();
2759                     let mut rem = (top_limb >> (LIMB_BITS - (divisor_bits - 1))) as $H;
2760                     shift_left(dividend, &mut 0, divisor_bits - 1);
2761
2762                     // Apply short division in place on $H (of $half bits) chunks.
2763                     each_chunk(dividend, $half, |chunk| {
2764                         let chunk = chunk as $H;
2765                         let combined = ((rem as $W) << $half) | (chunk as $W);
2766                         rem = (combined % divisor) as $H;
2767                         (combined / divisor) as $H as Limb
2768                     });
2769                     quotient.copy_from_slice(dividend);
2770
2771                     return lost_fraction(&[(rem as Limb) << 1], &[divisor as Limb]);
2772                 }
2773             }
2774         }
2775
2776         try_short_div!(u32, u16, 16);
2777         try_short_div!(u64, u32, 32);
2778         try_short_div!(u128, u64, 64);
2779
2780         // Zero the quotient before setting bits in it.
2781         for x in &mut quotient[..limbs_for_bits(precision)] {
2782             *x = 0;
2783         }
2784
2785         // Long division.
2786         for bit in (0..precision).rev() {
2787             if cmp(dividend, divisor) != Ordering::Less {
2788                 sub(dividend, divisor, 0);
2789                 set_bit(quotient, bit);
2790             }
2791             shift_left(dividend, &mut 0, 1);
2792         }
2793
2794         lost_fraction(dividend, divisor)
2795     }
2796 }