|
1 | | -use dashu_float::DBig; |
| 1 | +use core::str::FromStr; |
| 2 | + |
| 3 | +use dashu_base::{Approximation::*, ParseError}; |
| 4 | +use dashu_float::{round::Rounding::NoOp, DBig}; |
2 | 5 |
|
3 | 6 | mod helper_macros; |
4 | 7 |
|
@@ -124,6 +127,39 @@ fn test_trunc_fract() { |
124 | 127 | assert_eq!(dbig!(12e-2).fract().precision(), 2); |
125 | 128 | } |
126 | 129 |
|
| 130 | +/// Numbers with |self| < 1 can be stored with a single significand digit and a |
| 131 | +/// negative exponent (e.g. 0.009 = 9e-3). Rounding must use `-exponent` as the |
| 132 | +/// fractional scale, not `context.precision`; otherwise 9 / 10^1 = 0.9 rounds up. |
| 133 | +#[test] |
| 134 | +fn test_round_smaller_than_one_uses_exponent_scale() -> Result<(), ParseError> { |
| 135 | + let a = DBig::from_str("0.009")?.with_precision(1).unwrap(); |
| 136 | + assert_eq!(a.round(), DBig::ZERO); |
| 137 | + |
| 138 | + let b = DBig::from_str("0.09")?.with_precision(1).unwrap(); |
| 139 | + assert_eq!(b.round(), DBig::ZERO); |
| 140 | + |
| 141 | + let c = DBig::from_str("1e-5")?.with_precision(3).unwrap(); |
| 142 | + assert_eq!(c.round(), DBig::ZERO); |
| 143 | + assert_eq!(c.to_int(), Inexact(ibig!(0), NoOp)); |
| 144 | + |
| 145 | + Ok(()) |
| 146 | +} |
| 147 | + |
| 148 | +/// `.fract()` must not inflate context precision to `-exponent` when trailing |
| 149 | +/// zeros were normalized away from the significand. |
| 150 | +#[test] |
| 151 | +fn test_fract_preserves_context_precision() -> Result<(), ParseError> { |
| 152 | + let a = DBig::from_str("1e-5")?.with_precision(3).unwrap(); |
| 153 | + assert_eq!(a.fract(), a); |
| 154 | + assert_eq!(a.fract().precision(), 3); |
| 155 | + |
| 156 | + let b = DBig::from_str("9e-5")?.with_precision(1).unwrap(); |
| 157 | + assert_eq!(b.fract(), b); |
| 158 | + assert_eq!(b.fract().precision(), 1); |
| 159 | + |
| 160 | + Ok(()) |
| 161 | +} |
| 162 | + |
127 | 163 | #[test] |
128 | 164 | #[should_panic] |
129 | 165 | fn test_floor_inf() { |
|
0 commit comments