1use crate::decimal::{Decimal, Fraction};
34
35#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
37pub enum Format {
38 Half,
40 BFloat16,
43 Single,
45 Double,
47 X87Extended,
50 Quad,
53}
54
55impl Format {
56 #[must_use]
58 pub const fn precision(self) -> u32 {
59 match self {
60 Format::Half => 11,
61 Format::BFloat16 => 8,
62 Format::Single => 24,
63 Format::Double => 53,
64 Format::X87Extended => 64,
65 Format::Quad => 113,
66 }
67 }
68
69 #[must_use]
71 pub const fn max_exponent(self) -> i32 {
72 match self {
73 Format::Half => 15,
74 Format::BFloat16 | Format::Single => 127,
75 Format::Double => 1023,
76 Format::X87Extended | Format::Quad => 16383,
77 }
78 }
79
80 #[must_use]
82 pub const fn min_exponent(self) -> i32 {
83 1 - self.max_exponent()
84 }
85
86 #[must_use]
89 pub const fn width(self) -> u32 {
90 match self {
91 Format::Half | Format::BFloat16 => 16,
92 Format::Single => 32,
93 Format::Double => 64,
94 Format::X87Extended => 80,
95 Format::Quad => 128,
96 }
97 }
98
99 #[must_use]
101 pub const fn has_explicit_integer_bit(self) -> bool {
102 matches!(self, Format::X87Extended)
103 }
104
105 const fn exponent_bits(self) -> u32 {
107 self.width() - self.significand_bits() - 1
108 }
109
110 const fn significand_bits(self) -> u32 {
112 if self.has_explicit_integer_bit() { self.precision() } else { self.precision() - 1 }
113 }
114
115 const fn max_decimal_exponent(self) -> i32 {
121 (self.max_exponent() + 1) * 30103 / 100000 + 2
122 }
123
124 const fn min_decimal_exponent(self) -> i32 {
126 (self.min_exponent() - self.precision() as i32) * 30103 / 100000 - 2
127 }
128}
129
130#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
136pub struct Status(u8);
137
138impl Status {
139 pub const NONE: Status = Status(0);
141 pub const INEXACT: Status = Status(1);
143 pub const OVERFLOW: Status = Status(2);
145 pub const UNDERFLOW: Status = Status(4);
147
148 #[inline]
150 #[must_use]
151 pub const fn has(self, other: Status) -> bool {
152 self.0 & other.0 == other.0
153 }
154
155 #[inline]
157 #[must_use]
158 pub const fn with(self, other: Status) -> Status {
159 Status(self.0 | other.0)
160 }
161
162 #[inline]
164 #[must_use]
165 pub const fn is_none(self) -> bool {
166 self.0 == 0
167 }
168}
169
170#[derive(Debug, Clone, Copy, PartialEq, Eq)]
175pub enum ParseError {
176 NoDigits,
178 NoExponentDigits,
180 Invalid,
182}
183
184#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
186enum Category {
187 Zero,
188 Finite,
189 Infinite,
190}
191
192#[derive(Debug, Clone, Copy, PartialEq, Eq)]
197pub struct Float {
198 format: Format,
199 category: Category,
200 sign: bool,
201 exponent: i32,
202 significand: u128,
203}
204
205impl Float {
206 #[must_use]
208 pub const fn zero(format: Format, sign: bool) -> Float {
209 Float { format, category: Category::Zero, sign, exponent: 0, significand: 0 }
210 }
211
212 #[must_use]
214 pub const fn infinity(format: Format, sign: bool) -> Float {
215 Float { format, category: Category::Infinite, sign, exponent: 0, significand: 0 }
216 }
217
218 #[must_use]
220 pub const fn format(self) -> Format {
221 self.format
222 }
223
224 #[must_use]
226 pub const fn is_negative(self) -> bool {
227 self.sign
228 }
229
230 #[must_use]
232 pub const fn is_zero(self) -> bool {
233 matches!(self.category, Category::Zero)
234 }
235
236 #[must_use]
238 pub const fn is_infinite(self) -> bool {
239 matches!(self.category, Category::Infinite)
240 }
241
242 #[must_use]
244 pub const fn is_finite(self) -> bool {
245 !self.is_infinite()
246 }
247
248 pub fn parse(text: &str, format: Format) -> Result<(Float, Status), ParseError> {
260 let bytes = text.as_bytes();
261 let (sign, rest) = match bytes.first() {
262 Some(b'-') => (true, &bytes[1..]),
263 Some(b'+') => (false, &bytes[1..]),
264 _ => (false, bytes),
265 };
266 if rest.len() > 1 && rest[0] == b'0' && rest[1] | 32 == b'x' {
267 hexadecimal(&rest[2..], sign, format)
268 } else {
269 decimal(rest, sign, format)
270 }
271 }
272
273 #[must_use]
278 pub fn to_bits(self) -> u128 {
279 let format = self.format;
280 let significand_mask = (1u128 << format.significand_bits()) - 1;
281 let (exponent_field, significand_field) = match self.category {
282 Category::Zero => (0, 0),
283 Category::Infinite => (
284 (1u128 << format.exponent_bits()) - 1,
285 if format.has_explicit_integer_bit() {
286 1u128 << (format.precision() - 1)
287 } else {
288 0
289 },
290 ),
291 Category::Finite => {
292 let subnormal = self.significand >> (format.precision() - 1) == 0;
293 let field =
294 if subnormal { 0 } else { (self.exponent + format.max_exponent()) as u128 };
295 (field, self.significand & significand_mask)
296 }
297 };
298 let sign = u128::from(self.sign) << (format.width() - 1);
299 sign | (exponent_field << format.significand_bits()) | significand_field
300 }
301
302 #[must_use]
308 pub fn from_bits(format: Format, bits: u128) -> Float {
309 let significand_bits = format.significand_bits();
310 let sign = (bits >> (format.width() - 1)) & 1 == 1;
311 let exponent_field =
312 ((bits >> significand_bits) & ((1u128 << format.exponent_bits()) - 1)) as i32;
313 let stored = bits & ((1u128 << significand_bits) - 1);
314 if exponent_field == (1 << format.exponent_bits()) - 1 {
315 return Float::infinity(format, sign);
316 }
317 let implicit = if format.has_explicit_integer_bit() || exponent_field == 0 {
318 0
319 } else {
320 1u128 << (format.precision() - 1)
321 };
322 let significand = stored | implicit;
323 if significand == 0 {
324 return Float::zero(format, sign);
325 }
326 let exponent = if exponent_field == 0 {
327 format.min_exponent()
328 } else {
329 exponent_field - format.max_exponent()
330 };
331 Float { format, category: Category::Finite, sign, exponent, significand }
332 }
333}
334
335fn decimal(bytes: &[u8], sign: bool, format: Format) -> Result<(Float, Status), ParseError> {
337 let mut digits = Vec::new();
338 let mut integer_digits = 0i32;
339 let mut seen_point = false;
340 let mut seen_digit = false;
341 let mut index = 0;
342 while index < bytes.len() {
343 match bytes[index] {
344 byte @ b'0'..=b'9' => {
345 digits.push(byte - b'0');
346 if !seen_point {
347 integer_digits += 1;
348 }
349 seen_digit = true;
350 }
351 b'\'' => {}
352 b'.' if !seen_point => seen_point = true,
353 b'e' | b'E' => break,
354 _ => return Err(ParseError::Invalid),
355 }
356 index += 1;
357 }
358 if !seen_digit {
359 return Err(ParseError::NoDigits);
360 }
361 let mut point = integer_digits;
362 if index < bytes.len() {
363 point = point.saturating_add(exponent_of(&bytes[index + 1..])?);
364 }
365 Ok(convert(Decimal::new(digits, point), sign, format))
366}
367
368fn hexadecimal(bytes: &[u8], sign: bool, format: Format) -> Result<(Float, Status), ParseError> {
370 let mut significand: u128 = 0;
371 let mut exponent = 0i32;
372 let mut sticky = false;
373 let mut seen_point = false;
374 let mut seen_digit = false;
375 let mut index = 0;
376 while index < bytes.len() {
377 let byte = bytes[index];
378 let digit = match byte {
379 b'0'..=b'9' => byte - b'0',
380 b'a'..=b'f' => byte - b'a' + 10,
381 b'A'..=b'F' => byte - b'A' + 10,
382 b'\'' => {
383 index += 1;
384 continue;
385 }
386 b'.' if !seen_point => {
387 seen_point = true;
388 index += 1;
389 continue;
390 }
391 b'p' | b'P' => break,
392 _ => return Err(ParseError::Invalid),
393 };
394 seen_digit = true;
395 if significand.leading_zeros() >= 4 {
396 significand = (significand << 4) | u128::from(digit);
397 if seen_point {
398 exponent -= 4;
399 }
400 } else {
401 sticky |= digit != 0;
404 if !seen_point {
405 exponent += 4;
406 }
407 }
408 index += 1;
409 }
410 if !seen_digit {
411 return Err(ParseError::NoDigits);
412 }
413 if index < bytes.len() {
414 exponent = exponent.saturating_add(exponent_of(&bytes[index + 1..])?);
415 }
416 Ok(round(significand, exponent, sticky, sign, format))
417}
418
419fn exponent_of(bytes: &[u8]) -> Result<i32, ParseError> {
421 let (negative, digits) = match bytes.first() {
422 Some(b'-') => (true, &bytes[1..]),
423 Some(b'+') => (false, &bytes[1..]),
424 _ => (false, bytes),
425 };
426 if digits.is_empty() {
427 return Err(ParseError::NoExponentDigits);
428 }
429 let mut value = 0i32;
430 for &byte in digits {
431 if byte == b'\'' {
432 continue;
433 }
434 if !byte.is_ascii_digit() {
435 return Err(ParseError::Invalid);
436 }
437 value = value.saturating_mul(10).saturating_add(i32::from(byte - b'0'));
440 }
441 Ok(if negative { -value } else { value })
442}
443
444fn convert(mut value: Decimal, sign: bool, format: Format) -> (Float, Status) {
446 if value.is_zero() {
447 return (Float::zero(format, sign), Status::NONE);
448 }
449 if value.point() > format.max_decimal_exponent() {
450 return (Float::infinity(format, sign), Status::OVERFLOW.with(Status::INEXACT));
451 }
452 if value.point() < format.min_decimal_exponent() {
453 return (Float::zero(format, sign), Status::UNDERFLOW.with(Status::INEXACT));
454 }
455
456 let mut exponent = 0i32;
460 loop {
461 let point = value.point();
462 if point > 1 || (point == 1 && value.first_digit() >= 2) {
463 let step = binary_digits(point - 1).clamp(1, 60);
464 value.shift(-step);
465 exponent += step;
466 } else if point < 1 {
467 let step = (1 + binary_digits(-point)).clamp(1, 60);
468 value.shift(step);
469 exponent -= step;
470 } else {
471 break;
472 }
473 }
474
475 let precision = format.precision() as i32;
478 let scale = (exponent - precision + 1).max(format.min_exponent() - precision + 1);
479 value.shift(exponent - scale);
480 let (integer, fraction) = value.round_to_u128();
481 let rounded = match fraction {
482 Fraction::Zero | Fraction::BelowHalf => integer,
483 Fraction::Half => integer + (integer & 1),
484 Fraction::AboveHalf => integer + 1,
485 };
486 finish(rounded, scale, fraction != Fraction::Zero, sign, format)
487}
488
489const fn binary_digits(decimal: i32) -> i32 {
491 decimal * 33219 / 10000
492}
493
494fn round(
497 significand: u128,
498 exponent: i32,
499 sticky: bool,
500 sign: bool,
501 format: Format,
502) -> (Float, Status) {
503 if significand == 0 {
504 return (Float::zero(format, sign), Status::NONE);
505 }
506 let precision = format.precision() as i32;
507 let leading = (128 - significand.leading_zeros()) as i32;
508 let scale = (exponent + leading - precision).max(format.min_exponent() - precision + 1);
509 let mut sticky = sticky;
510 let (integer, half) = if scale <= exponent {
511 (significand << (exponent - scale), false)
512 } else {
513 let drop = (scale - exponent) as u32;
514 if drop >= 128 {
515 sticky = true;
516 (0, false)
517 } else {
518 let half = (significand >> (drop - 1)) & 1 == 1;
519 sticky |= drop > 1 && significand & ((1u128 << (drop - 1)) - 1) != 0;
520 (significand >> drop, half)
521 }
522 };
523 let rounded = if half && (sticky || integer & 1 == 1) { integer + 1 } else { integer };
524 finish(rounded, scale, half || sticky, sign, format)
525}
526
527fn finish(
530 significand: u128,
531 scale: i32,
532 inexact: bool,
533 sign: bool,
534 format: Format,
535) -> (Float, Status) {
536 let precision = format.precision();
537 let mut significand = significand;
538 let mut scale = scale;
539 if significand >> precision != 0 {
540 significand >>= 1;
542 scale += 1;
543 }
544 let mut status = if inexact { Status::INEXACT } else { Status::NONE };
545 if significand == 0 {
546 return (Float::zero(format, sign), status.with(Status::UNDERFLOW));
547 }
548 let exponent = scale + precision as i32 - 1;
549 if exponent > format.max_exponent() {
550 return (
551 Float::infinity(format, sign),
552 status.with(Status::OVERFLOW).with(Status::INEXACT),
553 );
554 }
555 let normal = significand >> (precision - 1) != 0;
556 if !normal && inexact {
557 status = status.with(Status::UNDERFLOW);
558 }
559 let exponent = if normal { exponent } else { format.min_exponent() };
560 (Float { format, category: Category::Finite, sign, exponent, significand }, status)
561}
562
563#[cfg(test)]
564mod tests {
565 use super::*;
566
567 fn double(text: &str) -> u128 {
569 Float::parse(text, Format::Double).expect("a number").0.to_bits()
570 }
571
572 fn single(text: &str) -> u128 {
574 Float::parse(text, Format::Single).expect("a number").0.to_bits()
575 }
576
577 #[test]
578 fn the_ordinary_numbers_land_where_the_host_would_put_them() {
579 for text in ["0", "1", "2", "0.5", "1.5", "3.14159", "2.718281828459045", "100", "1e10"] {
580 let host = text.parse::<f64>().expect("a number Rust reads too");
581 assert_eq!(double(text), u128::from(host.to_bits()), "{text}");
582 }
583 }
584
585 #[test]
586 fn a_number_that_needs_the_last_bit_rounded_gets_it_right() {
587 let hard = [
590 "0.1",
591 "0.3",
592 "2.2250738585072011e-308",
593 "2.2250738585072014e-308",
594 "1.7976931348623157e308",
595 "4.9406564584124654e-324",
596 "5e-324",
597 "8.98846567431158e307",
598 "9007199254740993",
599 "123456789012345678901234567890",
600 "1.000000000000000000000000000000000000000000000000000000000000000001",
601 "7.8459735791271921e65",
602 "3.518437208883201171875e13",
603 "0.500000000000000166533453693773481063544750213623046875",
604 ];
605 for text in hard {
606 let host = text.parse::<f64>().expect("a number Rust reads too");
607 assert_eq!(double(text), u128::from(host.to_bits()), "{text}");
608 }
609 }
610
611 #[test]
612 fn the_number_that_takes_seven_hundred_and_sixty_seven_digits() {
613 let text = concat!(
616 "2.47032822920623272088284396434110686182529901307162382",
617 "35378852574870103599108683372845652890455735483022221802",
618 "58573249056416711547735232764105795166208503595426876755",
619 "62317084535693494535245273750735013572761315046354601316",
620 "12127849863326369238975694273040488011871029093711789936",
621 "42245692702737764465109076580131048946378905599180391359",
622 "70011386455512221706120629864144453927884519445934871524",
623 "63344875888932891414823975864211858166195965106373837732",
624 "34435703331457550505022232309998195892058070506176382679",
625 "16323484472119097902806154870514036458498974142754747141",
626 "39683784321102080606305920253373777969877864922227306716",
627 "01324339457879181214233820577228206278891620001855078759",
628 "16278352090142077553206262229158550205643778244387017277",
629 "94459649305087139089301871550805125768938177360937844105",
630 "63661045147381814281647890691181239104545396303476425117",
631 "7562185422741845851144691421326303120484712594187004993e-324"
632 );
633 let host = text.parse::<f64>().expect("a number Rust reads too");
634 assert_eq!(double(text), u128::from(host.to_bits()));
635 }
636
637 #[test]
638 fn a_sweep_of_random_numbers_agrees_with_rust_in_every_bit() {
639 let mut state = 0x2545_f491_4f6c_dd1du64;
643 for _ in 0..4000 {
644 state = state.wrapping_mul(6364136223846793005).wrapping_add(1442695040888963407);
645 let digits = state >> 11;
646 let exponent = (state % 600) as i32 - 300;
647 let text = format!("{digits}e{exponent}");
648 let host = text.parse::<f64>().expect("a number Rust reads too");
649 assert_eq!(double(&text), u128::from(host.to_bits()), "{text}");
650 let host = text.parse::<f32>().expect("a number Rust reads too");
651 assert_eq!(single(&text), u128::from(host.to_bits()), "{text} as a float");
652 }
653 }
654
655 #[test]
656 fn the_ends_of_the_range_are_an_infinity_and_a_zero() {
657 let (value, status) = Float::parse("1e400", Format::Double).expect("a number");
658 assert!(value.is_infinite() && status.has(Status::OVERFLOW));
659 let (value, status) = Float::parse("1e-400", Format::Double).expect("a number");
660 assert!(value.is_zero() && status.has(Status::UNDERFLOW) && status.has(Status::INEXACT));
661 let (value, status) = Float::parse("1.7976931348623157e308", Format::Double).expect("one");
663 assert!(value.is_finite() && !status.has(Status::OVERFLOW));
664 let (value, _) = Float::parse("1.8e308", Format::Double).expect("a number");
665 assert!(value.is_infinite());
666 assert_eq!(double("2.4e-324"), u128::from((0f64).to_bits()));
668 assert_eq!(double("2.5e-324"), 1);
669 }
670
671 #[test]
672 fn a_number_that_is_exactly_what_was_written_says_so() {
673 assert!(Float::parse("1", Format::Double).expect("a number").1.is_none());
674 assert!(Float::parse("0.5", Format::Double).expect("a number").1.is_none());
675 assert!(Float::parse("0.1", Format::Double).expect("a number").1.has(Status::INEXACT));
676 let (_, status) = Float::parse("1e-320", Format::Double).expect("a number");
678 assert!(status.has(Status::INEXACT) && status.has(Status::UNDERFLOW));
679 }
680
681 #[test]
682 fn a_hexadecimal_constant_is_exact_and_needs_no_scaling() {
683 assert_eq!(double("0x1p0"), u128::from((1f64).to_bits()));
684 assert_eq!(double("0x1.8p1"), u128::from((3f64).to_bits()));
685 assert_eq!(double("0x1p-1074"), 1);
686 assert_eq!(double("0xa.bp-4"), u128::from((0.66796875f64).to_bits()));
687 assert_eq!(double("0X1.FFFFFFFFFFFFFP+1023"), u128::from(f64::MAX.to_bits()));
688 assert!(Float::parse("0x1p0", Format::Double).expect("a number").1.is_none());
689 let (_, status) = Float::parse("0x1.00000000000008p0", Format::Double).expect("a number");
691 assert!(status.has(Status::INEXACT));
692 assert_eq!(double("0x1.00000000000008p0"), u128::from((1f64).to_bits()));
693 assert_eq!(double("0x1.00000000000018p0"), u128::from((1f64).to_bits() + 2));
694 }
695
696 #[test]
697 fn digit_separators_are_not_part_of_the_number() {
698 assert_eq!(double("1'000.000'1"), double("1000.0001"));
699 assert_eq!(double("0x1'0p0"), double("16.0"));
700 assert_eq!(double("1e1'0"), double("1e10"));
701 }
702
703 #[test]
704 fn a_spelling_that_is_not_a_number_says_which_way_it_is_wrong() {
705 assert_eq!(Float::parse("", Format::Double), Err(ParseError::NoDigits));
706 assert_eq!(Float::parse(".", Format::Double), Err(ParseError::NoDigits));
707 assert_eq!(Float::parse("1e", Format::Double), Err(ParseError::NoExponentDigits));
708 assert_eq!(Float::parse("1e+", Format::Double), Err(ParseError::NoExponentDigits));
709 assert_eq!(Float::parse("0x1p", Format::Double), Err(ParseError::NoExponentDigits));
710 assert_eq!(Float::parse("0xp1", Format::Double), Err(ParseError::NoDigits));
711 assert_eq!(Float::parse("1x0", Format::Double), Err(ParseError::Invalid));
712 }
713
714 #[test]
715 fn a_sign_is_accepted_although_a_c_constant_never_has_one() {
716 let (value, _) = Float::parse("-1.5", Format::Double).expect("a number");
717 assert!(value.is_negative());
718 assert_eq!(value.to_bits(), u128::from((-1.5f64).to_bits()));
719 let (value, _) = Float::parse("-0.0", Format::Double).expect("a number");
720 assert!(value.is_zero() && value.is_negative());
721 assert_eq!(value.to_bits(), u128::from((-0.0f64).to_bits()));
722 }
723
724 #[test]
725 fn every_format_says_how_wide_its_fields_are() {
726 for format in [
727 Format::Half,
728 Format::BFloat16,
729 Format::Single,
730 Format::Double,
731 Format::X87Extended,
732 Format::Quad,
733 ] {
734 assert_eq!(
735 format.exponent_bits() + format.significand_bits() + 1,
736 format.width(),
737 "{format:?}"
738 );
739 assert_eq!(format.min_exponent(), 1 - format.max_exponent());
740 }
741 assert_eq!(Format::Half.exponent_bits(), 5);
742 assert_eq!(Format::BFloat16.exponent_bits(), 8);
743 assert_eq!(Format::Single.exponent_bits(), 8);
744 assert_eq!(Format::Double.exponent_bits(), 11);
745 assert_eq!(Format::X87Extended.exponent_bits(), 15);
746 assert_eq!(Format::Quad.exponent_bits(), 15);
747 }
748
749 #[test]
750 fn a_number_survives_a_trip_through_its_encoding() {
751 for format in [
752 Format::Half,
753 Format::BFloat16,
754 Format::Single,
755 Format::Double,
756 Format::X87Extended,
757 Format::Quad,
758 ] {
759 for text in ["0", "-0", "1", "-1.5", "3.14159", "1e-5", "65504", "0x1p-20"] {
760 let (value, _) = Float::parse(text, format).expect("a number");
761 let bits = value.to_bits();
762 assert_eq!(Float::from_bits(format, bits).to_bits(), bits, "{text} in {format:?}");
763 }
764 assert_eq!(
765 Float::from_bits(format, Float::infinity(format, false).to_bits()).to_bits(),
766 Float::infinity(format, false).to_bits()
767 );
768 }
769 }
770
771 #[test]
772 fn the_narrow_formats_round_where_they_are_supposed_to() {
773 let (value, status) = Float::parse("65504", Format::Half).expect("a number");
777 assert!(value.is_finite() && status.is_none());
778 assert_eq!(value.to_bits(), 0x7bff);
779 let (value, _) = Float::parse("65536", Format::Half).expect("a number");
780 assert!(value.is_infinite());
781 assert_eq!(Float::parse("1", Format::Half).expect("one").0.to_bits(), 0x3c00);
782 assert_eq!(Float::parse("1", Format::BFloat16).expect("one").0.to_bits(), 0x3f80);
783 assert_eq!(Float::parse("1e30", Format::BFloat16).expect("big").0.to_bits(), 0x714a);
784 assert_eq!(Float::parse("0x1p-24", Format::Half).expect("tiny").0.to_bits(), 1);
786 assert!(Float::parse("0x1p-26", Format::Half).expect("tinier").0.is_zero());
787 }
788
789 #[test]
790 fn the_x87_format_stores_the_bit_the_others_leave_implied() {
791 let one = Float::parse("1", Format::X87Extended).expect("one").0;
794 assert_eq!(one.to_bits(), 0x3fff_8000_0000_0000_0000);
795 assert_eq!(
796 Float::parse("2", Format::X87Extended).expect("two").0.to_bits(),
797 0x4000_8000_0000_0000_0000
798 );
799 let (value, status) = Float::parse("9007199254740993", Format::X87Extended).expect("one");
801 assert!(status.is_none());
802 assert_eq!(value.to_bits(), 0x4034_8000_0000_0000_0400);
803 assert_eq!(
806 Float::parse("0.1", Format::X87Extended).expect("a tenth").0.to_bits(),
807 0x3ffb_cccc_cccc_cccc_cccd
808 );
809 assert_eq!(Float::parse("1e-4950", Format::X87Extended).expect("tiny").0.to_bits(), 3);
812 }
813
814 #[test]
815 fn the_quad_format_has_a_hundred_and_thirteen_bits_of_it() {
816 assert_eq!(
817 Float::parse("1", Format::Quad).expect("one").0.to_bits(),
818 0x3fff_0000_0000_0000_0000_0000_0000_0000
819 );
820 assert_eq!(
822 Float::parse("0.1", Format::Quad).expect("a tenth").0.to_bits(),
823 0x3ffb_9999_9999_9999_9999_9999_9999_999a
824 );
825 assert_eq!(
827 Float::parse("3.14159", Format::Quad).expect("pi, roughly").0.to_bits(),
828 0x4000_921f_9f01_b866_e43a_a79b_badc_0981
829 );
830 let (value, status) = Float::parse("1e5000", Format::Quad).expect("a number");
831 assert!(value.is_infinite() && status.has(Status::OVERFLOW));
832 let (value, _) = Float::parse("1e-5000", Format::Quad).expect("a number");
833 assert!(value.is_zero());
834 }
835}