1 use std::{ ops, fmt, f32, f64 };
2 use std::convert::{TryFrom, Infallible};
3 use std::num::{FpCategory, TryFromIntError};
4 use crate::util::grisu2;
5 use crate::util::print_dec;
6
7 /// NaN value represented in `Number` type. NaN is equal to itself.
8 pub const NAN: Number = Number {
9 category: NAN_MASK,
10 mantissa: 0,
11 exponent: 0
12 };
13
14 const NEGATIVE: u8 = 0;
15 const POSITIVE: u8 = 1;
16 const NAN_MASK: u8 = !1;
17
18 /// Number representation used inside `JsonValue`. You can easily convert
19 /// the `Number` type into native Rust number types and back, or use the
20 /// equality operator with another number type.
21 ///
22 /// ```
23 /// # use json::number::Number;
24 /// let foo: Number = 3.14.into();
25 /// let bar: f64 = foo.into();
26 ///
27 /// assert_eq!(foo, 3.14);
28 /// assert_eq!(bar, 3.14);
29 /// ```
30 ///
31 /// More often than not you will deal with `JsonValue::Number` variant that
32 /// wraps around this type, instead of using the methods here directly.
33 #[derive(Copy, Clone, Debug)]
34 pub struct Number {
35 // A byte describing the sign and NaN-ness of the number.
36 //
37 // category == 0 (NEGATIVE constant) -> negative sign
38 // category == 1 (POSITIVE constant) -> positive sign
39 // category > 1 (matches NAN_MASK constant) -> NaN
40 category: u8,
41
42 // Decimal exponent, analog to `e` notation in string form.
43 exponent: i16,
44
45 // Integer base before sing and exponent applied.
46 mantissa: u64,
47 }
48
49 impl Number {
50 /// Construct a new `Number` from parts. This can't create a NaN value.
51 ///
52 /// ```
53 /// # use json::number::Number;
54 /// let pi = unsafe { Number::from_parts_unchecked(true, 3141592653589793, -15) };
55 ///
56 /// assert_eq!(pi, 3.141592653589793);
57 /// ```
58 ///
59 /// While this method is marked unsafe, it doesn't actually perform any unsafe operations.
60 /// THe goal of the 'unsafe' is to deter from using this method in favor of its safe equivalent
61 /// `from_parts`, at least in context when the associated performance cost is negligible.
62 #[inline]
from_parts_unchecked(positive: bool, mantissa: u64, exponent: i16) -> Self63 pub unsafe fn from_parts_unchecked(positive: bool, mantissa: u64, exponent: i16) -> Self {
64 Number {
65 category: positive as u8,
66 exponent: exponent,
67 mantissa: mantissa,
68 }
69 }
70
71 /// Construct a new `Number` from parts, stripping unnecessary trailing zeroes.
72 /// This can't create a NaN value.
73 ///
74 /// ```
75 /// # use json::number::Number;
76 /// let one = Number::from_parts(true, 1000, -3);
77 /// let (positive, mantissa, exponent) = one.as_parts();
78 ///
79 /// assert_eq!(true, positive);
80 /// assert_eq!(1, mantissa);
81 /// assert_eq!(0, exponent);
82 /// ```
83 #[inline]
from_parts(positive: bool, mut mantissa: u64, mut exponent: i16) -> Self84 pub fn from_parts(positive: bool, mut mantissa: u64, mut exponent: i16) -> Self {
85 while exponent < 0 && mantissa % 10 == 0 {
86 exponent += 1;
87 mantissa /= 10;
88 }
89 unsafe { Number::from_parts_unchecked(positive, mantissa, exponent) }
90 }
91
92 /// Reverse to `from_parts` - obtain parts from an existing `Number`.
93 ///
94 /// ```
95 /// # use json::number::Number;
96 /// let pi = Number::from(3.141592653589793);
97 /// let (positive, mantissa, exponent) = pi.as_parts();
98 ///
99 /// assert_eq!(positive, true);
100 /// assert_eq!(mantissa, 3141592653589793);
101 /// assert_eq!(exponent, -15);
102 /// ```
103 #[inline]
as_parts(&self) -> (bool, u64, i16)104 pub fn as_parts(&self) -> (bool, u64, i16) {
105 (self.category == POSITIVE, self.mantissa, self.exponent)
106 }
107
108 #[inline]
is_sign_positive(&self) -> bool109 pub fn is_sign_positive(&self) -> bool {
110 self.category == POSITIVE
111 }
112
113 #[inline]
is_zero(&self) -> bool114 pub fn is_zero(&self) -> bool {
115 self.mantissa == 0 && !self.is_nan()
116 }
117
118 #[inline]
is_nan(&self) -> bool119 pub fn is_nan(&self) -> bool {
120 self.category & NAN_MASK != 0
121 }
122
123 /// Test if the number is NaN or has a zero value.
124 #[inline]
is_empty(&self) -> bool125 pub fn is_empty(&self) -> bool {
126 self.mantissa == 0 || self.is_nan()
127 }
128
129 /// Obtain an integer at a fixed decimal point. This is useful for
130 /// converting monetary values and doing arithmetic on them without
131 /// rounding errors introduced by floating point operations.
132 ///
133 /// Will return `None` if `Number` is negative or a NaN.
134 ///
135 /// ```
136 /// # use json::number::Number;
137 /// let price_a = Number::from(5.99);
138 /// let price_b = Number::from(7);
139 /// let price_c = Number::from(10.2);
140 ///
141 /// assert_eq!(price_a.as_fixed_point_u64(2), Some(599));
142 /// assert_eq!(price_b.as_fixed_point_u64(2), Some(700));
143 /// assert_eq!(price_c.as_fixed_point_u64(2), Some(1020));
144 /// ```
as_fixed_point_u64(&self, point: u16) -> Option<u64>145 pub fn as_fixed_point_u64(&self, point: u16) -> Option<u64> {
146 if self.category != POSITIVE {
147 return None;
148 }
149
150 let e_diff = point as i16 + self.exponent;
151
152 Some(if e_diff == 0 {
153 self.mantissa
154 } else if e_diff < 0 {
155 self.mantissa.wrapping_div(decimal_power(-e_diff as u16))
156 } else {
157 self.mantissa.wrapping_mul(decimal_power(e_diff as u16))
158 })
159 }
160
161 /// Analog to `as_fixed_point_u64`, except returning a signed
162 /// `i64`, properly handling negative numbers.
163 ///
164 /// ```
165 /// # use json::number::Number;
166 /// let balance_a = Number::from(-1.49);
167 /// let balance_b = Number::from(42);
168 ///
169 /// assert_eq!(balance_a.as_fixed_point_i64(2), Some(-149));
170 /// assert_eq!(balance_b.as_fixed_point_i64(2), Some(4200));
171 /// ```
as_fixed_point_i64(&self, point: u16) -> Option<i64>172 pub fn as_fixed_point_i64(&self, point: u16) -> Option<i64> {
173 if self.is_nan() {
174 return None;
175 }
176
177 let num = if self.is_sign_positive() {
178 self.mantissa as i64
179 } else {
180 -(self.mantissa as i64)
181 };
182
183 let e_diff = point as i16 + self.exponent;
184
185 Some(if e_diff == 0 {
186 num
187 } else if e_diff < 0 {
188 num.wrapping_div(decimal_power(-e_diff as u16) as i64)
189 } else {
190 num.wrapping_mul(decimal_power(e_diff as u16) as i64)
191 })
192 }
193 }
194
195 impl PartialEq for Number {
196 #[inline]
eq(&self, other: &Number) -> bool197 fn eq(&self, other: &Number) -> bool {
198 if self.is_zero() && other.is_zero()
199 || self.is_nan() && other.is_nan() {
200 return true;
201 }
202
203 if self.category != other.category {
204 return false;
205 }
206
207 let e_diff = self.exponent - other.exponent;
208
209 if e_diff == 0 {
210 return self.mantissa == other.mantissa;
211 } else if e_diff > 0 {
212 let power = decimal_power(e_diff as u16);
213
214 self.mantissa.wrapping_mul(power) == other.mantissa
215 } else {
216 let power = decimal_power(-e_diff as u16);
217
218 self.mantissa == other.mantissa.wrapping_mul(power)
219 }
220
221 }
222 }
223
224 impl fmt::Display for Number {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result225 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
226 unsafe {
227 if self.is_nan() {
228 return f.write_str("nan")
229 }
230 let (positive, mantissa, exponent) = self.as_parts();
231 let mut buf = Vec::new();
232 print_dec::write(&mut buf, positive, mantissa, exponent).unwrap();
233 f.write_str(&String::from_utf8_unchecked(buf))
234 }
235 }
236 }
237
exponentiate_f64(n: f64, e: i16) -> f64238 fn exponentiate_f64(n: f64, e: i16) -> f64 {
239 static CACHE_POWERS: [f64; 23] = [
240 1.0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7,
241 1e8, 1e9, 1e10, 1e11, 1e12, 1e13, 1e14, 1e15,
242 1e16, 1e17, 1e18, 1e19, 1e20, 1e21, 1e22
243 ];
244
245 if e >= 0 {
246 let index = e as usize;
247
248 n * if index < 23 {
249 CACHE_POWERS[index]
250 } else {
251 10f64.powf(index as f64)
252 }
253 } else {
254 let index = -e as usize;
255
256 n / if index < 23 {
257 CACHE_POWERS[index]
258 } else {
259 10f64.powf(index as f64)
260 }
261 }
262 }
263
264
exponentiate_f32(n: f32, e: i16) -> f32265 fn exponentiate_f32(n: f32, e: i16) -> f32 {
266 static CACHE_POWERS: [f32; 23] = [
267 1.0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7,
268 1e8, 1e9, 1e10, 1e11, 1e12, 1e13, 1e14, 1e15,
269 1e16, 1e17, 1e18, 1e19, 1e20, 1e21, 1e22
270 ];
271
272 if e >= 0 {
273 let index = e as usize;
274
275 n * if index < 23 {
276 CACHE_POWERS[index]
277 } else {
278 10f32.powf(index as f32)
279 }
280 } else {
281 let index = -e as usize;
282
283 n / if index < 23 {
284 CACHE_POWERS[index]
285 } else {
286 10f32.powf(index as f32)
287 }
288 }
289 }
290
291 impl From<Number> for f64 {
from(num: Number) -> f64292 fn from(num: Number) -> f64 {
293 if num.is_nan() { return f64::NAN; }
294
295 let mut n = num.mantissa as f64;
296 let mut e = num.exponent;
297
298 if e < -308 {
299 n = exponentiate_f64(n, e + 308);
300 e = -308;
301 }
302
303 let f = exponentiate_f64(n, e);
304 if num.is_sign_positive() { f } else { -f }
305 }
306 }
307
308 impl From<Number> for f32 {
from(num: Number) -> f32309 fn from(num: Number) -> f32 {
310 if num.is_nan() { return f32::NAN; }
311
312 let mut n = num.mantissa as f32;
313 let mut e = num.exponent;
314
315 if e < -127 {
316 n = exponentiate_f32(n, e + 127);
317 e = -127;
318 }
319
320 let f = exponentiate_f32(n, e);
321 if num.is_sign_positive() { f } else { -f }
322 }
323 }
324
325 impl From<f64> for Number {
from(float: f64) -> Number326 fn from(float: f64) -> Number {
327 match float.classify() {
328 FpCategory::Infinite | FpCategory::Nan => return NAN,
329 _ => {}
330 }
331
332 if !float.is_sign_positive() {
333 let (mantissa, exponent) = grisu2::convert(-float);
334
335 Number::from_parts(false, mantissa, exponent)
336 } else {
337 let (mantissa, exponent) = grisu2::convert(float);
338
339 Number::from_parts(true, mantissa, exponent)
340 }
341 }
342 }
343
344 impl From<f32> for Number {
from(float: f32) -> Number345 fn from(float: f32) -> Number {
346 match float.classify() {
347 FpCategory::Infinite | FpCategory::Nan => return NAN,
348 _ => {}
349 }
350
351 if !float.is_sign_positive() {
352 let (mantissa, exponent) = grisu2::convert(-float as f64);
353
354 Number::from_parts(false, mantissa, exponent)
355 } else {
356 let (mantissa, exponent) = grisu2::convert(float as f64);
357
358 Number::from_parts(true, mantissa, exponent)
359 }
360 }
361 }
362
363 impl PartialEq<f64> for Number {
eq(&self, other: &f64) -> bool364 fn eq(&self, other: &f64) -> bool {
365 f64::from(*self) == *other
366 }
367 }
368
369 impl PartialEq<f32> for Number {
eq(&self, other: &f32) -> bool370 fn eq(&self, other: &f32) -> bool {
371 f32::from(*self) == *other
372 }
373 }
374
375 impl PartialEq<Number> for f64 {
eq(&self, other: &Number) -> bool376 fn eq(&self, other: &Number) -> bool {
377 f64::from(*other) == *self
378 }
379 }
380
381 impl PartialEq<Number> for f32 {
eq(&self, other: &Number) -> bool382 fn eq(&self, other: &Number) -> bool {
383 f32::from(*other) == *self
384 }
385 }
386
387 /// Error type generated when trying to convert a `Number` into an
388 /// integer of inadequate size.
389 #[derive(Clone, Copy)]
390 pub struct NumberOutOfScope;
391
392 impl From<Infallible> for NumberOutOfScope {
from(_: Infallible) -> NumberOutOfScope393 fn from(_: Infallible) -> NumberOutOfScope {
394 NumberOutOfScope
395 }
396 }
397
398 impl From<TryFromIntError> for NumberOutOfScope {
from(_: TryFromIntError) -> NumberOutOfScope399 fn from(_: TryFromIntError) -> NumberOutOfScope {
400 NumberOutOfScope
401 }
402 }
403
404 macro_rules! impl_unsigned {
405 ($( $t:ty ),*) => ($(
406 impl From<$t> for Number {
407 #[inline]
408 fn from(num: $t) -> Number {
409 Number {
410 category: POSITIVE,
411 exponent: 0,
412 mantissa: num as u64,
413 }
414 }
415 }
416
417 impl TryFrom<Number> for $t {
418 type Error = NumberOutOfScope;
419
420 fn try_from(num: Number) -> Result<Self, Self::Error> {
421 let (positive, mantissa, exponent) = num.as_parts();
422
423 if !positive || exponent != 0 {
424 return Err(NumberOutOfScope);
425 }
426
427 TryFrom::try_from(mantissa).map_err(Into::into)
428 }
429 }
430
431 impl_integer!($t);
432 )*)
433 }
434
435 macro_rules! impl_signed {
436 ($( $t:ty ),*) => ($(
437 impl From<$t> for Number {
438 fn from(num: $t) -> Number {
439 if num < 0 {
440 Number {
441 category: NEGATIVE,
442 exponent: 0,
443 mantissa: -num as u64,
444 }
445 } else {
446 Number {
447 category: POSITIVE,
448 exponent: 0,
449 mantissa: num as u64,
450 }
451 }
452 }
453 }
454
455 impl TryFrom<Number> for $t {
456 type Error = NumberOutOfScope;
457
458 fn try_from(num: Number) -> Result<Self, Self::Error> {
459 let (positive, mantissa, exponent) = num.as_parts();
460
461 if exponent != 0 {
462 return Err(NumberOutOfScope);
463 }
464
465 let mantissa = if positive {
466 mantissa as i64
467 } else {
468 -(mantissa as i64)
469 };
470
471 TryFrom::try_from(mantissa).map_err(Into::into)
472 }
473 }
474
475 impl_integer!($t);
476 )*)
477 }
478
479 macro_rules! impl_integer {
480 ($t:ty) => {
481 impl PartialEq<$t> for Number {
482 fn eq(&self, other: &$t) -> bool {
483 *self == Number::from(*other)
484 }
485 }
486
487 impl PartialEq<Number> for $t {
488 fn eq(&self, other: &Number) -> bool {
489 Number::from(*self) == *other
490 }
491 }
492 }
493 }
494
495 impl_signed!(isize, i8, i16, i32, i64);
496 impl_unsigned!(usize, u8, u16, u32, u64);
497
498 impl ops::Neg for Number {
499 type Output = Number;
500
501 #[inline]
neg(self) -> Number502 fn neg(self) -> Number {
503 Number {
504 category: self.category ^ POSITIVE,
505 exponent: self.exponent,
506 mantissa: self.mantissa,
507 }
508 }
509 }
510
511 // Commented out for now - not doing math ops for 0.10.0
512 // -----------------------------------------------------
513 //
514 // impl ops::Mul for Number {
515 // type Output = Number;
516
517 // #[inline]
518 // fn mul(self, other: Number) -> Number {
519 // // If either is a NaN, return a NaN
520 // if (self.category | other.category) & NAN_MASK != 0 {
521 // NAN
522 // } else {
523 // Number {
524 // // If both signs are the same, xoring will produce 0.
525 // // If they are different, xoring will produce 1.
526 // // Xor again with 1 to get a proper proper sign!
527 // // Xor all the things! ^ _ ^
528
529 // category: self.category ^ other.category ^ POSITIVE,
530 // exponent: self.exponent + other.exponent,
531 // mantissa: self.mantissa * other.mantissa,
532 // }
533 // }
534 // }
535 // }
536
537 // impl ops::MulAssign for Number {
538 // #[inline]
539 // fn mul_assign(&mut self, other: Number) {
540 // *self = *self * other;
541 // }
542 // }
543
544 #[inline]
decimal_power(mut e: u16) -> u64545 fn decimal_power(mut e: u16) -> u64 {
546 static CACHED: [u64; 20] = [
547 1,
548 10,
549 100,
550 1000,
551 10000,
552 100000,
553 1000000,
554 10000000,
555 100000000,
556 1000000000,
557 10000000000,
558 100000000000,
559 1000000000000,
560 10000000000000,
561 100000000000000,
562 1000000000000000,
563 10000000000000000,
564 100000000000000000,
565 1000000000000000000,
566 10000000000000000000,
567 ];
568
569 if e < 20 {
570 CACHED[e as usize]
571 } else {
572 let mut pow = 1u64;
573 while e >= 20 {
574 pow = pow.saturating_mul(CACHED[(e % 20) as usize]);
575 e /= 20;
576 }
577
578 pow
579 }
580 }
581