Skip to main content

dec_number_sys/
dec_number.rs

1//! Safe bindings for arbitrary precision decimal.
2
3use crate::dec_context::*;
4use crate::dec_number_c::*;
5use libc::c_char;
6use std::ffi::{CStr, CString};
7
8/// Sign mask: 1 = negative, 0 = positive or zero.
9pub const DEC_NEG: u8 = 0x80;
10
11/// Infinity mask: 1 = Infinity.
12pub const DEC_INF: u8 = 0x40;
13
14/// Not-a-Number mask: 1 = NaN.
15pub const DEC_NAN: u8 = 0x20;
16
17/// Signalling Not-a-Number mask: 1 = sNaN.
18pub const DEC_SNAN: u8 = 0x10;
19
20/// Special value mask: 1 = special (Infinity, NaN or sNaN).
21pub const DEC_SPECIAL: u8 = DEC_INF | DEC_NAN | DEC_SNAN;
22
23/// [DecNumber] value 0 (zero).
24pub const DEC_NUMBER_ZERO: DecNumber = DecNumber {
25  digits: 1,
26  exponent: 0,
27  bits: 0,
28  lsu: [0; 12],
29};
30
31/// [DecNumber] value 1 (one).
32pub const DEC_NUMBER_ONE: DecNumber = DecNumber {
33  digits: 1,
34  exponent: 0,
35  bits: 0,
36  lsu: [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
37};
38
39/// [DecNumber] value 2 (two).
40pub const DEC_NUMBER_TWO: DecNumber = DecNumber {
41  digits: 1,
42  exponent: 0,
43  bits: 0,
44  lsu: [2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
45};
46
47/// [DecNumber] value 10 (ten).
48pub const DEC_NUMBER_TEN: DecNumber = DecNumber {
49  digits: 2,
50  exponent: 0,
51  bits: 0,
52  lsu: [10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
53};
54
55/// [DecNumber] value 100 (hundred).
56pub const DEC_NUMBER_HUNDRED: DecNumber = DecNumber {
57  digits: 3,
58  exponent: 0,
59  bits: 0,
60  lsu: [100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
61};
62
63/// [DecNumber] value 1000 (thousand).
64pub const DEC_NUMBER_THOUSAND: DecNumber = DecNumber {
65  digits: 4,
66  exponent: 0,
67  bits: 0,
68  lsu: [0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
69};
70
71/// [DecNumber] value 1000000 (million).
72pub const DEC_NUMBER_MILLION: DecNumber = DecNumber {
73  digits: 7,
74  exponent: 0,
75  bits: 0,
76  lsu: [0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0],
77};
78
79/// [DecNumber] value 1000000000 (billion).
80pub const DEC_NUMBER_BILLION: DecNumber = DecNumber {
81  digits: 10,
82  exponent: 0,
83  bits: 0,
84  lsu: [0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0],
85};
86
87/// Arbitrary precision decimal number.
88#[repr(C)]
89#[derive(Debug, Copy, Clone)]
90pub struct DecNumber {
91  digits: i32,
92  exponent: i32,
93  bits: u8,
94  lsu: [u16; 12],
95}
96
97impl Default for DecNumber {
98  /// Default value for [DecNumber] is zero.
99  fn default() -> Self {
100    DEC_NUMBER_ZERO
101  }
102}
103
104/// Safe binding to *decNumberAdd* function.
105pub fn dec_number_add(dn1: &DecNumber, dn2: &DecNumber, dc: &mut DecContext) -> DecNumber {
106  let mut dn = DEC_NUMBER_ZERO;
107  unsafe {
108    decNumberAdd(&mut dn, dn1, dn2, dc);
109  }
110  dn
111}
112
113/// Safe binding to *decNumberCompare* function.
114pub fn dec_number_compare(dn1: &DecNumber, dn2: &DecNumber, dc: &mut DecContext) -> DecNumber {
115  let mut dn = DEC_NUMBER_ZERO;
116  unsafe {
117    decNumberCompare(&mut dn, dn1, dn2, dc);
118  }
119  dn
120}
121
122/// Safe binding to *decNumberDivide* function.
123pub fn dec_number_divide(dn1: &DecNumber, dn2: &DecNumber, dc: &mut DecContext) -> DecNumber {
124  let mut dn = DEC_NUMBER_ZERO;
125  unsafe {
126    decNumberDivide(&mut dn, dn1, dn2, dc);
127  }
128  dn
129}
130
131/// Safe binding to *decNumberExp* function.
132pub fn dec_number_exp(dn1: &DecNumber, dc: &mut DecContext) -> DecNumber {
133  let mut dn = DEC_NUMBER_ZERO;
134  unsafe {
135    decNumberExp(&mut dn, dn1, dc);
136  }
137  dn
138}
139
140/// Safe binding to *decNumberFromInt32* function.
141pub fn dec_number_from_i32(n: i32) -> DecNumber {
142  let mut dn = DEC_NUMBER_ZERO;
143  unsafe {
144    decNumberFromInt32(&mut dn, n);
145  }
146  dn
147}
148
149/// Safe binding to *decNumberFromString* function.
150pub fn dec_number_from_string(s: &str, dc: &mut DecContext) -> DecNumber {
151  let c_s = CString::new(s).unwrap();
152  let mut value = DEC_NUMBER_ZERO;
153  unsafe {
154    decNumberFromString(&mut value, c_s.as_ptr(), dc);
155  }
156  value
157}
158
159/// Safe binding to *decNumberFromUInt32* function.
160pub fn dec_number_from_u32(n: u32) -> DecNumber {
161  let mut result = DEC_NUMBER_ZERO;
162  unsafe {
163    decNumberFromUInt32(&mut result, n);
164  }
165  result
166}
167
168/// Safe binding to *decNumberIsNegative* function.
169///
170/// This function was replaced by macro and removed from public API.
171/// This implementation is the Rust version of original library macro.
172pub fn dec_number_is_negative(dn1: &DecNumber) -> bool {
173  dn1.bits & DEC_NEG != 0
174}
175
176/// Safe binding to *decNumberIsZero* function.
177///
178/// This function was replaced by macro and removed from public API.
179/// This implementation is the Rust version of original library macro.
180pub fn dec_number_is_zero(dn1: &DecNumber) -> bool {
181  dn1.lsu[0] == 0 && dn1.digits == 1 && (dn1.bits & DEC_SPECIAL == 0)
182}
183
184/// Safe binding to *decNumberLn* function.
185pub fn dec_number_ln(dn1: &DecNumber, dc: &mut DecContext) -> DecNumber {
186  let mut dn = DEC_NUMBER_ZERO;
187  unsafe {
188    decNumberLn(&mut dn, dn1, dc);
189  }
190  dn
191}
192
193/// Safe binding to *decNumberMinus* function.
194pub fn dec_number_minus(dn1: &DecNumber, dc: &mut DecContext) -> DecNumber {
195  let mut dn = DEC_NUMBER_ZERO;
196  unsafe {
197    decNumberMinus(&mut dn, dn1, dc);
198  }
199  dn
200}
201
202/// Safe binding to *decNumberMultiply* function.
203pub fn dec_number_multiply(dn1: &DecNumber, dn2: &DecNumber, dc: &mut DecContext) -> DecNumber {
204  let mut dn = DEC_NUMBER_ZERO;
205  unsafe {
206    decNumberMultiply(&mut dn, dn1, dn2, dc);
207  }
208  dn
209}
210
211/// Safe binding to *decNumberPlus* function.
212pub fn dec_number_plus(dn1: &DecNumber, dc: &mut DecContext) -> DecNumber {
213  let mut dn = DEC_NUMBER_ZERO;
214  unsafe {
215    decNumberPlus(&mut dn, dn1, dc);
216  }
217  dn
218}
219
220/// Safe binding to *decNumberPower* function.
221pub fn dec_number_power(dn1: &DecNumber, dn2: &DecNumber, dc: &mut DecContext) -> DecNumber {
222  let mut dn = DEC_NUMBER_ZERO;
223  unsafe {
224    decNumberPower(&mut dn, dn1, dn2, dc);
225  }
226  dn
227}
228
229/// Safe binding to *decNumberQuantize* function.
230pub fn dec_number_quantize(dn1: &DecNumber, dn2: &DecNumber, dc: &mut DecContext) -> DecNumber {
231  let mut dn = DEC_NUMBER_ZERO;
232  unsafe {
233    decNumberQuantize(&mut dn, dn1, dn2, dc);
234  }
235  dn
236}
237
238/// Safe binding to *decNumberReduce* function.
239pub fn dec_number_reduce(dn1: &DecNumber, dc: &mut DecContext) -> DecNumber {
240  let mut dn = DEC_NUMBER_ZERO;
241  unsafe {
242    decNumberReduce(&mut dn, dn1, dc);
243  }
244  dn
245}
246
247/// Safe binding to *decNumberRescale* function.
248pub fn dec_number_rescale(dn1: &DecNumber, dn2: &DecNumber, dc: &mut DecContext) -> DecNumber {
249  let mut dn = DEC_NUMBER_ZERO;
250  unsafe {
251    decNumberRescale(&mut dn, dn1, dn2, dc);
252  }
253  dn
254}
255
256/// Safe binding to *decNumberScaleB* function.
257pub fn dec_number_scale_b(dn1: &DecNumber, dn2: &DecNumber, dc: &mut DecContext) -> DecNumber {
258  let mut dn = DEC_NUMBER_ZERO;
259  unsafe {
260    decNumberScaleB(&mut dn, dn1, dn2, dc);
261  }
262  dn
263}
264
265/// Safe binding to *decNumberSquareRoot* function.
266pub fn dec_number_square_root(dn1: &DecNumber, dc: &mut DecContext) -> DecNumber {
267  let mut dn = DEC_NUMBER_ZERO;
268  unsafe {
269    decNumberSquareRoot(&mut dn, dn1, dc);
270  }
271  dn
272}
273
274/// Safe binding to *decNumberSubtract* function.
275pub fn dec_number_subtract(dn1: &DecNumber, dn2: &DecNumber, dc: &mut DecContext) -> DecNumber {
276  let mut dn = DEC_NUMBER_ZERO;
277  unsafe {
278    decNumberSubtract(&mut dn, dn1, dn2, dc);
279  }
280  dn
281}
282
283/// Safe binding to *decNumberToString* function.
284pub fn dec_number_to_string(dn1: &DecNumber) -> String {
285  unsafe {
286    let mut buf = Vec::<char>::with_capacity((dn1.digits + 14) as usize);
287    decNumberToString(dn1, buf.as_mut_ptr() as *mut c_char);
288    CStr::from_ptr(buf.as_ptr() as *const c_char)
289      .to_string_lossy()
290      .into_owned()
291  }
292}
293
294/// Safe binding to *decNumberZero* function.
295pub fn dec_number_zero(dn1: &mut DecNumber) {
296  unsafe {
297    decNumberZero(dn1);
298  }
299}