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