pub fn round_dp(&self, dp: u32) -> Decimal {

        let old_scale = self.scale();

        if dp < old_scale && dp < 20 {
            // Technically, it's 28...
            // Short circuit for zero
            if self.is_zero() {
                return self.rescale(dp);
            }

            // Check to see if we need to add or subtract one.
            // Some expected results assuming dp = 2 and old_scale = 3:
            //   1.235  = 1.24
            //   1.2361 = 1.24
            //   1.2250 = 1.22
            //   1.2251 = 1.23
            // If we consider this example, we have the following number in `low`:
            //   1235 (scale 3)
            //   12361
            //   12250
            //   12251
            let index = dp as usize;
            let power10 = if dp < 10 {
                Decimal::from_u32(POWERS_10[index]).unwrap()
            } else {
                Decimal::from_u64(BIG_POWERS_10[index - 10]).unwrap()
            };
            //println!("{} * {}", self.to_string(), power10.to_string());
            let mut value = self.mul(power10);

            // Do some midpoint rounding checks
            // We're actually doing two things here.
            //  1. Figuring out midpoint rounding when we're right on the boundary. e.g. 2.50000
            //  2. Figuring out whether to add one or not e.g. 2.51
            // We only need to search back a certain number. e.g. 2.500, round(2) search 1.
            let raw = self.to_biguint();

            // Get the decimal portion
            //  e.g. 2.5001, round(2) decimal portion = 01
            let offset = self.rescale(dp).rescale(old_scale).to_biguint();
            //println!("Raw: {}, Offset: {}", raw.to_string(), offset.to_string());
            let decimal_portion = raw - offset;

            // Rescale to zero so it's easier to work with
            value = value.rescale(0u32);

            // If the decimal_portion is zero then we round based on the other data
            let mut cap = BigUint::from_u32(5u32).unwrap();
            for _ in 0..(old_scale - dp - 1) {
                cap = cap.mul(BigUint::from_u32(10u32).unwrap());
            }
            //println!("Cap {} Decimal Portion {}", cap, decimal_portion);
            if decimal_portion == cap {
                let even_or_odd = value.rem(Decimal::from_u32(2u32).unwrap());
                if !even_or_odd.is_zero() {
                    value = value.add(Decimal::one());
                }
            } else if decimal_portion > cap {
                // Doesn't matter about the decimal portion
                if self.is_negative() {
                    value = value.sub(Decimal::one());
                } else {
                    //println!("Decimal is greater than cap {} > {}", decimal_portion, cap);
                    value = value.add(Decimal::one());
                }
            }

            // Divide by the power to get back
            value.div(power10)
        } else {
            *self
        }
    }
/// Returns a new `Decimal` number with the specified number of decimal points for fractional portion.
/// Rounding currently follows "Bankers Rounding" rules. e.g. 6.5 -> 6, 7.5 -> 8
///
/// # Arguments
/// * `dp`: the number of decimal points to round to.
Returns a new `Decimal` number with the specified number of decimal points for fractional portion.
Rounding currently follows "Bankers Rounding" rules.
Returns a new ` Decimal ` number with the specified number of decimal points for fractional portion . Rounding currently follows " Bankers Rounding " rules .
pub fn round_dp(&self, dp: u32) -> Decimal {
        let old_scale = self.scale();
        if dp < old_scale && dp < 20 {
            // Technically, it's 28...
            // Short circuit for zero
            if self.is_zero() {
                return self.rescale(dp);
            }
            // Check to see if we need to add or subtract one.
            // Some expected results assuming dp = 2 and old_scale = 3:
            //   1.235  = 1.24
            //   1.2361 = 1.24
            //   1.2250 = 1.22
            //   1.2251 = 1.23
            // If we consider this example, we have the following number in `low`:
            //   1235 (scale 3)
            //   12361
            //   12250
            //   12251
            let index = dp as usize;
            let power10 = if dp < 10 {
                Decimal::from_u32(POWERS_10[index]).unwrap()
            } else {
                Decimal::from_u64(BIG_POWERS_10[index - 10]).unwrap()
            };
            //println!("{} * {}", self.to_string(), power10.to_string());
            let mut value = self.mul(power10);
            // Do some midpoint rounding checks
            // We're actually doing two things here.
            //  1. Figuring out midpoint rounding when we're right on the boundary. e.g. 2.50000
            //  2. Figuring out whether to add one or not e.g. 2.51
            // We only need to search back a certain number. e.g. 2.500, round(2) search 1.
            let raw = self.to_biguint();
            // Get the decimal portion
            //  e.g. 2.5001, round(2) decimal portion = 01
            let offset = self.rescale(dp).rescale(old_scale).to_biguint();
            //println!("Raw: {}, Offset: {}", raw.to_string(), offset.to_string());
            let decimal_portion = raw - offset;
            // Rescale to zero so it's easier to work with
            value = value.rescale(0u32);
            // If the decimal_portion is zero then we round based on the other data
            let mut cap = BigUint::from_u32(5u32).unwrap();
            for _ in 0..(old_scale - dp - 1) {
                cap = cap.mul(BigUint::from_u32(10u32).unwrap());
            }
            //println!("Cap {} Decimal Portion {}", cap, decimal_portion);
            if decimal_portion == cap {
                let even_or_odd = value.rem(Decimal::from_u32(2u32).unwrap());
                if !even_or_odd.is_zero() {
                    value = value.add(Decimal::one());
                }
            } else if decimal_portion > cap {
                // Doesn't matter about the decimal portion
                if self.is_negative() {
                    value = value.sub(Decimal::one());
                } else {
                    //println!("Decimal is greater than cap {} > {}", decimal_portion, cap);
                    value = value.add(Decimal::one());
                }
            }
            // Divide by the power to get back
            value.div(power10)
        } else {
            *self
        }
    }
pub fn round_dp ( & self , dp : u32 ) -> Decimal { let old_scale = self . scale ( ) ; if dp < old_scale && dp < 20 { // Technically, it's 28... // Short circuit for zero if self . is_zero ( ) { return self . rescale ( dp ) ; } // Check to see if we need to add or subtract one. // Some expected results assuming dp = 2 and old_scale = 3: //   1.235  = 1.24 //   1.2361 = 1.24 //   1.2250 = 1.22 //   1.2251 = 1.23 // If we consider this example, we have the following number in `low`: //   1235 (scale 3) //   12361 //   12250 //   12251 let index = dp as usize ; let power10 = if dp < 10 { Decimal :: from_u32 ( POWERS_10 [ index ] ) . unwrap ( ) } else { Decimal :: from_u64 ( BIG_POWERS_10 [ index - 10 ] ) . unwrap ( ) } ; //println!("{} * {}", self.to_string(), power10.to_string()); let mut value = self . mul ( power10 ) ; // Do some midpoint rounding checks // We're actually doing two things here. //  1. Figuring out midpoint rounding when we're right on the boundary. e.g. 2.50000 //  2. Figuring out whether to add one or not e.g. 2.51 // We only need to search back a certain number. e.g. 2.500, round(2) search 1. let raw = self . to_biguint ( ) ; // Get the decimal portion //  e.g. 2.5001, round(2) decimal portion = 01 let offset = self . rescale ( dp ) . rescale ( old_scale ) . to_biguint ( ) ; //println!("Raw: {}, Offset: {}", raw.to_string(), offset.to_string()); let decimal_portion = raw - offset ; // Rescale to zero so it's easier to work with value = value . rescale ( 0u32 ) ; // If the decimal_portion is zero then we round based on the other data let mut cap = BigUint :: from_u32 ( 5u32 ) . unwrap ( ) ; for _ in 0 .. ( old_scale - dp - 1 ) { cap = cap . mul ( BigUint :: from_u32 ( 10u32 ) . unwrap ( ) ) ; } //println!("Cap {} Decimal Portion {}", cap, decimal_portion); if decimal_portion == cap { let even_or_odd = value . rem ( Decimal :: from_u32 ( 2u32 ) . unwrap ( ) ) ; if ! even_or_odd . is_zero ( ) { value = value . add ( Decimal :: one ( ) ) ; } } else if decimal_portion > cap { // Doesn't matter about the decimal portion if self . is_negative ( ) { value = value . sub ( Decimal :: one ( ) ) ; } else { //println!("Decimal is greater than cap {} > {}", decimal_portion, cap); value = value . add ( Decimal :: one ( ) ) ; } } // Divide by the power to get back value . div ( power10 ) } else { * self } }
Returns a new `Decimal` number with the specified number of decimal points for fractional portion.
Returns a new ` Decimal ` number with the specified number of decimal points for fractional portion .
&self
dp
u32
&self
dp
u32