@@ -34,7 +34,7 @@ pub use paste;
3434#[ cfg( feature = "std" ) ]
3535pub use runtime_io:: { StorageOverlay , ChildrenStorageOverlay } ;
3636
37- use rstd:: { prelude:: * , ops} ;
37+ use rstd:: { prelude:: * , ops, convert :: TryInto } ;
3838use substrate_primitives:: { crypto, ed25519, sr25519, hash:: { H256 , H512 } } ;
3939use codec:: { Encode , Decode } ;
4040
@@ -43,7 +43,7 @@ pub mod testing;
4343
4444pub mod weights;
4545pub mod traits;
46- use traits:: { SaturatedConversion , UniqueSaturatedInto } ;
46+ use traits:: { SaturatedConversion , UniqueSaturatedInto , Saturating , Bounded , CheckedSub , CheckedAdd } ;
4747
4848pub mod generic;
4949pub mod transaction_validity;
@@ -168,7 +168,7 @@ impl BuildStorage for (StorageOverlay, ChildrenStorageOverlay) {
168168pub type ConsensusEngineId = [ u8 ; 4 ] ;
169169
170170/// Permill is parts-per-million (i.e. after multiplying by this, divide by 1000000).
171- #[ cfg_attr( feature = "std" , derive( Serialize , Deserialize , Debug ) ) ]
171+ #[ cfg_attr( feature = "std" , derive( Serialize , Deserialize , Debug , Ord , PartialOrd ) ) ]
172172#[ derive( Encode , Decode , Default , Copy , Clone , PartialEq , Eq ) ]
173173pub struct Permill ( u32 ) ;
174174
@@ -273,7 +273,7 @@ impl From<codec::Compact<Permill>> for Permill {
273273/// Perbill is parts-per-billion. It stores a value between 0 and 1 in fixed point and
274274/// provides a means to multiply some other value by that.
275275#[ cfg_attr( feature = "std" , derive( Serialize , Deserialize , Debug ) ) ]
276- #[ derive( Encode , Decode , Default , Copy , Clone , PartialEq , Eq ) ]
276+ #[ derive( Encode , Decode , Default , Copy , Clone , PartialEq , Eq , Ord , PartialOrd ) ]
277277pub struct Perbill ( u32 ) ;
278278
279279impl Perbill {
@@ -377,6 +377,128 @@ impl From<codec::Compact<Perbill>> for Perbill {
377377 }
378378}
379379
380+
381+ /// A fixed point number by the scale of 1 billion.
382+ ///
383+ /// cannot hold a value larger than +-`9223372036854775807 / 1_000_000_000` (~9 billion).
384+ #[ cfg_attr( feature = "std" , derive( Debug ) ) ]
385+ #[ derive( Encode , Decode , Default , Copy , Clone , PartialEq , Eq , PartialOrd , Ord ) ]
386+ pub struct Fixed64 ( i64 ) ;
387+
388+ /// The maximum value of the `Fixed64` type
389+ const DIV : i64 = 1_000_000_000 ;
390+
391+ impl Fixed64 {
392+ /// creates self from a natural number.
393+ ///
394+ /// Note that this might be lossy.
395+ pub fn from_natural ( int : i64 ) -> Self {
396+ Self ( int. saturating_mul ( DIV ) )
397+ }
398+
399+ /// Return the accuracy of the type. Given that this function returns the value `X`, it means
400+ /// that an instance composed of `X` parts (`Fixed64::from_parts(X)`) is equal to `1`.
401+ pub fn accuracy ( ) -> i64 {
402+ DIV
403+ }
404+
405+ /// creates self from a rational number. Equal to `n/d`.
406+ ///
407+ /// Note that this might be lossy.
408+ pub fn from_rational ( n : i64 , d : u64 ) -> Self {
409+ Self ( ( n as i128 * DIV as i128 / ( d as i128 ) . max ( 1 ) ) . try_into ( ) . unwrap_or ( Bounded :: max_value ( ) ) )
410+ }
411+
412+ /// Performs a saturated multiply and accumulate.
413+ ///
414+ /// Returns `n + (self * n)`.
415+ pub fn saturated_multiply_accumulate ( & self , int : u32 ) -> u32 {
416+ let parts = self . 0 ;
417+
418+ let positive = parts > 0 ;
419+ // natural parts might overflow.
420+ let natural_parts = self . clone ( ) . saturated_into :: < u32 > ( ) ;
421+ // fractional parts can always fit into u32.
422+ let perbill_parts = ( parts. abs ( ) % DIV ) as u32 ;
423+
424+ let n = int. saturating_mul ( natural_parts) ;
425+ let p = Perbill :: from_parts ( perbill_parts) * int;
426+ // everything that needs to be either added or subtracted from the original weight.
427+ let excess = n. saturating_add ( p) ;
428+
429+ if positive {
430+ int. saturating_add ( excess)
431+ } else {
432+ int. saturating_sub ( excess)
433+ }
434+ }
435+
436+ /// Raw constructor. Equal to `parts / 1_000_000_000`.
437+ pub fn from_parts ( parts : i64 ) -> Self {
438+ Self ( parts)
439+ }
440+ }
441+
442+ impl UniqueSaturatedInto < u32 > for Fixed64 {
443+ /// Note that the maximum value of Fixed64 might be more than what can fit in u32. This is hence,
444+ /// expected to be lossy.
445+ fn unique_saturated_into ( self ) -> u32 {
446+ ( self . 0 . abs ( ) / DIV ) . try_into ( ) . unwrap_or ( Bounded :: max_value ( ) )
447+ }
448+ }
449+
450+ impl Saturating for Fixed64 {
451+ fn saturating_add ( self , rhs : Self ) -> Self {
452+ Self ( self . 0 . saturating_add ( rhs. 0 ) )
453+ }
454+ fn saturating_mul ( self , rhs : Self ) -> Self {
455+ Self ( self . 0 . saturating_mul ( rhs. 0 ) / DIV )
456+ }
457+ fn saturating_sub ( self , rhs : Self ) -> Self {
458+ Self ( self . 0 . saturating_sub ( rhs. 0 ) )
459+ }
460+ }
461+
462+ /// Note that this is a standard, _potentially-panicking_, implementation. Use `Saturating` trait for
463+ /// safe addition.
464+ impl ops:: Add for Fixed64 {
465+ type Output = Self ;
466+
467+ fn add ( self , rhs : Self ) -> Self :: Output {
468+ Self ( self . 0 + rhs. 0 )
469+ }
470+ }
471+
472+ /// Note that this is a standard, _potentially-panicking_, implementation. Use `Saturating` trait for
473+ /// safe subtraction.
474+ impl ops:: Sub for Fixed64 {
475+ type Output = Self ;
476+
477+ fn sub ( self , rhs : Self ) -> Self :: Output {
478+ Self ( self . 0 - rhs. 0 )
479+ }
480+ }
481+
482+ impl CheckedSub for Fixed64 {
483+ fn checked_sub ( & self , rhs : & Self ) -> Option < Self > {
484+ if let Some ( v) = self . 0 . checked_sub ( rhs. 0 ) {
485+ Some ( Self ( v) )
486+ } else {
487+ None
488+ }
489+ }
490+ }
491+
492+ impl CheckedAdd for Fixed64 {
493+ fn checked_add ( & self , rhs : & Self ) -> Option < Self > {
494+ if let Some ( v) = self . 0 . checked_add ( rhs. 0 ) {
495+ Some ( Self ( v) )
496+ } else {
497+ None
498+ }
499+ }
500+ }
501+
380502/// PerU128 is parts-per-u128-max-value. It stores a value between 0 and 1 in fixed point.
381503#[ cfg_attr( feature = "std" , derive( Serialize , Deserialize , Debug ) ) ]
382504#[ derive( Encode , Decode , Default , Copy , Clone , PartialEq , Eq ) ]
@@ -755,6 +877,7 @@ impl traits::Extrinsic for OpaqueExtrinsic {
755877#[ cfg( test) ]
756878mod tests {
757879 use crate :: codec:: { Encode , Decode } ;
880+ use super :: { Perbill , Permill } ;
758881
759882 macro_rules! per_thing_upper_test {
760883 ( $num_type: tt, $per: tt) => {
@@ -798,19 +921,19 @@ mod tests {
798921 fn compact_permill_perbill_encoding ( ) {
799922 let tests = [ ( 0u32 , 1usize ) , ( 63 , 1 ) , ( 64 , 2 ) , ( 16383 , 2 ) , ( 16384 , 4 ) , ( 1073741823 , 4 ) , ( 1073741824 , 5 ) , ( u32:: max_value ( ) , 5 ) ] ;
800923 for & ( n, l) in & tests {
801- let compact: crate :: codec:: Compact < super :: Permill > = super :: Permill ( n) . into ( ) ;
924+ let compact: crate :: codec:: Compact < Permill > = Permill ( n) . into ( ) ;
802925 let encoded = compact. encode ( ) ;
803926 assert_eq ! ( encoded. len( ) , l) ;
804- let decoded = <crate :: codec:: Compact < super :: Permill > >:: decode ( & mut & encoded[ ..] ) . unwrap ( ) ;
805- let permill: super :: Permill = decoded. into ( ) ;
806- assert_eq ! ( permill, super :: Permill ( n) ) ;
927+ let decoded = <crate :: codec:: Compact < Permill > >:: decode ( & mut & encoded[ ..] ) . unwrap ( ) ;
928+ let permill: Permill = decoded. into ( ) ;
929+ assert_eq ! ( permill, Permill ( n) ) ;
807930
808- let compact: crate :: codec:: Compact < super :: Perbill > = super :: Perbill ( n) . into ( ) ;
931+ let compact: crate :: codec:: Compact < Perbill > = Perbill ( n) . into ( ) ;
809932 let encoded = compact. encode ( ) ;
810933 assert_eq ! ( encoded. len( ) , l) ;
811- let decoded = <crate :: codec:: Compact < super :: Perbill > >:: decode ( & mut & encoded[ ..] ) . unwrap ( ) ;
812- let perbill: super :: Perbill = decoded. into ( ) ;
813- assert_eq ! ( perbill, super :: Perbill ( n) ) ;
934+ let decoded = <crate :: codec:: Compact < Perbill > >:: decode ( & mut & encoded[ ..] ) . unwrap ( ) ;
935+ let perbill: Perbill = decoded. into ( ) ;
936+ assert_eq ! ( perbill, Perbill ( n) ) ;
814937 }
815938 }
816939
@@ -821,16 +944,16 @@ mod tests {
821944
822945 #[ test]
823946 fn test_has_compact_permill ( ) {
824- let data = WithCompact { data : super :: Permill ( 1 ) } ;
947+ let data = WithCompact { data : Permill ( 1 ) } ;
825948 let encoded = data. encode ( ) ;
826- assert_eq ! ( data, WithCompact :: <super :: Permill >:: decode( & mut & encoded[ ..] ) . unwrap( ) ) ;
949+ assert_eq ! ( data, WithCompact :: <Permill >:: decode( & mut & encoded[ ..] ) . unwrap( ) ) ;
827950 }
828951
829952 #[ test]
830953 fn test_has_compact_perbill ( ) {
831- let data = WithCompact { data : super :: Perbill ( 1 ) } ;
954+ let data = WithCompact { data : Perbill ( 1 ) } ;
832955 let encoded = data. encode ( ) ;
833- assert_eq ! ( data, WithCompact :: <super :: Perbill >:: decode( & mut & encoded[ ..] ) . unwrap( ) ) ;
956+ assert_eq ! ( data, WithCompact :: <Perbill >:: decode( & mut & encoded[ ..] ) . unwrap( ) ) ;
834957 }
835958
836959 #[ test]
@@ -850,20 +973,20 @@ mod tests {
850973
851974 #[ test]
852975 fn per_things_operate_in_output_type ( ) {
853- assert_eq ! ( super :: Perbill :: one( ) * 255_u64 , 255 ) ;
976+ assert_eq ! ( Perbill :: one( ) * 255_u64 , 255 ) ;
854977 }
855978
856979 #[ test]
857980 fn per_things_one_minus_one_part ( ) {
858981 use primitive_types:: U256 ;
859982
860983 assert_eq ! (
861- super :: Perbill :: from_parts( 999_999_999 ) * std:: u128 :: MAX ,
984+ Perbill :: from_parts( 999_999_999 ) * std:: u128 :: MAX ,
862985 ( ( Into :: <U256 >:: into( std:: u128 :: MAX ) * 999_999_999u32 ) / 1_000_000_000u32 ) . as_u128( )
863986 ) ;
864987
865988 assert_eq ! (
866- super :: Permill :: from_parts( 999_999 ) * std:: u128 :: MAX ,
989+ Permill :: from_parts( 999_999 ) * std:: u128 :: MAX ,
867990 ( ( Into :: <U256 >:: into( std:: u128 :: MAX ) * 999_999u32 ) / 1_000_000u32 ) . as_u128( )
868991 ) ;
869992 }
0 commit comments