use crate::dec_context::*;
use crate::dec_number_c::*;
use libc::c_char;
use std::ffi::{CStr, CString};
pub const DEC_NEG: u8 = 0x80;
pub const DEC_INF: u8 = 0x40;
pub const DEC_NAN: u8 = 0x20;
pub const DEC_SNAN: u8 = 0x10;
pub const DEC_SPECIAL: u8 = DEC_INF | DEC_NAN | DEC_SNAN;
pub const DEC_NUMBER_ZERO: DecNumber = DecNumber {
digits: 1,
exponent: 0,
bits: 0,
lsu: [0; 12],
};
pub const DEC_NUMBER_ONE: DecNumber = DecNumber {
digits: 1,
exponent: 0,
bits: 0,
lsu: [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
};
pub const DEC_NUMBER_TWO: DecNumber = DecNumber {
digits: 1,
exponent: 0,
bits: 0,
lsu: [2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
};
pub const DEC_NUMBER_TEN: DecNumber = DecNumber {
digits: 2,
exponent: 0,
bits: 0,
lsu: [10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
};
pub const DEC_NUMBER_HUNDRED: DecNumber = DecNumber {
digits: 3,
exponent: 0,
bits: 0,
lsu: [100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
};
pub const DEC_NUMBER_THOUSAND: DecNumber = DecNumber {
digits: 4,
exponent: 0,
bits: 0,
lsu: [0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
};
pub const DEC_NUMBER_MILLION: DecNumber = DecNumber {
digits: 7,
exponent: 0,
bits: 0,
lsu: [0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0],
};
pub const DEC_NUMBER_BILLION: DecNumber = DecNumber {
digits: 10,
exponent: 0,
bits: 0,
lsu: [0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0],
};
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct DecNumber {
digits: i32,
exponent: i32,
bits: u8,
lsu: [u16; 12],
}
impl Default for DecNumber {
fn default() -> Self {
DEC_NUMBER_ZERO
}
}
pub fn dec_number_add(dn1: &DecNumber, dn2: &DecNumber, dc: &mut DecContext) -> DecNumber {
let mut dn = DEC_NUMBER_ZERO;
unsafe {
decNumberAdd(&mut dn, dn1, dn2, dc);
}
dn
}
pub fn dec_number_compare(dn1: &DecNumber, dn2: &DecNumber, dc: &mut DecContext) -> DecNumber {
let mut dn = DEC_NUMBER_ZERO;
unsafe {
decNumberCompare(&mut dn, dn1, dn2, dc);
}
dn
}
pub fn dec_number_divide(dn1: &DecNumber, dn2: &DecNumber, dc: &mut DecContext) -> DecNumber {
let mut dn = DEC_NUMBER_ZERO;
unsafe {
decNumberDivide(&mut dn, dn1, dn2, dc);
}
dn
}
pub fn dec_number_exp(dn1: &DecNumber, dc: &mut DecContext) -> DecNumber {
let mut dn = DEC_NUMBER_ZERO;
unsafe {
decNumberExp(&mut dn, dn1, dc);
}
dn
}
pub fn dec_number_from_i32(n: i32) -> DecNumber {
let mut dn = DEC_NUMBER_ZERO;
unsafe {
decNumberFromInt32(&mut dn, n);
}
dn
}
pub fn dec_number_from_string(s: &str, dc: &mut DecContext) -> DecNumber {
let c_s = CString::new(s).unwrap();
let mut value = DEC_NUMBER_ZERO;
unsafe {
decNumberFromString(&mut value, c_s.as_ptr(), dc);
}
value
}
pub fn dec_number_from_u32(n: u32) -> DecNumber {
let mut result = DEC_NUMBER_ZERO;
unsafe {
decNumberFromUInt32(&mut result, n);
}
result
}
pub fn dec_number_is_negative(dn1: &DecNumber) -> bool {
dn1.bits & DEC_NEG != 0
}
pub fn dec_number_is_zero(dn1: &DecNumber) -> bool {
dn1.lsu[0] == 0 && dn1.digits == 1 && (dn1.bits & DEC_SPECIAL == 0)
}
pub fn dec_number_ln(dn1: &DecNumber, dc: &mut DecContext) -> DecNumber {
let mut dn = DEC_NUMBER_ZERO;
unsafe {
decNumberLn(&mut dn, dn1, dc);
}
dn
}
pub fn dec_number_minus(dn1: &DecNumber, dc: &mut DecContext) -> DecNumber {
let mut dn = DEC_NUMBER_ZERO;
unsafe {
decNumberMinus(&mut dn, dn1, dc);
}
dn
}
pub fn dec_number_multiply(dn1: &DecNumber, dn2: &DecNumber, dc: &mut DecContext) -> DecNumber {
let mut dn = DEC_NUMBER_ZERO;
unsafe {
decNumberMultiply(&mut dn, dn1, dn2, dc);
}
dn
}
pub fn dec_number_plus(dn1: &DecNumber, dc: &mut DecContext) -> DecNumber {
let mut dn = DEC_NUMBER_ZERO;
unsafe {
decNumberPlus(&mut dn, dn1, dc);
}
dn
}
pub fn dec_number_power(dn1: &DecNumber, dn2: &DecNumber, dc: &mut DecContext) -> DecNumber {
let mut dn = DEC_NUMBER_ZERO;
unsafe {
decNumberPower(&mut dn, dn1, dn2, dc);
}
dn
}
pub fn dec_number_quantize(dn1: &DecNumber, dn2: &DecNumber, dc: &mut DecContext) -> DecNumber {
let mut dn = DEC_NUMBER_ZERO;
unsafe {
decNumberQuantize(&mut dn, dn1, dn2, dc);
}
dn
}
pub fn dec_number_reduce(dn1: &DecNumber, dc: &mut DecContext) -> DecNumber {
let mut dn = DEC_NUMBER_ZERO;
unsafe {
decNumberReduce(&mut dn, dn1, dc);
}
dn
}
pub fn dec_number_rescale(dn1: &DecNumber, dn2: &DecNumber, dc: &mut DecContext) -> DecNumber {
let mut dn = DEC_NUMBER_ZERO;
unsafe {
decNumberRescale(&mut dn, dn1, dn2, dc);
}
dn
}
pub fn dec_number_scale_b(dn1: &DecNumber, dn2: &DecNumber, dc: &mut DecContext) -> DecNumber {
let mut dn = DEC_NUMBER_ZERO;
unsafe {
decNumberScaleB(&mut dn, dn1, dn2, dc);
}
dn
}
pub fn dec_number_square_root(dn1: &DecNumber, dc: &mut DecContext) -> DecNumber {
let mut dn = DEC_NUMBER_ZERO;
unsafe {
decNumberSquareRoot(&mut dn, dn1, dc);
}
dn
}
pub fn dec_number_subtract(dn1: &DecNumber, dn2: &DecNumber, dc: &mut DecContext) -> DecNumber {
let mut dn = DEC_NUMBER_ZERO;
unsafe {
decNumberSubtract(&mut dn, dn1, dn2, dc);
}
dn
}
pub fn dec_number_to_string(dn1: &DecNumber) -> String {
unsafe {
let mut buf = Vec::<char>::with_capacity((dn1.digits + 14) as usize);
decNumberToString(dn1, buf.as_mut_ptr() as *mut c_char);
CStr::from_ptr(buf.as_ptr() as *const c_char)
.to_string_lossy()
.into_owned()
}
}
pub fn dec_number_zero(dn1: &mut DecNumber) {
unsafe {
decNumberZero(dn1);
}
}