attention I use the night version 0.15.1 incompatible with 0.14.1
#ZIG_DECIMAL
processing decimal numbers with mpdecimal as a backdrop
I wrote this lib to free myself from arithmetic problems on large decimals
https://speleotrove.com/decimal/
This part explains why we need it.
Another source that inspired me and that joins what I think 1990
https://github.com/dnotq/decNumber
Communication structure for default common control decimal128 - 34 digits
Respects the SQL display alignment standard based on the trim()
| Function | Description | Pub | trunc | bool | panic |
|---|---|---|---|---|---|
| init | Creates Decimal (Entier , Scal) | x | x | ||
| deinit | De-allocates the Decimal | x | |||
| isNumber | check the area is still 'NAN' and field INVALID | x | x | ||
| normalize | normalize this conforms to the attributes | x | |||
| isOverflow | Check if the number of integers is too high | x | x | ||
| setDcml | give a value (text format) to '.number' | x | x | x | |
| set | give a value (DCMLFX, f128) | x | x | ||
| zadd | zadd(dst: *DCMLFX ,src: DCMLFX) | x | x | ||
| setZero | forces the value 0 to setZeros(dst: *DCMLFX) | x | |||
| isZeros | checks if the value 0 isZeros(dst: DCMLFX) | x | x | ||
| isNegative | checks value negative | x | x | ||
| round | two-function round and truncate see finance... | x | |||
| roundTo | Copy data 'B' to 'A' rounded with 'A'. | x | |||
| trunc | function, truncate | x | |||
| truncTo | truncTo(dst: *DCMLFX, a : DCMLFX) | x | |||
| string | Field formatting ex. 12345.321 field_init(8,3) | x | x | ||
| editCodeFlt | Field formatting and edit-code | x | x | ||
| strUFlt | Field formatting and unsigned | x | x | ||
| editCodeInt | Field formatting and edit-code | x | x | ||
| strUInt | Field formatting and unsigned | x | x | ||
| add | a = a + b | x | x | ||
| @"+" | a = a + b | x | x | ||
| addTo | r = a + b | x | x | ||
| sub | a = a - b | x | x | ||
| @"-" | a = a - b | x | x | ||
| subTo | r = a - b | x | x | ||
| mult | a = a * b | x | x | ||
| @"*" | a = a * b | x | x | ||
| mutlto | r = a * b | x | x | ||
| div | a = a / b | x | x | x | |
| @"/" | c = a / b | x | x | x | |
| divTo | r = a / b | x | x | x | |
| floor | r = a | x | x | ||
| ceil | r = a | x | x | ||
| rem | r = a / b | x | x | x | |
| getpercent | r = a / b | x | x | x | |
| percent | r = a / b | x | x | x | |
| rate | total.rate(prix,nbritem,tax) | x | x | x | |
| cmp | compare a , b returns EQ LT GT ERR | x | x | ||
| eval | evaluation d'expression | x | |||
| show | show evaluation d'expression | x | |||
| debugPrint | small followed by '.number, entier, scal' | x | |||
| DcmlIterator | Struct Iterator | . | |||
| next | next iterator Char(UTF8) | . | |||
| iterator | Returns a DcmlIterator over the String | . | |||
| isUTF8Byte | Checks if byte is part of UTF-8 character | . | |||
| getUTF8Size | Returns the UTF-8 character's size | . |
</br/>
const std = @import("std"); const builtin = @import("builtin"); const dcml = @import("decimal").DCMLFX; const stdout = std.io.getStdOut().writer(); const stdin = std.io.getStdIn().reader(); //================================= pub const prix = struct { base : dcml , tax : dcml , htx : dcml , ttx : dcml , ttc : dcml , nbritem : dcml , // defined structure and set "0" pub fn init() prix { return prix { .base = dcml.init(13,2), .tax = dcml.init(3,2), .htx = dcml.init(20,2), .ttx = dcml.init(20,2), .ttc = dcml.init(20,2), .nbritem = dcml.init(15,0), }; } pub fn deinitRecord( r :*prix) void { dcml.deinit(&r.base); dcml.deinit(&r.tax); dcml.deinit(&r.htx); dcml.deinit(&r.ttc); dcml.deinit(&r.nbritem); } }; pub fn main() !void { stdout.writeAll("\x1b[2J") catch {}; stdout.writeAll("\x1b[3J") catch {}; stdout.print("\x1b[{d};{d}H", .{ 1, 1 }) catch {}; var vente = prix.init (); // prix moyenne voiture vente.base.setDcml("45578.00") ; // taxe 20% vente.tax.setDcml("0.25") ; // number of cars sold by the group worldwide vente.nbritem.setDcml("100000000000") ; // Prices all taxes included vente.ttc.rate(vente.base,vente.nbritem,vente.tax) ; std.debug.print("\r\n Prices base fabrication : {s}\r\n",.{vente.base.string()}); std.debug.print("\r\n Tax : {s}\r\n",.{vente.tax.string()}); std.debug.print("\r\n nombre de voitures vendue : {s}\r\n",.{vente.nbritem.string()}); // Total Price excluding tax vente.htx.multTo(vente.base,vente.nbritem); // Prices all taxes included vente.ttc.rate(vente.base,vente.nbritem,vente.tax); // Prices all total taxe vente.ttx.subTo(vente.ttc, vente.htx); std.debug.print("\r\n Total Price excluding tax : {s}\r\n",.{vente.htx.string()}); std.debug.print("\r\n Total Price tax : {s}\r\n",.{vente.ttx.string()}); std.debug.print("\r\n Total Price included tax : {s}\r\n",.{vente.ttc.string()}); // ---------------------- // test divers // ---------------------- // other calcul vente.htx.setZeros(); vente.ttx.setZeros(); vente.ttc.setZeros(); vente.base.setDcml("1.52") ; vente.tax.setDcml("25") ; vente.nbritem.setDcml("10") ; std.debug.print("\r\n Prices base fabrication : {s}\r\n",.{vente.base.string()}); std.debug.print("\r\n Tax : {s}\r\n",.{vente.tax.string()}); std.debug.print("\r\n nombre de steack : {s}\r\n",.{vente.nbritem.string()}); vente.htx.multTo(vente.base,vente.nbritem) ; _=vente.ttx.percent(vente.htx, vente.tax); vente.ttc.addTo(vente.htx, vente.ttx); std.debug.print("\r\n Total Price excluding tax : {s}\r\n",.{vente.htx.string()}); std.debug.print("\r\n Total Price tax : {s}\r\n",.{vente.ttx.string()}); std.debug.print("\r\n Total Price included tax : {s}\r\n",.{vente.ttc.string()}); vente.htx.setZeros(); vente.ttc.setZeros(); vente.ttc.rate(vente.base,vente.nbritem,vente.tax) ; std.debug.print("\r\n Prices all taxes included {s}\r\n",.{vente.ttc.string()}); prix.deinitRecord(&vente); std.debug.print("\r\n-----------------------------------\r\n",.{}); // test error // dcml.debugContext(); // std.debug.print("\r\nzeros {}\r\n",.{vente.ttc.isZeros()}); var r = dcml.init(7,3) ; // set 0 init default var t = dcml.init(12,2) ; var x = dcml.init(12,0) ; var z = dcml.init(5,2) ; var y = dcml.init(7,0) ; // set 0 init default // ------------------------------------------------------------------ // Management: calculation of the number of boxes to be delivered, // taking into account business tolerances // ------------------------------------------------------------------ var boite = dcml.init( 7,0) ; // Number of sheets per box var feuille = dcml.init(4,0) ; // Number of sheets off the press var nbrfeuille = dcml.init(10,0); // Number of sheets remaining less than one box var rest = dcml.init(7,0); // Tolerance below which a box cannot be added var tolerance = dcml.init(3,2); var pourcentage = dcml.init(3,2); boite.setDcml("0") ; feuille.setDcml("2500") ; nbrfeuille.setDcml("626500"); tolerance.setDcml("54.00"); // overflow // rest.setDcml("1000"); // nbrfeuille.mult(rest); std.debug.print("\r\n divTo({s},{s})= boite:={s}\r\n",.{nbrfeuille.string(),feuille.string(),boite.string()}); rest.setZeros();pourcentage.setZeros(); _= boite.divTo(nbrfeuille,feuille) ; _= rest.rem(nbrfeuille,feuille) ; _= pourcentage.getpercent(rest,feuille) ; std.debug.print("\r\n percent({s},{s})= pourcentage:{s}\r\n",.{feuille.string(),rest.string(),pourcentage.string()}); // As the percentage is greater than 54%, 1 box is added to the delivery. if( pourcentage.cmp(tolerance) == dcml.CMP.GT) { // rest.setDcml("1"); boite.@"+"(1); } std.debug.print("\r\n boite:{s}\r\n",.{boite.string()}); t.setDcml("3.55") ; x.setDcml("3") ; r.setDcml("3.55") ; r.floor() ; std.debug.print("\r\n floor(t:{s}) r:{s}\r\n",.{t.string(),r.string()}); r.setDcml("3.55") ;r.ceil() ; std.debug.print("\r\n ceil(t:{s}) r:{s}\r\n",.{t.string(),r.string()}); r.setZeros(); x.setZeros(); var t0 = r.divTo(t,x) ; if (!t0) std.debug.print("Division by zeros",.{}); std.debug.print("\r\n rem({s},{s})={s}\r\n",.{t.string(),x.string(),r.string()}); x.setDcml("2") ; t.setZeros(); t0 = r.rem(t,x) ; if (!t0) std.debug.print("Division by zeros",.{}); std.debug.print("\r\n rem({s},{s})={s}\r\n",.{t.string(),x.string(),r.string()}); r.setDcml("12.650") ; const repcmp = r.cmp(t) ; std.debug.print("\r\n repcmp = dcml.cmp({s},{s}) = {}\r\n",.{r.string(),t.string(),repcmp}); r.setDcml("12.6509874") ; std.debug.print("\r\n print setDcml(12.6509874) (7.3) {s}\r\n",.{r.string()}); y.setDcml("12.6504") ; std.debug.print("\r\n if (scale == 0 ) print setdcml(12.6504) (7,0) {s}\r\n",.{y.string()}); t.setDcml("50.00"); r.setDcml("2.00") ; z.multTo(t,r) ; std.debug.print("\r\n t:{s} mult r:{s} = {s}\r\n",.{ t.string(),r.string(),z.string()}); r.setZeros(); const t1 = t.div(r) ; if (!t1) std.debug.print("Division by zeros",.{}); var c = dcml.init(7,3) ; // set 0 init default var b = dcml.init(12,2) ; c.setDcml("12345.68521"); std.debug.print("isNegative {} c.round() c:{s}; \r\n",.{c.isNegative(),c.string()}); b.setZeros(); std.debug.print("\r\n c:{s} b:{s}\r\n",.{c.string(), b.string()}); b.roundTo(c); b.debugPrint("b.roundIndex(b)"); std.debug.print("control b.roundIndex(c) b:{s} c:{s}; \r\n",.{b.string(),c.string()}); b.zadd(c); std.debug.print("\r\n b.zadd(c); b:{s} c:{s}\r\n",.{b.string(),c.string()}); c.setDcml("12345.68541"); c.round(); std.debug.print("control 12345.68541 c.round() c:{s}; \r\n",.{c.string()}); c.setDcml("-12345.68451"); std.debug.print("isNegative {} c.round() c:{s}; \r\n",.{c.isNegative(),c.string()}); c.round(); std.debug.print("control -12345.68451 c.round() c:{s}; \r\n",.{c.string()}); c.setDcml("12345.68421"); c.round(); std.debug.print("control 12345.68421 c.round() c:{s}; \r\n",.{c.string()}); c.setDcml("-12345.68781"); c.round(); std.debug.print("control 12345.68781 c.round() c:{s}; \r\n",.{c.string()}); c.setDcml("12345.68781"); c.round(); std.debug.print("control 12345.68781 c.round() c:{s}; \r\n",.{c.string()}); c.setDcml("12345.68541"); c.trunc(); std.debug.print("control 12345.68541 c.trunc() c:{s}; \r\n",.{c.string()}); c.setDcml("12345.68451"); c.trunc(); std.debug.print("control 12345.68451 c.trunc() c:{s}; \r\n",.{c.string()}); c.setDcml("12345.68421"); c.trunc(); std.debug.print("control 12345.68421 c.trunc() c:{s}; \r\n",.{c.string()}); c.setDcml("12345.68781"); c.trunc(); std.debug.print("control 12345.68781 c.trunc() c:{s}; \r\n",.{c.string()}); c.setDcml("-12345.68781"); c.trunc(); std.debug.print("control -12345.68781 c.trunc() c:{s}; \r\n",.{c.string()}); std.debug.print("control 12345.68781 c.round() c:{s}; \r\n",.{c.strUFlt()}); c.setZeros(); c.trunc(); std.debug.print("control 0.0 c.trunc() c:{s}; \r\n",.{c.string()}); c.setDcml("12345.68781"); c.trunc(); std.debug.print("control 12345.68781 c.trunc() c:{s}; \r\n",.{c.editCodeFlt("{c}{d:>7}.{d}")}); c.setDcml("-12345.68781"); c.trunc(); std.debug.print("control -12345.68781 c.trunc() c:{s}; \r\n",.{c.editCodeInt("{c}{d:>7}")}); c.setDcml("-12345.68781"); c.round(); std.debug.print("control 12345.68781 c.round() c:{s}; \r\n",.{c.editCodeFlt("{c}{d:>7}.{d}")}); c.setDcml("12345.68781"); c.round(); std.debug.print("control 12345.68781 c.round() c:{s}; \r\n",.{c.editCodeFlt("{c}{d:>7}.{d}")}); std.debug.print("control 12345.68781 c.round() c:{s}; \r\n",.{c.strUFlt()}); c.setZeros(); c.round(); std.debug.print("control 0.0 c.round() c:{s}; \r\n",.{c.editCodeFlt("{c}{d:>7}.{d}")}); std.debug.print("control 0.0 c.round() c:{s}; \r\n",.{c.strUFlt()}); r.setZeros(); const t2 =t.div(r) ; if (!t2) std.debug.print("Division by zeros\n\r",.{}); var n = dcml.init(7,3) ; // set 0 init default n.@"+"(100.25); std.debug.print("n.@+(100.25) n:{s}; \r\n",.{n.string()}); n.@"-"(0.25); std.debug.print("n.@-(0.25) n:{s}; \r\n",.{n.string()}); n.@"*"(5); std.debug.print("n.@*(5) n:{s}; \r\n",.{n.string()}); _=n.@"/"(2); std.debug.print("n.@/(2) n:{s}; \r\n",.{n.string()}); _=n.@"/"(3); std.debug.print("n.@/(3) n:{s}; \r\n",.{n.string()}); pause("deinitDcml()"); dcml.deinitDcml(); const e0 = dcml.Expr{ .Div = .{ .left = &dcml.Expr{ .Val = 2 }, .right = &dcml.Expr{ .Val = 0 }, }, }; try dcml.show(&e0, &stdout); try stdout.print(" = {d}\n", .{dcml.eval(&e0)}); var e1 = dcml.Expr{ .Add = .{ .left = &dcml.Expr{ .Div = .{ .left = &dcml.Expr{ .Val = 2 }, .right = &dcml.Expr{ .Val = 0 }, }, }, .right = &dcml.Expr{ .Val = 1 }, } }; try dcml.show(&e1, &stdout); if (std.math.isNan(dcml.eval(&e1))) try stdout.print(" division par zeros\n", .{}) else try stdout.print(" = {d} \n", .{dcml.eval(&e1)}); e1 = dcml.Expr{ .Add = .{ .left = &dcml.Expr{ .Div = .{ .left = &dcml.Expr{ .Val = -2 }, .right = &dcml.Expr{ .Val = 1 }, }, }, .right = &dcml.Expr{ .Val = -1 }, } }; try dcml.show(&e1, &stdout); if (std.math.isNan(dcml.eval(&e1))) try stdout.print(" division par zeros\n", .{}) else try stdout.print(" = {d} \n", .{dcml.eval(&e1)}); pause("fin"); } fn pause(text : [] const u8) void { std.debug.print("{s}\n",.{text}); var buf : [3]u8 = [_]u8{0} ** 3; _= stdin.readUntilDelimiterOrEof(buf[0..], '\n') catch unreachable; } → 2025-07-10 Standardization, based on AS400 principles
→ 2025-08-22 update version 0.15.1
→ 2025-10-05 add function isNegative value