Eine aufbereitete Darstellung der Quelle

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Quelle  common.rs

  Sprache: Rust
 

use crate::constants::MAX_PRECISION_U32;
use crate::{
    ops::array::{div_by_u32, is_all_zero, mul_by_u32},
    Decimal,
};
use core::fmt;
use std::error;

#[derive(Debug, Clone)]
pub struct InvalidDecimal {
    inner: Option<String>,
}

impl fmt::Display for InvalidDecimal {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        if let Some(ref msg) = self.inner {
            fmt.write_fmt(format_args!("Invalid Decimal: {}", msg))
        } else {
            fmt.write_str("Invalid Decimal")
        }
    }
}

impl error::Error for InvalidDecimal {}

pub(in crate::postgres) struct PostgresDecimal<D> {
    pub neg: bool,
    pub weight: i16,
    pub scale: u16,
    pub digits: D,
}

impl Decimal {
    pub(in crate::postgres) fn from_postgres<D: ExactSizeIterator<Item = u16>>(
        PostgresDecimal {
            neg,
            scale,
            digits,
            weight,
        }: PostgresDecimal<D>,
    ) -> Self {
        let mut digits = digits.into_iter().collect::<Vec<_>>();

        let fractionals_part_count = digits.len() as i32 + (-weight as i32) - 1;
        let integers_part_count = weight as i32 + 1;

        let mut result = Decimal::ZERO;
        // adding integer part
        if integers_part_count > 0 {
            let (start_integers, last) = if integers_part_count > digits.len() as i32 {
                (integers_part_count - digits.len() as i32, digits.len() as i32)
            } else {
                (0, integers_part_count)
            };
            let integers: Vec<_> = digits.drain(..last as usize).collect();
            for digit in integers {
                result *= Decimal::from_i128_with_scale(10i128.pow(4), 0);
                result += Decimal::new(digit as i64, 0);
            }
            result *= Decimal::from_i128_with_scale(10i128.pow(4 * start_integers as u32), 0);
        }
        // adding fractional part
        if fractionals_part_count > 0 {
            let start_fractionals = if weight < 0 { (-weight as u32) - 1 } else { 0 };
            for (i, digit) in digits.into_iter().enumerate() {
                let fract_pow = 4 * (i as u32 + 1 + start_fractionals);
                if fract_pow <= MAX_PRECISION_U32 {
                    result += Decimal::new(digit as i64, 0) / Decimal::from_i128_with_scale(10i128.pow(fract_pow), 0);
                } else if fract_pow == MAX_PRECISION_U32 + 4 {
                    // rounding last digit
                    if digit >= 5000 {
                        result +=
                            Decimal::new(1_i64, 0) / Decimal::from_i128_with_scale(10i128.pow(MAX_PRECISION_U32), 0);
                    }
                }
            }
        }

        result.set_sign_negative(neg);
        // Rescale to the postgres value, automatically rounding as needed.
        result.rescale(scale as u32);
        result
    }

    pub(in crate::postgres) fn to_postgres(self) -> PostgresDecimal<Vec<i16>> {
        if self.is_zero() {
            return PostgresDecimal {
                neg: false,
                weight: 0,
                scale: 0,
                digits: vec![0],
            };
        }
        let scale = self.scale() as u16;

        let groups_diff = scale & 0x3; // groups_diff = scale % 4

        let mut mantissa = self.mantissa_array4();

        if groups_diff > 0 {
            let remainder = 4 - groups_diff;
            let power = 10u32.pow(u32::from(remainder));
            mul_by_u32(&mut mantissa, power);
        }

        // array to store max mantissa of Decimal in Postgres decimal format
        const MAX_GROUP_COUNT: usize = 8;
        let mut digits = Vec::with_capacity(MAX_GROUP_COUNT);

        while !is_all_zero(&mantissa) {
            let digit = div_by_u32(&mut mantissa, 10000as u16;
            digits.push(digit.try_into().unwrap());
        }
        digits.reverse();
        let digits_after_decimal = (scale + 3as u16 / 4;
        let weight = digits.len() as i16 - digits_after_decimal as i16 - 1;

        let unnecessary_zeroes = if weight >= 0 {
            let index_of_decimal = (weight + 1as usize;
            digits
                .get(index_of_decimal..)
                .expect("enough digits exist")
                .iter()
                .rev()
                .take_while(|i| **i == 0)
                .count()
        } else {
            0
        };
        let relevant_digits = digits.len() - unnecessary_zeroes;
        digits.truncate(relevant_digits);

        PostgresDecimal {
            neg: self.is_sign_negative(),
            digits,
            scale,
            weight,
        }
    }
}

Messung V0.5 in Prozent
C=87 H=96 G=91

¤ Dauer der Verarbeitung: 0.9 Sekunden  (vorverarbeitet am  2026-06-23) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....

Besucherstatistik

Besucherstatistik