1use crate::convert::MAX_I128_REPR;
18use crate::error::{DecimalConvertError, DecimalFormatError};
19use crate::u256::{POWERS_10, ROUNDINGS, U256};
20use stack_buf::StackVec;
21use std::cmp::Ordering;
22use std::fmt;
23use std::hash::{Hash, Hasher};
24use std::io;
25
26pub const MAX_PRECISION: u32 = 38;
28pub const MAX_BINARY_SIZE: usize = 18;
30pub const MAX_SCALE: i16 = 130;
31pub const MIN_SCALE: i16 = -126;
32
33const SIGN_MASK: u8 = 0x01;
34const SCALE_MASK: u8 = 0x02;
35const SCALE_SHIFT: u8 = 1;
36
37pub const DECIMAL128: u8 = 1;
39pub const DECIMAL64: u8 = 2;
41pub const DECIMAL64_MAX_PRECISION: u8 = 19;
43
44static NATURAL_EXP: [Decimal; 291] = [
46 unsafe { Decimal::from_raw_parts(1, 0, false) },
48 unsafe { Decimal::from_raw_parts(27182818284590452353602874713526624975, 37, false) },
49 unsafe { Decimal::from_raw_parts(73890560989306502272304274605750078133, 37, false) },
50 unsafe { Decimal::from_raw_parts(20085536923187667740928529654581717900, 36, false) },
51 unsafe { Decimal::from_raw_parts(54598150033144239078110261202860878404, 36, false) },
52 unsafe { Decimal::from_raw_parts(14841315910257660342111558004055227960, 35, false) },
54 unsafe { Decimal::from_raw_parts(40342879349273512260838718054338827962, 35, false) },
55 unsafe { Decimal::from_raw_parts(10966331584284585992637202382881214326, 34, false) },
56 unsafe { Decimal::from_raw_parts(29809579870417282747435920994528886736, 34, false) },
57 unsafe { Decimal::from_raw_parts(81030839275753840077099966894327599646, 34, false) },
58 unsafe { Decimal::from_raw_parts(22026465794806716516957900645284244366, 33, false) },
60 unsafe { Decimal::from_raw_parts(59874141715197818455326485792257781616, 33, false) },
61 unsafe { Decimal::from_raw_parts(16275479141900392080800520489848678316, 32, false) },
62 unsafe { Decimal::from_raw_parts(44241339200892050332610277594908828183, 32, false) },
63 unsafe { Decimal::from_raw_parts(12026042841647767777492367707678594496, 31, false) },
64 unsafe { Decimal::from_raw_parts(32690173724721106393018550460917213156, 31, false) },
66 unsafe { Decimal::from_raw_parts(88861105205078726367630237407814503509, 31, false) },
67 unsafe { Decimal::from_raw_parts(24154952753575298214775435180385823883, 30, false) },
68 unsafe { Decimal::from_raw_parts(65659969137330511138786503259060033570, 30, false) },
69 unsafe { Decimal::from_raw_parts(17848230096318726084491003378872270387, 29, false) },
70 unsafe { Decimal::from_raw_parts(48516519540979027796910683054154055870, 29, false) },
72 unsafe { Decimal::from_raw_parts(13188157344832146972099988837453027850, 28, false) },
73 unsafe { Decimal::from_raw_parts(35849128461315915616811599459784206894, 28, false) },
74 unsafe { Decimal::from_raw_parts(97448034462489026000346326848229752775, 28, false) },
75 unsafe { Decimal::from_raw_parts(26489122129843472294139162152811882340, 27, false) },
76 unsafe { Decimal::from_raw_parts(72004899337385872524161351466126157931, 27, false) },
78 unsafe { Decimal::from_raw_parts(19572960942883876426977639787609534281, 26, false) },
79 unsafe { Decimal::from_raw_parts(53204824060179861668374730434117744164, 26, false) },
80 unsafe { Decimal::from_raw_parts(14462570642914751736770474229969288564, 25, false) },
81 unsafe { Decimal::from_raw_parts(39313342971440420743886205808435276867, 25, false) },
82 unsafe { Decimal::from_raw_parts(10686474581524462146990468650741401654, 24, false) },
84 unsafe { Decimal::from_raw_parts(29048849665247425231085682111679825660, 24, false) },
85 unsafe { Decimal::from_raw_parts(78962960182680695160978022635108224222, 24, false) },
86 unsafe { Decimal::from_raw_parts(21464357978591606462429776153126088037, 23, false) },
87 unsafe { Decimal::from_raw_parts(58346174252745488140290273461039101919, 23, false) },
88 unsafe { Decimal::from_raw_parts(15860134523134307281296446257746601247, 22, false) },
90 unsafe { Decimal::from_raw_parts(43112315471151952271134222928569253911, 22, false) },
91 unsafe { Decimal::from_raw_parts(11719142372802611308772939791190194524, 21, false) },
92 unsafe { Decimal::from_raw_parts(31855931757113756220328671701298645997, 21, false) },
93 unsafe { Decimal::from_raw_parts(86593400423993746953606932719264934249, 21, false) },
94 unsafe { Decimal::from_raw_parts(23538526683701998540789991074903480449, 20, false) },
96 unsafe { Decimal::from_raw_parts(63984349353005494922266340351557081880, 20, false) },
97 unsafe { Decimal::from_raw_parts(17392749415205010473946813036112352260, 19, false) },
98 unsafe { Decimal::from_raw_parts(47278394682293465614744575627442803712, 19, false) },
99 unsafe { Decimal::from_raw_parts(12851600114359308275809299632143099259, 18, false) },
100 unsafe { Decimal::from_raw_parts(34934271057485095348034797233406099546, 18, false) },
102 unsafe { Decimal::from_raw_parts(94961194206024488745133649117118323116, 18, false) },
103 unsafe { Decimal::from_raw_parts(25813128861900673962328580021527338043, 17, false) },
104 unsafe { Decimal::from_raw_parts(70167359120976317386547159988611740555, 17, false) },
105 unsafe { Decimal::from_raw_parts(19073465724950996905250998409538484479, 16, false) },
106 unsafe { Decimal::from_raw_parts(51847055285870724640874533229334853872, 16, false) },
108 unsafe { Decimal::from_raw_parts(14093490824269387964492143312370168789, 15, false) },
109 unsafe { Decimal::from_raw_parts(38310080007165768493035695487861993900, 15, false) },
110 unsafe { Decimal::from_raw_parts(10413759433029087797183472933493796442, 14, false) },
111 unsafe { Decimal::from_raw_parts(28307533032746939004420635480140745403, 14, false) },
112 unsafe { Decimal::from_raw_parts(76947852651420171381827455901293939935, 14, false) },
114 unsafe { Decimal::from_raw_parts(20916594960129961539070711572146737783, 13, false) },
115 unsafe { Decimal::from_raw_parts(56857199993359322226403488206332533049, 13, false) },
116 unsafe { Decimal::from_raw_parts(15455389355901039303530766911174620071, 12, false) },
117 unsafe { Decimal::from_raw_parts(42012104037905142549565934307191617692, 12, false) },
118 unsafe { Decimal::from_raw_parts(11420073898156842836629571831447656295, 11, false) },
120 unsafe { Decimal::from_raw_parts(31042979357019199087073421411071003730, 11, false) },
121 unsafe { Decimal::from_raw_parts(84383566687414544890733294803731179603, 11, false) },
122 unsafe { Decimal::from_raw_parts(22937831594696098790993528402686136005, 10, false) },
123 unsafe { Decimal::from_raw_parts(62351490808116168829092387089284697469, 10, false) },
124 unsafe { Decimal::from_raw_parts(16948892444103337141417836114371974954, 9, false) },
126 unsafe { Decimal::from_raw_parts(46071866343312915426773184428060086892, 9, false) },
127 unsafe { Decimal::from_raw_parts(12523631708422137805135219607443657677, 8, false) },
128 unsafe { Decimal::from_raw_parts(34042760499317405213769071870043505954, 8, false) },
129 unsafe { Decimal::from_raw_parts(92537817255877876002423979166873458740, 8, false) },
130 unsafe { Decimal::from_raw_parts(25154386709191670062657811742521129623, 7, false) },
132 unsafe { Decimal::from_raw_parts(68376712297627438667558928266777109561, 7, false) },
133 unsafe { Decimal::from_raw_parts(18586717452841279803403701812545411949, 6, false) },
134 unsafe { Decimal::from_raw_parts(50523936302761041945570383321857646506, 6, false) },
135 unsafe { Decimal::from_raw_parts(13733829795401761877841885298085389320, 5, false) },
136 unsafe { Decimal::from_raw_parts(37332419967990016402549083172647001445, 5, false) },
138 unsafe { Decimal::from_raw_parts(10148003881138887278324617841317169760, 4, false) },
139 unsafe { Decimal::from_raw_parts(27585134545231702062864698199026619434, 4, false) },
140 unsafe { Decimal::from_raw_parts(74984169969901204346756305912240604567, 4, false) },
141 unsafe { Decimal::from_raw_parts(20382810665126687668323137537172632374, 3, false) },
142 unsafe { Decimal::from_raw_parts(55406223843935100525711733958316612937, 3, false) },
144 unsafe { Decimal::from_raw_parts(15060973145850305483525941301676749817, 2, false) },
145 unsafe { Decimal::from_raw_parts(40939969621274546966609142293278290448, 2, false) },
146 unsafe { Decimal::from_raw_parts(11128637547917594120870714781839408062, 1, false) },
147 unsafe { Decimal::from_raw_parts(30250773222011423382665663964434287432, 1, false) },
148 unsafe { Decimal::from_raw_parts(82230127146229135103043280164077746957, 1, false) },
150 unsafe { Decimal::from_raw_parts(22352466037347150474430657323327147399, 0, false) },
151 unsafe { Decimal::from_raw_parts(60760302250568721495223289381302760758, 0, false) },
152 unsafe { Decimal::from_raw_parts(16516362549940018555283297962648587672, -1, false) },
153 unsafe { Decimal::from_raw_parts(44896128191743452462842455796453162784, -1, false) },
154 unsafe { Decimal::from_raw_parts(12204032943178408020027100351363697548, -2, false) },
156 unsafe { Decimal::from_raw_parts(33174000983357426257555161078525919101, -2, false) },
157 unsafe { Decimal::from_raw_parts(90176284050342989314009959821709052567, -2, false) },
158 unsafe { Decimal::from_raw_parts(24512455429200857855527729431109153420, -3, false) },
159 unsafe { Decimal::from_raw_parts(66631762164108958342448140502408732643, -3, false) },
160 unsafe { Decimal::from_raw_parts(18112390828890232821937987580988159254, -4, false) },
162 unsafe { Decimal::from_raw_parts(49234582860120583997548620591133044956, -4, false) },
163 unsafe { Decimal::from_raw_parts(13383347192042695004617364087061150290, -5, false) },
164 unsafe { Decimal::from_raw_parts(36379709476088045792877438267601857313, -5, false) },
165 unsafe { Decimal::from_raw_parts(98890303193469467705600309671380371021, -5, false) },
166 unsafe { Decimal::from_raw_parts(26881171418161354484126255515800135886, -6, false) },
168 unsafe { Decimal::from_raw_parts(73070599793680672726476826340615135883, -6, false) },
169 unsafe { Decimal::from_raw_parts(19862648361376543258740468906137709930, -7, false) },
170 unsafe { Decimal::from_raw_parts(53992276105801688697616842371936818967, -7, false) },
171 unsafe { Decimal::from_raw_parts(14676622301554423285107021120870470922, -8, false) },
172 unsafe { Decimal::from_raw_parts(39895195705472158507637572787300953989, -8, false) },
174 unsafe { Decimal::from_raw_parts(10844638552900230813361001028568739551, -9, false) },
175 unsafe { Decimal::from_raw_parts(29478783914555093773878202487079276618, -9, false) },
176 unsafe { Decimal::from_raw_parts(80131642640005911410561058362935555141, -9, false) },
177 unsafe { Decimal::from_raw_parts(21782038807290206355539393313936824934, -10, false) },
178 unsafe { Decimal::from_raw_parts(59209720276646702989552288155880397734, -10, false) },
180 unsafe { Decimal::from_raw_parts(16094870669615180549262332993373505801, -11, false) },
181 unsafe { Decimal::from_raw_parts(43750394472613410734625746750879389186, -11, false) },
182 unsafe { Decimal::from_raw_parts(11892590228282008819681954096389267312, -12, false) },
183 unsafe { Decimal::from_raw_parts(32327411910848593114262354205829189194, -12, false) },
184 unsafe { Decimal::from_raw_parts(87875016358370231131069738030496383831, -12, false) },
186 unsafe { Decimal::from_raw_parts(23886906014249914254626392949441611667, -13, false) },
187 unsafe { Decimal::from_raw_parts(64931342556644621362249507087712085619, -13, false) },
188 unsafe { Decimal::from_raw_parts(17650168856917655832911782056447182390, -14, false) },
189 unsafe { Decimal::from_raw_parts(47978133272993021860034882895011331584, -14, false) },
190 unsafe { Decimal::from_raw_parts(13041808783936322797338790280986488115, -15, false) },
192 unsafe { Decimal::from_raw_parts(35451311827611664751894074212478186941, -15, false) },
193 unsafe { Decimal::from_raw_parts(96366656736032012717638730141942241231, -15, false) },
194 unsafe { Decimal::from_raw_parts(26195173187490626761889810253746390880, -16, false) },
195 unsafe { Decimal::from_raw_parts(71205863268893377088330680682701942197, -16, false) },
196 unsafe { Decimal::from_raw_parts(19355760420357225687206244905274872200, -17, false) },
198 unsafe { Decimal::from_raw_parts(52614411826663857451767767041616346183, -17, false) },
199 unsafe { Decimal::from_raw_parts(14302079958348104463583671072905261088, -18, false) },
200 unsafe { Decimal::from_raw_parts(38877084059945950922226736883574780745, -18, false) },
201 unsafe { Decimal::from_raw_parts(10567887114362588125648834960427354587, -19, false) },
202 unsafe { Decimal::from_raw_parts(28726495508178319332673332249621538192, -19, false) },
204 unsafe { Decimal::from_raw_parts(78086710735191511717214963161789844250, -19, false) },
205 unsafe { Decimal::from_raw_parts(21226168683560893890870118295564590878, -20, false) },
206 unsafe { Decimal::from_raw_parts(57698708620330031794130831485493325609, -20, false) },
207 unsafe { Decimal::from_raw_parts(15684135116819639406725212333317378882, -21, false) },
208 unsafe { Decimal::from_raw_parts(42633899483147210448936866880765989362, -21, false) },
210 unsafe { Decimal::from_raw_parts(11589095424138854283480495676005460415, -22, false) },
211 unsafe { Decimal::from_raw_parts(31502427499714519184111642911336978953, -22, false) },
212 unsafe { Decimal::from_raw_parts(85632476224822491931954909086237584537, -22, false) },
213 unsafe { Decimal::from_raw_parts(23277320404788620254741750385140984218, -23, false) },
214 unsafe { Decimal::from_raw_parts(63274317071555853643430245123511451556, -23, false) },
216 unsafe { Decimal::from_raw_parts(17199742630376622641833783925547830056, -24, false) },
217 unsafe { Decimal::from_raw_parts(46753747846325154027207734100637066905, -24, false) },
218 unsafe { Decimal::from_raw_parts(12708986318302188795555166499146091281, -25, false) },
219 unsafe { Decimal::from_raw_parts(34546606567175463231258517866889865270, -25, false) },
220 unsafe { Decimal::from_raw_parts(93907412866476978131540504016909901172, -25, false) },
222 unsafe { Decimal::from_raw_parts(25526681395254551047668755808654353440, -26, false) },
223 unsafe { Decimal::from_raw_parts(69388714177584033016228037440452491187, -26, false) },
224 unsafe { Decimal::from_raw_parts(18861808084906520052196148181812219044, -27, false) },
225 unsafe { Decimal::from_raw_parts(51271710169083297668258887684658163998, -27, false) },
226 unsafe { Decimal::from_raw_parts(13937095806663796973183419371414574787, -28, false) },
228 unsafe { Decimal::from_raw_parts(37884954272746958042494750441949388081, -28, false) },
229 unsafe { Decimal::from_raw_parts(10298198277160991943993878773913738166, -29, false) },
230 unsafe { Decimal::from_raw_parts(27993405242674970683739228910895090969, -29, false) },
231 unsafe { Decimal::from_raw_parts(76093964787853542218200718174787272690, -29, false) },
232 unsafe { Decimal::from_raw_parts(20684484173822473091270347966282423297, -30, false) },
234 unsafe { Decimal::from_raw_parts(56226257460750335807897650819666306371, -30, false) },
235 unsafe { Decimal::from_raw_parts(15283881393781745666100414040841103028, -31, false) },
236 unsafe { Decimal::from_raw_parts(41545897061040224373905771068319348361, -31, false) },
237 unsafe { Decimal::from_raw_parts(11293345702805569478727022021871312858, -32, false) },
238 unsafe { Decimal::from_raw_parts(30698496406442424667364570301654957343, -32, false) },
240 unsafe { Decimal::from_raw_parts(83447164942647743609658358092023252638, -32, false) },
241 unsafe { Decimal::from_raw_parts(22683291210002404713058390312611402982, -33, false) },
242 unsafe { Decimal::from_raw_parts(61659578305794325320049670543781654770, -33, false) },
243 unsafe { Decimal::from_raw_parts(16760811125908827725861073497722332472, -34, false) },
244 unsafe { Decimal::from_raw_parts(45560608313792156880112864411796691453, -34, false) },
246 unsafe { Decimal::from_raw_parts(12384657367292132198269856467846840036, -35, false) },
247 unsafe { Decimal::from_raw_parts(33664989073201642477955778901752989037, -35, false) },
248 unsafe { Decimal::from_raw_parts(91510928052956339360089438336198973142, -35, false) },
249 unsafe { Decimal::from_raw_parts(24875249283177429446603994479964329509, -36, false) },
250 unsafe { Decimal::from_raw_parts(67617938104850097226297739817614724043, -36, false) },
252 unsafe { Decimal::from_raw_parts(18380461242828247026619661332259011810, -37, false) },
253 unsafe { Decimal::from_raw_parts(49963273795075782374799992291440821058, -37, false) },
254 unsafe { Decimal::from_raw_parts(13581425924747849789093255011954118328, -38, false) },
255 unsafe { Decimal::from_raw_parts(36918143295804664423920014322334714971, -38, false) },
256 unsafe { Decimal::from_raw_parts(10035391806143294571946733464755740501, -39, false) },
258 unsafe { Decimal::from_raw_parts(27279023188106115192557593199527116730, -39, false) },
259 unsafe { Decimal::from_raw_parts(74152073030341784283386937576609008214, -39, false) },
260 unsafe { Decimal::from_raw_parts(20156623266094612066329318409141309108, -40, false) },
261 unsafe { Decimal::from_raw_parts(54791382747319794379865564450966140139, -40, false) },
262 unsafe { Decimal::from_raw_parts(14893842007818383595644410230322886973, -41, false) },
264 unsafe { Decimal::from_raw_parts(40485660085792693262271426689569678698, -41, false) },
265 unsafe { Decimal::from_raw_parts(11005143412437994843280976031210742493, -42, false) },
266 unsafe { Decimal::from_raw_parts(29915081357615969207184701601447122427, -42, false) },
267 unsafe { Decimal::from_raw_parts(81317622051281434061126712044925707902, -42, false) },
268 unsafe { Decimal::from_raw_parts(22104421435549887327561037093210488312, -43, false) },
270 unsafe { Decimal::from_raw_parts(60086047116855861250341632178539649714, -43, false) },
271 unsafe { Decimal::from_raw_parts(16333081002168329377271943881088378495, -44, false) },
272 unsafe { Decimal::from_raw_parts(44397917290943821356155881988414973276, -44, false) },
273 unsafe { Decimal::from_raw_parts(12068605179340023095364473314473432497, -45, false) },
274 unsafe { Decimal::from_raw_parts(32805870153846701518250084137059135841, -45, false) },
276 unsafe { Decimal::from_raw_parts(89175600705988431420770803324912086042, -45, false) },
277 unsafe { Decimal::from_raw_parts(24240441494100795852378097352461489720, -46, false) },
278 unsafe { Decimal::from_raw_parts(65892351627238821736753930934534639373, -46, false) },
279 unsafe { Decimal::from_raw_parts(17911398206275708900431827624144225532, -47, false) },
280 unsafe { Decimal::from_raw_parts(48688228266413197067093362018659672146, -47, false) },
282 unsafe { Decimal::from_raw_parts(13234832615645703553069383005626040404, -48, false) },
283 unsafe { Decimal::from_raw_parts(35976005001806811307586628488491091980, -48, false) },
284 unsafe { Decimal::from_raw_parts(97792920656963176027414937748815917871, -48, false) },
285 unsafe { Decimal::from_raw_parts(26582871917376019734003283472389741150, -49, false) },
286 unsafe { Decimal::from_raw_parts(72259737681257492581774770421893056951, -49, false) },
288 unsafe { Decimal::from_raw_parts(19642233186817958656484864137420231201, -50, false) },
289 unsafe { Decimal::from_raw_parts(53393125542082459716222599802082679919, -50, false) },
290 unsafe { Decimal::from_raw_parts(14513756292567525940523654914390132839, -51, false) },
291 unsafe { Decimal::from_raw_parts(39452479992769427900327573211143818566, -51, false) },
292 unsafe { Decimal::from_raw_parts(10724295945198918021924451209369968217, -52, false) },
294 unsafe { Decimal::from_raw_parts(29151658790851239660496155224556382547, -52, false) },
295 unsafe { Decimal::from_raw_parts(79242424360609307491188688802264059684, -52, false) },
296 unsafe { Decimal::from_raw_parts(21540324218248465690209815988756000148, -53, false) },
297 unsafe { Decimal::from_raw_parts(58552671901581093475081587475320346051, -53, false) },
298 unsafe { Decimal::from_raw_parts(15916266403779241591571863407774423364, -54, false) },
300 unsafe { Decimal::from_raw_parts(43264897742306309199371472477969207063, -54, false) },
301 unsafe { Decimal::from_raw_parts(11760618534305001227335647241278102208, -55, false) },
302 unsafe { Decimal::from_raw_parts(31968675653239935348846785115930182070, -55, false) },
303 unsafe { Decimal::from_raw_parts(86899870108103213822063274684049309002, -55, false) },
304 unsafe { Decimal::from_raw_parts(23621833781030833300746567469515129092, -56, false) },
306 unsafe { Decimal::from_raw_parts(64210801521856135516771541362226454717, -56, false) },
307 unsafe { Decimal::from_raw_parts(17454305496765194050281862479081601620, -57, false) },
308 unsafe { Decimal::from_raw_parts(47445721460229655544587842889161196570, -57, false) },
309 unsafe { Decimal::from_raw_parts(12897084248347162974810234147016917437, -58, false) },
310 unsafe { Decimal::from_raw_parts(35057909752387477224025060891275483360, -58, false) },
312 unsafe { Decimal::from_raw_parts(95297279023672025386355634986304892255, -58, false) },
313 unsafe { Decimal::from_raw_parts(25904486187163901031830171287130712546, -59, false) },
314 unsafe { Decimal::from_raw_parts(70415694078135969991088372949671264959, -59, false) },
315 unsafe { Decimal::from_raw_parts(19140970165092820820108477320064452781, -60, false) },
316 unsafe { Decimal::from_raw_parts(52030551378848545923020205358078977737, -60, false) },
318 unsafe { Decimal::from_raw_parts(14143370233782872265039837168370554989, -61, false) },
319 unsafe { Decimal::from_raw_parts(38445666299660540093457531706674996418, -61, false) },
320 unsafe { Decimal::from_raw_parts(10450615608536754863982177507098957249, -62, false) },
321 unsafe { Decimal::from_raw_parts(28407718504895927718534013347769901830, -62, false) },
322 unsafe { Decimal::from_raw_parts(77220184999838357175621252140277020406, -62, false) },
324 unsafe { Decimal::from_raw_parts(20990622567530634724568039312619468559, -63, false) },
325 unsafe { Decimal::from_raw_parts(57058427893360872481970148326895352874, -63, false) },
326 unsafe { Decimal::from_raw_parts(15510088770296358097556054518881247548, -64, false) },
327 unsafe { Decimal::from_raw_parts(42160792462083288741186917596094351517, -64, false) },
328 unsafe { Decimal::from_raw_parts(11460491602311409370637865042895610414, -65, false) },
330 unsafe { Decimal::from_raw_parts(31152846067770590954201464312400440172, -65, false) },
331 unsafe { Decimal::from_raw_parts(84682215370802619418949577677244718361, -65, false) },
332 unsafe { Decimal::from_raw_parts(23019012723610800962705119766260408375, -66, false) },
333 unsafe { Decimal::from_raw_parts(62572163995658794914917604846876973579, -66, false) },
334 unsafe { Decimal::from_raw_parts(17008877635675862685398902860714557440, -67, false) },
336 unsafe { Decimal::from_raw_parts(46234922999541146273426274861568776275, -67, false) },
337 unsafe { Decimal::from_raw_parts(12567955102985587136353369613287969585, -68, false) },
338 unsafe { Decimal::from_raw_parts(34163243977334849966907467619116852824, -68, false) },
339 unsafe { Decimal::from_raw_parts(92865325304802240908397570249090596499, -68, false) },
340 unsafe { Decimal::from_raw_parts(25243412626998187770632793234418799940, -69, false) },
342 unsafe { Decimal::from_raw_parts(68618709832262784296500189663439273040, -69, false) },
343 unsafe { Decimal::from_raw_parts(18652499202934394647893057141276968924, -70, false) },
344 unsafe { Decimal::from_raw_parts(50702749638683390134216749367456409844, -70, false) },
345 unsafe { Decimal::from_raw_parts(13782436299574148088857901819149382333, -71, false) },
346 unsafe { Decimal::from_raw_parts(37464546145026732603499548122029201501, -71, false) },
348 unsafe { Decimal::from_raw_parts(10183919499749154121311809801154593781, -72, false) },
349 unsafe { Decimal::from_raw_parts(27682763318657855929985771603963318292, -72, false) },
350 unsafe { Decimal::from_raw_parts(75249552490640263726958791405721841505, -72, false) },
351 unsafe { Decimal::from_raw_parts(20454949113498251750794190253329225813, -73, false) },
352 unsafe { Decimal::from_raw_parts(55602316477276754174041540473381702051, -73, false) },
354 unsafe { Decimal::from_raw_parts(15114276650041035425200896657072865078, -74, false) },
355 unsafe { Decimal::from_raw_parts(41084863568109398732746435014199662608, -74, false) },
356 unsafe { Decimal::from_raw_parts(11168023806191082975759894188368741636, -75, false) },
357 unsafe { Decimal::from_raw_parts(30357836172167242865270564060096681892, -75, false) },
358 unsafe { Decimal::from_raw_parts(82521154418138915708209187078469436590, -75, false) },
360 unsafe { Decimal::from_raw_parts(22431575451828987090132598854038981998, -76, false) },
361 unsafe { Decimal::from_raw_parts(60975343934414732803540925731945597709, -76, false) },
362 unsafe { Decimal::from_raw_parts(16574816940096003310288868055969816163, -77, false) },
363 unsafe { Decimal::from_raw_parts(45055023698298121117106125112845233389, -77, false) },
364 unsafe { Decimal::from_raw_parts(12247225219987543111692123050999620531, -78, false) },
366 unsafe { Decimal::from_raw_parts(33291409764537471210498902650647395181, -78, false) },
367 unsafe { Decimal::from_raw_parts(90495434206726229847410205869155592671, -78, false) },
368 unsafe { Decimal::from_raw_parts(24599209436265500385962442739613565585, -79, false) },
369 unsafe { Decimal::from_raw_parts(66867584005058783767836195501715462777, -79, false) },
370 unsafe { Decimal::from_raw_parts(18176493851390999782546650445313340672, -80, false) },
372 unsafe { Decimal::from_raw_parts(49408832941333720129685111047602318635, -80, false) },
373 unsafe { Decimal::from_raw_parts(13430713274979613085859250297613421779, -81, false) },
374 unsafe { Decimal::from_raw_parts(36508463838620754258131757683218532187, -81, false) },
375 unsafe { Decimal::from_raw_parts(99240293837476957258975386473680449662, -81, false) },
376 unsafe { Decimal::from_raw_parts(26976308738934978232765417912571366677, -82, false) },
378 unsafe { Decimal::from_raw_parts(73329209843947893397917976493127739665, -82, false) },
379 unsafe { Decimal::from_raw_parts(19932945861406369879404057817936726125, -83, false) },
380 unsafe { Decimal::from_raw_parts(54183364522718865591003756988762312406, -83, false) },
381 unsafe { Decimal::from_raw_parts(14728565518687920080874372478970627032, -84, false) },
382 unsafe { Decimal::from_raw_parts(40036392008717845384002607853055449617, -84, false) },
384 unsafe { Decimal::from_raw_parts(10883019687436065167926658665346876179, -85, false) },
385 unsafe { Decimal::from_raw_parts(29583114655119494191648535413124937628, -85, false) },
386 unsafe { Decimal::from_raw_parts(80415242996231796059259460914427322527, -85, false) },
387 unsafe { Decimal::from_raw_parts(21859129376777539785144693723458114365, -86, false) },
388 unsafe { Decimal::from_raw_parts(59419274170829680786039665041625326132, -86, false) },
390 unsafe { Decimal::from_raw_parts(16151833323879222366041833857187834774, -87, false) },
391 unsafe { Decimal::from_raw_parts(43905235020600150754042953190395882915, -87, false) },
392 unsafe { Decimal::from_raw_parts(11934680253072108439235558933754921818, -88, false) },
393 unsafe { Decimal::from_raw_parts(32441824460394911649740723321265334285, -88, false) },
394 unsafe { Decimal::from_raw_parts(88186021912749658986094822427733469383, -88, false) },
396];
397
398static NATURAL_EXP_NEG: [Decimal; 9] = [
400 unsafe { Decimal::from_raw_parts(41716298478166806118243377939293045745, 164, false) },
402 unsafe { Decimal::from_raw_parts(15346568571889094399003486191226211569, 164, false) },
403 unsafe { Decimal::from_raw_parts(56456870701257797059912015304055553681, 165, false) },
404 unsafe { Decimal::from_raw_parts(20769322043867093362333818538068856442, 165, false) },
405 unsafe { Decimal::from_raw_parts(76406065870075445735958388880036815267, 166, false) },
407 unsafe { Decimal::from_raw_parts(28108220814391766921916452972683068317, 166, false) },
408 unsafe { Decimal::from_raw_parts(10340436565521946602575863724595250916, 166, false) },
409 unsafe { Decimal::from_raw_parts(38040340251929620404917847776950070293, 167, false) },
410 unsafe { Decimal::from_raw_parts(13994259113851392172977837187029463838, 167, false) },
411];
412
413pub(crate) type Buf = stack_buf::StackVec<u8, 256>;
414
415#[derive(Copy, Clone, Debug, Eq)]
417#[repr(C, packed(4))]
418pub struct Decimal {
419 int_val: u128,
420 scale: i16,
422 negative: u8,
424 _aligned: u8,
425}
426
427impl Decimal {
428 pub const ZERO: Decimal = unsafe { Decimal::from_raw_parts(0, 0, false) };
430
431 pub const ONE: Decimal = unsafe { Decimal::from_raw_parts(1, 0, false) };
433
434 const MINUS_ONE: Decimal = unsafe { Decimal::from_raw_parts(1, 0, true) };
436
437 const TWO: Decimal = unsafe { Decimal::from_raw_parts(2, 0, false) };
439
440 const ZERO_POINT_FIVE: Decimal = unsafe { Decimal::from_raw_parts(5, 1, false) };
442
443 #[inline]
444 pub(crate) const unsafe fn from_raw_parts(int_val: u128, scale: i16, negative: bool) -> Decimal {
445 Decimal {
446 int_val,
447 scale,
448 negative: negative as u8,
449 _aligned: 0,
450 }
451 }
452
453 #[inline]
458 pub const unsafe fn from_parts_unchecked(int_val: u128, scale: i16, negative: bool) -> Decimal {
459 if int_val != 0 {
460 unsafe { Decimal::from_raw_parts(int_val, scale, negative) }
461 } else {
462 Decimal::ZERO
463 }
464 }
465
466 #[inline]
470 pub const fn from_parts(int_val: u128, scale: i16, negative: bool) -> Result<Decimal, DecimalConvertError> {
471 if int_val > MAX_I128_REPR as u128 {
472 return Err(DecimalConvertError::Overflow);
473 }
474
475 if scale >= MAX_SCALE + MAX_PRECISION as i16 || scale < MIN_SCALE {
476 return Err(DecimalConvertError::Overflow);
477 }
478
479 Ok(unsafe { Decimal::from_parts_unchecked(int_val, scale, negative) })
480 }
481
482 #[inline]
484 pub const fn into_parts(self) -> (u128, i16, bool) {
485 (self.int_val, self.scale, self.negative())
486 }
487
488 #[inline]
490 pub fn precision(&self) -> u8 {
491 U256::from(self.int_val).count_digits() as u8
492 }
493
494 #[inline(always)]
495 pub(crate) const fn int_val(&self) -> u128 {
496 self.int_val
497 }
498
499 #[inline(always)]
502 pub const fn scale(&self) -> i16 {
503 self.scale
504 }
505
506 #[inline(always)]
507 const fn negative(&self) -> bool {
508 #[allow(clippy::transmute_int_to_bool)]
510 unsafe {
511 std::mem::transmute(self.negative)
512 }
513 }
514
515 #[inline(always)]
517 pub const fn is_sign_negative(&self) -> bool {
518 self.negative()
519 }
520
521 #[inline(always)]
523 pub const fn is_sign_positive(&self) -> bool {
524 !self.negative()
525 }
526
527 #[inline]
529 pub const fn is_zero(&self) -> bool {
530 self.int_val == 0
531 }
532
533 #[inline]
535 pub fn has_fract(&self) -> bool {
536 if self.is_zero() || self.scale <= 0 {
537 false
538 } else if self.scale >= MAX_PRECISION as i16 {
539 true
540 } else {
541 let frac = self.int_val % POWERS_10[self.scale as usize].low();
542 frac != 0
543 }
544 }
545
546 #[inline]
548 pub const fn abs(&self) -> Decimal {
549 let mut abs_val = *self;
550 abs_val.negative = false as u8;
551 abs_val
552 }
553
554 #[inline]
555 pub(crate) const fn neg_mut(&mut self) {
556 if !self.is_zero() {
557 self.negative = !self.negative() as u8;
558 }
559 }
560
561 #[inline]
562 const fn encode_header(&self) -> [u8; 2] {
563 let sign = if self.is_sign_negative() { 1 } else { 0 };
564
565 let (scale_sign, abs_scale) = if self.scale <= 0 {
566 (0, (-self.scale) as u8)
567 } else {
568 (1, self.scale as u8)
569 };
570
571 let flags = (scale_sign << SCALE_SHIFT) | sign;
572
573 [flags, abs_scale]
574 }
575
576 fn internal_encode<W: io::Write, const COMPACT: bool>(&self, mut writer: W) -> std::io::Result<usize> {
579 if self.is_zero() {
580 return if COMPACT {
581 writer.write_all(&[0])?;
582 Ok(1)
583 } else {
584 writer.write_all(&[0; 3])?;
585 Ok(3)
586 };
587 }
588
589 let int_bytes: [u8; 16] = self.int_val.to_le_bytes();
590
591 let leading_zeros = self.int_val.leading_zeros() >> 3;
592 let trailing_non_zeros = 16 - leading_zeros as usize;
593
594 if COMPACT && trailing_non_zeros <= 2 && self.scale == 0 && self.is_sign_positive() {
595 debug_assert_ne!(trailing_non_zeros, 0);
596 return if trailing_non_zeros == 1 {
597 writer.write_all(&int_bytes[0..1])?;
598 Ok(1)
599 } else {
600 writer.write_all(&int_bytes[0..2])?;
601 Ok(2)
602 };
603 }
604
605 let header = self.encode_header();
606 writer.write_all(&header)?;
607 writer.write_all(&int_bytes[0..trailing_non_zeros])?;
608 let size = trailing_non_zeros + 2;
609
610 Ok(size)
611 }
612
613 #[inline]
616 pub fn encode<W: io::Write>(&self, writer: W) -> std::io::Result<usize> {
617 self.internal_encode::<_, false>(writer)
618 }
619
620 #[inline]
626 pub fn compact_encode<W: io::Write>(&self, writer: W) -> std::io::Result<usize> {
627 self.internal_encode::<_, true>(writer)
628 }
629
630 #[inline]
632 pub fn decode(bytes: &[u8]) -> Decimal {
633 let len = bytes.len();
634 assert!(len > 0);
635
636 if len <= 2 {
637 let int_val = if len == 1 {
638 bytes[0] as u128
639 } else {
640 ((bytes[1] as u128) << 8) | (bytes[0] as u128)
641 };
642
643 return unsafe { Decimal::from_parts_unchecked(int_val, 0, false) };
644 }
645
646 let flags = bytes[0];
647 let abs_scale = bytes[1];
648
649 let negative = (flags & SIGN_MASK) == 1;
650 let scale = if (flags & SCALE_MASK) != 0 {
651 abs_scale as i16
652 } else {
653 -(abs_scale as i16)
654 };
655
656 let mut int_bytes = [0; 16];
657 if len < MAX_BINARY_SIZE {
658 int_bytes[0..len - 2].copy_from_slice(&bytes[2..]);
659 } else {
660 int_bytes.copy_from_slice(&bytes[2..MAX_BINARY_SIZE]);
661 }
662 let int = u128::from_le_bytes(int_bytes);
663
664 unsafe { Decimal::from_parts_unchecked(int, scale, negative) }
665 }
666
667 #[inline]
669 pub fn ceil(&self) -> Decimal {
670 if self.scale <= 0 {
671 return *self;
672 }
673
674 if self.scale > MAX_PRECISION as i16 {
675 return if self.negative() { Decimal::ZERO } else { Decimal::ONE };
676 }
677
678 let divisor = POWERS_10[self.scale as usize].low();
679 let int_val = self.int_val / divisor;
680
681 let int_val = if !self.negative() && !self.int_val.is_multiple_of(divisor) {
682 int_val + 1
683 } else {
684 int_val
685 };
686
687 unsafe { Decimal::from_parts_unchecked(int_val, 0, self.negative()) }
688 }
689
690 #[inline]
692 pub fn floor(&self) -> Decimal {
693 if self.scale <= 0 {
694 return *self;
695 }
696
697 if self.scale > MAX_PRECISION as i16 {
698 return if self.negative() {
699 Decimal::MINUS_ONE
700 } else {
701 Decimal::ZERO
702 };
703 }
704
705 let divisor = POWERS_10[self.scale as usize].low();
706 let int_val = self.int_val / divisor;
707
708 let int_val = if !self.negative() || self.int_val.is_multiple_of(divisor) {
709 int_val
710 } else {
711 int_val + 1
712 };
713
714 unsafe { Decimal::from_parts_unchecked(int_val, 0, self.negative()) }
715 }
716
717 #[inline]
721 pub fn trunc(&self, scale: i16) -> Decimal {
722 let real_scale = if !self.is_zero() {
724 scale.max(MIN_SCALE).min(MAX_SCALE + MAX_PRECISION as i16 - 1)
725 } else {
726 return Decimal::ZERO;
727 };
728
729 if self.scale <= real_scale {
730 return *self;
731 }
732
733 let e = self.scale - real_scale;
734 debug_assert!(e > 0);
735 if e > MAX_PRECISION as i16 {
736 return Decimal::ZERO;
737 }
738
739 let int_val = self.int_val / POWERS_10[e as usize].low();
740
741 unsafe { Decimal::from_parts_unchecked(int_val, real_scale, self.negative()) }
742 }
743
744 #[inline]
748 pub fn round(&self, scale: i16) -> Decimal {
749 let real_scale = if !self.is_zero() {
751 scale.max(MIN_SCALE).min(MAX_SCALE + MAX_PRECISION as i16 - 1)
752 } else {
753 return Decimal::ZERO;
754 };
755
756 if self.scale <= real_scale {
757 return *self;
758 }
759
760 let e = self.scale - real_scale;
761 debug_assert!(e > 0);
762 if e > MAX_PRECISION as i16 {
763 return Decimal::ZERO;
764 }
765
766 let int_val = (self.int_val + ROUNDINGS[e as usize].low()) / POWERS_10[e as usize].low();
767
768 unsafe { Decimal::from_parts_unchecked(int_val, real_scale, self.negative()) }
769 }
770
771 #[inline]
775 pub fn round_with_precision(&mut self, precision: u8, scale: i16) -> bool {
776 if self.is_zero() {
777 return false;
778 }
779
780 let e = scale - self.scale;
787 if e >= precision as i16 {
788 return true;
789 }
790
791 if e < -(self.precision() as i16) {
792 *self = Decimal::ZERO;
793 return false;
794 }
795
796 if e >= 0 {
798 let ceil = POWERS_10[(precision as i16 - e) as usize].low();
799 if self.int_val >= ceil {
800 return true;
801 }
802
803 if e == 0 {
804 return false;
805 }
806
807 let val = U256::mul128(self.int_val, POWERS_10[e as usize].low());
808 self.int_val = val.low();
809 } else {
810 let div_result = U256::from(self.int_val).div128_round(POWERS_10[-e as usize].low());
811 let ceil = POWERS_10[precision as usize].low();
812 self.int_val = div_result.low();
813 if self.int_val >= ceil {
814 return true;
815 }
816 }
817
818 self.scale = scale;
819 false
820 }
821
822 #[inline]
824 pub fn normalize_to_scale(&self, scale: i16) -> Decimal {
825 if self.is_zero() {
826 return Decimal::ZERO;
827 }
828
829 if self.scale == scale {
830 return *self;
831 }
832
833 let mut current_scale = self.scale;
834 let mut int_val = self.int_val;
835
836 while current_scale > scale {
837 if !int_val.is_multiple_of(10) {
838 break;
839 }
840
841 int_val /= 10;
842 current_scale -= 1;
843 }
844
845 while current_scale < scale {
846 if int_val >= 10_0000_0000_0000_0000_0000_0000_0000_0000_0000_u128 {
847 break;
848 }
849
850 int_val *= 10;
851 current_scale += 1;
852 }
853
854 unsafe { Decimal::from_parts_unchecked(int_val, current_scale, self.negative()) }
855 }
856
857 #[inline]
859 pub fn normalize(&self) -> Decimal {
860 self.normalize_to_scale(0)
861 }
862
863 #[inline]
864 fn rescale_cmp(&self, other: &Decimal) -> Ordering {
865 debug_assert!(self.scale < other.scale);
866
867 let e = other.scale - self.scale;
868 debug_assert!(e > 0);
869 if e as u32 > MAX_PRECISION {
870 Ordering::Greater
871 } else {
872 let self_int_val = U256::mul128(self.int_val, POWERS_10[e as usize].low());
873 self_int_val.cmp128(other.int_val)
874 }
875 }
876
877 #[inline]
878 fn adjust_scale(int_val: U256, scale: i16, negative: bool) -> Option<Decimal> {
879 let digits = int_val.count_digits();
880 let s = scale as i32 - digits as i32;
881
882 if s >= MAX_SCALE as i32 {
883 return Some(Decimal::ZERO);
884 }
885
886 if s < MIN_SCALE as i32 {
887 return None;
889 }
890
891 if digits > MAX_PRECISION {
892 let shift_scale = (digits - MAX_PRECISION) as i16;
893 return if shift_scale as u32 <= MAX_PRECISION {
894 let dividend = int_val + ROUNDINGS[shift_scale as usize].low();
895 let result = dividend / POWERS_10[shift_scale as usize].low();
896 Some(unsafe { Decimal::from_parts_unchecked(result.low(), scale - shift_scale, negative) })
897 } else {
898 let dividend = int_val + ROUNDINGS[shift_scale as usize];
899 let result = dividend / POWERS_10[shift_scale as usize];
900 Some(unsafe { Decimal::from_parts_unchecked(result.low(), scale - shift_scale, negative) })
901 };
902 }
903
904 Some(unsafe { Decimal::from_parts_unchecked(int_val.low(), scale, negative) })
905 }
906
907 #[inline]
908 fn rescale_add(&self, other: &Decimal, negative: bool) -> Option<Decimal> {
909 debug_assert!(self.scale < other.scale);
910
911 let e = other.scale - self.scale;
912 debug_assert!(e > 0);
913 if e as u32 > MAX_PRECISION {
914 if self.is_zero() {
915 return Some(unsafe { Decimal::from_parts_unchecked(other.int_val, other.scale, negative) });
916 }
917 if other.is_zero() {
918 return Some(unsafe { Decimal::from_parts_unchecked(self.int_val, self.scale, negative) });
919 }
920 if (e as usize) < POWERS_10.len() {
921 if let Some(self_int_val) = POWERS_10[e as usize].checked_mul(self.int_val) {
922 if let Some(int_val) = self_int_val.checked_add(other.int_val) {
923 return Decimal::adjust_scale(int_val, other.scale, negative);
924 }
925 }
926 }
927
928 return Some(unsafe { Decimal::from_parts_unchecked(self.int_val, self.scale, negative) });
929 }
930
931 let self_int_val = U256::mul128(self.int_val, POWERS_10[e as usize].low());
932 let int_val = self_int_val + other.int_val;
933 Decimal::adjust_scale(int_val, other.scale, negative)
934 }
935
936 #[inline]
937 fn add_internal(&self, other: &Decimal, negative: bool) -> Option<Decimal> {
938 if self.scale != other.scale {
939 return if self.scale < other.scale {
940 self.rescale_add(other, negative)
941 } else {
942 other.rescale_add(self, negative)
943 };
944 }
945
946 let int_val = U256::add128(self.int_val, other.int_val);
947 if !int_val.is_decimal_overflowed() && self.scale >= 0 {
948 return Some(unsafe { Decimal::from_parts_unchecked(int_val.low(), self.scale, negative) });
949 }
950
951 Decimal::adjust_scale(int_val, self.scale, negative)
952 }
953
954 #[inline]
956 const unsafe fn add_internal_with_same_scale<const DECIMAL_MODEL: u8>(
957 &self,
958 other: &Decimal,
959 negative: bool,
960 scale: i16,
961 ) -> Decimal {
962 debug_assert!(self.scale == scale || self.is_zero());
963 debug_assert!(other.scale == scale || other.is_zero());
964 let val = match DECIMAL_MODEL {
965 DECIMAL64 => (self.int_val as u64 + other.int_val as u64) as u128,
966 _ => self.int_val + other.int_val,
967 };
968
969 unsafe { Decimal::from_parts_unchecked(val, scale, negative) }
970 }
971
972 #[inline]
973 fn rescale_sub(&self, other: &Decimal, negative: bool) -> Option<Decimal> {
974 debug_assert!(self.scale < other.scale);
975
976 let e = other.scale - self.scale;
977 debug_assert!(e > 0);
978 if e as u32 > MAX_PRECISION {
979 if (e as usize) < POWERS_10.len() {
980 if let Some(self_int_val) = POWERS_10[e as usize].checked_mul(self.int_val) {
981 if let Some(int_val) = self_int_val.checked_sub(other.int_val) {
982 return Decimal::adjust_scale(int_val, other.scale, negative);
983 }
984 }
985 }
986
987 return Some(unsafe { Decimal::from_parts_unchecked(self.int_val(), self.scale, negative) });
988 }
989
990 let self_int_val = U256::mul128(self.int_val(), POWERS_10[e as usize].low());
991 let (int_val, neg) = if self_int_val >= other.int_val() {
992 let result = self_int_val - other.int_val();
993 (result, negative)
994 } else {
995 let result = other.int_val() - self_int_val;
996 (U256::from(result), !negative)
997 };
998
999 Decimal::adjust_scale(int_val, other.scale, neg)
1000 }
1001
1002 #[inline]
1003 fn sub_internal(&self, other: &Decimal, negative: bool) -> Option<Decimal> {
1004 if other.int_val == 0 {
1005 return Some(*self);
1006 }
1007
1008 if self.int_val == 0 {
1009 return Some(unsafe { Decimal::from_parts_unchecked(other.int_val, other.scale, !negative) });
1010 }
1011
1012 if self.scale != other.scale {
1013 return if self.scale < other.scale {
1014 self.rescale_sub(other, negative)
1015 } else {
1016 other.rescale_sub(self, !negative)
1017 };
1018 }
1019
1020 debug_assert_eq!(self.scale, other.scale);
1021 let (val, neg) = if self.int_val >= other.int_val {
1022 (self.int_val - other.int_val, negative)
1023 } else {
1024 (other.int_val - self.int_val, !negative)
1025 };
1026
1027 Some(unsafe { Decimal::from_parts_unchecked(val, self.scale, neg) })
1028 }
1029
1030 #[inline]
1031 const unsafe fn sub_internal_with_same_scale<const DECIMAL_MODEL: u8>(
1032 &self,
1033 other: &Decimal,
1034 negative: bool,
1035 scale: i16,
1036 ) -> Decimal {
1037 debug_assert!(self.scale == scale || self.is_zero());
1038 debug_assert!(other.scale == scale || other.is_zero());
1039 let (val, neg) = match DECIMAL_MODEL {
1040 DECIMAL64 => {
1041 let l = self.int_val as u64;
1042 let r = other.int_val as u64;
1043 if l >= r {
1044 ((l - r) as u128, negative)
1045 } else {
1046 ((r - l) as u128, !negative)
1047 }
1048 }
1049 _ => {
1050 if self.int_val >= other.int_val {
1051 (self.int_val - other.int_val, negative)
1052 } else {
1053 (other.int_val - self.int_val, !negative)
1054 }
1055 }
1056 };
1057 unsafe { Decimal::from_parts_unchecked(val, scale, neg) }
1058 }
1059
1060 #[inline]
1063 pub fn checked_add(&self, other: impl AsRef<Decimal>) -> Option<Decimal> {
1064 let other = other.as_ref();
1065 if self.negative() != other.negative() {
1066 if other.negative() {
1067 self.sub_internal(other, self.negative())
1068 } else {
1069 other.sub_internal(self, other.negative())
1070 }
1071 } else {
1072 self.add_internal(other, self.negative())
1073 }
1074 }
1075
1076 #[inline]
1080 pub const unsafe fn add_with_same_scale_unchecked<const DECIMAL_MODEL: u8>(
1081 &self,
1082 other: &Decimal,
1083 scale: i16,
1084 ) -> Decimal {
1085 if self.negative() != other.negative() {
1086 if other.negative() {
1087 unsafe { self.sub_internal_with_same_scale::<DECIMAL_MODEL>(other, self.negative(), scale) }
1088 } else {
1089 unsafe { other.sub_internal_with_same_scale::<DECIMAL_MODEL>(self, other.negative(), scale) }
1090 }
1091 } else {
1092 unsafe { self.add_internal_with_same_scale::<DECIMAL_MODEL>(other, self.negative(), scale) }
1093 }
1094 }
1095
1096 #[inline]
1103 pub const unsafe fn add_with_same_scale_and_negative_unchecked<const DECIMAL_MODEL: u8>(
1104 &self,
1105 other: &Decimal,
1106 scale: i16,
1107 negative: bool,
1108 ) -> Decimal {
1109 debug_assert!(self.negative() == negative || self.is_zero());
1110 debug_assert!(other.negative() == negative || other.is_zero());
1111 unsafe { self.add_internal_with_same_scale::<DECIMAL_MODEL>(other, negative, scale) }
1112 }
1113
1114 #[inline]
1117 pub fn checked_sub(&self, other: impl AsRef<Decimal>) -> Option<Decimal> {
1118 let other = other.as_ref();
1119 if self.negative() != other.negative() {
1120 self.add_internal(other, self.negative())
1121 } else if self.negative() {
1122 other.sub_internal(self, !self.negative())
1123 } else {
1124 self.sub_internal(other, self.negative())
1125 }
1126 }
1127
1128 #[inline]
1132 pub const unsafe fn sub_with_same_scale_unchecked<const DECIMAL_MODEL: u8>(
1133 &self,
1134 other: &Decimal,
1135 scale: i16,
1136 ) -> Decimal {
1137 if self.negative() != other.negative() {
1138 unsafe { self.add_internal_with_same_scale::<DECIMAL_MODEL>(other, self.negative(), scale) }
1139 } else if self.negative() {
1140 unsafe { other.sub_internal_with_same_scale::<DECIMAL_MODEL>(self, !self.negative(), scale) }
1141 } else {
1142 unsafe { self.sub_internal_with_same_scale::<DECIMAL_MODEL>(other, self.negative(), scale) }
1143 }
1144 }
1145
1146 #[inline]
1149 pub fn checked_mul(&self, other: impl AsRef<Decimal>) -> Option<Decimal> {
1150 let other = other.as_ref();
1151
1152 if self.is_zero() || other.is_zero() {
1153 return Some(Decimal::ZERO);
1154 }
1155
1156 let scale = self.scale + other.scale;
1157 let negative = self.negative() ^ other.negative();
1158 let int_val = U256::mul128(self.int_val, other.int_val);
1159
1160 if !int_val.is_decimal_overflowed() && scale == 0 {
1161 Some(unsafe { Decimal::from_parts_unchecked(int_val.low(), 0, negative) })
1162 } else {
1163 Decimal::adjust_scale(int_val, scale, negative)
1164 }
1165 }
1166
1167 #[inline]
1171 pub const unsafe fn mul_unchecked<const DECIMAL_MODEL: u8>(&self, other: &Decimal, scale: i16) -> Decimal {
1172 let negative = self.negative() ^ other.negative();
1173 let val = match DECIMAL_MODEL {
1174 DECIMAL64 => ((self.int_val) as u64 * (other.int_val as u64)) as u128,
1175 _ => self.int_val * other.int_val,
1176 };
1177 unsafe { Decimal::from_parts_unchecked(val, scale, negative) }
1178 }
1179
1180 #[inline]
1183 pub fn checked_div(&self, other: impl AsRef<Decimal>) -> Option<Decimal> {
1184 let other = other.as_ref();
1185
1186 if other.is_zero() {
1187 return None;
1188 }
1189
1190 if self.is_zero() {
1191 return Some(Decimal::ZERO);
1192 }
1193
1194 let other_precision = other.precision();
1195 let self_precision = self.precision();
1196
1197 let (self_int_val, shift_precision) = if other_precision > self_precision {
1198 let p = MAX_PRECISION + (other_precision - self_precision) as u32;
1199 (POWERS_10[p as usize] * self.int_val, other_precision - self_precision)
1200 } else {
1201 (U256::mul128(self.int_val, POWERS_10[MAX_PRECISION as usize].low()), 0)
1202 };
1203
1204 let negative = self.negative() ^ other.negative();
1205 let int_val = self_int_val.div128_round(other.int_val);
1206 let scale = self.scale - other.scale + MAX_PRECISION as i16 + shift_precision as i16;
1207
1208 Decimal::adjust_scale(int_val, scale, negative)
1209 }
1210
1211 #[inline]
1214 pub fn checked_rem(&self, other: impl AsRef<Decimal>) -> Option<Decimal> {
1215 let other = other.as_ref();
1216
1217 if other.is_zero() {
1218 return None;
1219 }
1220
1221 if self.is_zero() {
1222 return Some(Decimal::ZERO);
1223 }
1224
1225 if self.scale == other.scale {
1226 let rem = self.int_val % other.int_val;
1227 return Some(unsafe { Decimal::from_parts_unchecked(rem, self.scale, self.negative()) });
1228 }
1229
1230 if self.scale < other.scale {
1231 let e = other.scale - self.scale;
1232 debug_assert!(e > 0);
1233
1234 let mut res = *self;
1235 loop {
1236 let scale = (MAX_PRECISION as i16).min(other.scale - res.scale);
1237 let res_val = U256::mul128(res.int_val, POWERS_10[scale as usize].low());
1238 let rem = res_val % other.int_val;
1239 res = unsafe { Decimal::from_parts_unchecked(rem.low(), res.scale + scale, res.negative()) };
1240 if res.scale == other.scale || res.is_zero() {
1241 break;
1242 }
1243 }
1244 Some(res)
1245 } else {
1246 let e = self.scale - other.scale;
1247 debug_assert!(e > 0);
1248 if e as u32 > MAX_PRECISION {
1249 return Some(*self);
1250 }
1251
1252 let other_int_val = U256::mul128(other.int_val, POWERS_10[e as usize].low());
1253 let rem = self.int_val % other_int_val;
1254 debug_assert_eq!(rem.high(), 0);
1255
1256 Some(unsafe { Decimal::from_parts_unchecked(rem.low(), self.scale, self.negative()) })
1257 }
1258 }
1259
1260 #[inline]
1263 pub fn sqrt(&self) -> Option<Decimal> {
1264 if self.negative() {
1265 return None;
1266 }
1267
1268 if self.is_zero() {
1269 return Some(Decimal::ZERO);
1270 }
1271
1272 let mut result = Decimal::ONE;
1273 let mut last = result;
1274
1275 loop {
1276 let val = self.checked_div(result)?.normalize();
1277 result = result.checked_add(val)?;
1278 result = result.checked_mul(Decimal::ZERO_POINT_FIVE)?;
1279
1280 if result == last {
1281 break;
1282 }
1283
1284 last = result;
1285 }
1286
1287 Some(result)
1288 }
1289
1290 #[inline]
1292 pub fn simply_format<W: fmt::Write>(&self, w: W) -> Result<(), DecimalFormatError> {
1293 self.fmt_internal(true, true, true, None, w)
1294 }
1295
1296 #[inline]
1297 pub(crate) fn fmt_internal<W: fmt::Write>(
1298 &self,
1299 append_sign: bool,
1300 omit_integer_zero: bool,
1301 omit_frac_ending_zero: bool,
1302 expected_scale: Option<usize>,
1303 mut w: W,
1304 ) -> Result<(), DecimalFormatError> {
1305 use std::fmt::Write;
1306
1307 const ZERO_BUF: [u8; 256] = [b'0'; 256];
1308
1309 if self.is_zero() {
1310 w.write_byte(b'0')?;
1311 return Ok(());
1312 }
1313
1314 let dec = if let Some(scale) = expected_scale {
1315 self.round(scale as i16)
1316 } else {
1317 *self
1318 };
1319
1320 let scale = dec.scale();
1321
1322 if append_sign && self.is_sign_negative() {
1323 w.write_byte(b'-')?;
1324 }
1325
1326 if scale <= 0 {
1327 write!(w, "{}", dec.int_val())?;
1328 w.write_bytes(&ZERO_BUF[..-scale as usize])?;
1329 if let Some(s) = expected_scale {
1330 if s != 0 {
1331 w.write_byte(b'.')?;
1332 w.write_bytes(&ZERO_BUF[..s])?;
1333 }
1334 }
1335 } else {
1336 let mut buf = StackVec::<u8, 40>::new();
1337 write!(&mut buf, "{}", dec.int_val())?;
1338 let digits = buf.as_slice();
1339
1340 let len = digits.len();
1341 if len <= scale as usize {
1342 if !omit_integer_zero {
1343 w.write_byte(b'0')?;
1344 }
1345 w.write_byte(b'.')?;
1346 w.write_bytes(&ZERO_BUF[..scale as usize - len])?;
1347 if omit_frac_ending_zero {
1348 let zero_num = digits.iter().rev().take_while(|ch| **ch == b'0').count();
1349 w.write_bytes(&digits[0..len - zero_num])?;
1350 } else {
1351 w.write_bytes(digits)?;
1352 }
1353 } else {
1354 let (int_digits, frac_digits) = digits.split_at(len - scale as usize);
1355 w.write_bytes(int_digits)?;
1356 let frac_len = frac_digits.len();
1357 let zero_num = frac_digits.iter().rev().take_while(|ch| **ch == b'0').count();
1358 if let Some(s) = expected_scale {
1359 if s > frac_len {
1360 if !omit_frac_ending_zero {
1361 w.write_byte(b'.')?;
1362 w.write_bytes(frac_digits)?;
1363 w.write_bytes(&ZERO_BUF[..s - frac_len])?;
1364 } else if zero_num < frac_len {
1365 w.write_byte(b'.')?;
1366 w.write_bytes(&frac_digits[0..frac_len - zero_num])?;
1367 }
1368 } else if !omit_frac_ending_zero {
1369 w.write_byte(b'.')?;
1370 w.write_bytes(&frac_digits[0..s])?;
1371 } else if zero_num < frac_len {
1372 w.write_byte(b'.')?;
1373 let end = s.min(frac_len - zero_num);
1374 w.write_bytes(&frac_digits[0..end])?;
1375 }
1376 } else if zero_num < frac_len {
1377 w.write_byte(b'.')?;
1378 w.write_bytes(&frac_digits[0..frac_len - zero_num])?;
1379 }
1380 }
1381 }
1382
1383 Ok(())
1384 }
1385
1386 #[inline]
1387 fn fmt_sci_internal<W: fmt::Write, const POSITIVE_EXP: bool, const MIN_SCALE: i16>(
1388 &self,
1389 expect_scale: i16,
1390 mut exp: u16,
1391 mut w: W,
1392 ) -> Result<(), DecimalFormatError> {
1393 if expect_scale >= MIN_SCALE {
1394 let temp_scale = if POSITIVE_EXP {
1396 expect_scale - exp as i16
1397 } else {
1398 expect_scale + exp as i16
1399 };
1400
1401 let mut dec = self.round(temp_scale);
1402
1403 if dec.precision() > self.trunc(temp_scale).precision() {
1405 if POSITIVE_EXP { exp += 1 } else { exp -= 1 }
1406 }
1407
1408 if POSITIVE_EXP {
1410 dec.scale += exp as i16
1411 } else {
1412 dec.scale -= exp as i16
1413 };
1414
1415 dec.fmt_internal(true, true, false, Some(expect_scale as usize), &mut w)?;
1417
1418 if POSITIVE_EXP {
1419 write_exp(b"E+", exp, true, w)?;
1420 } else {
1421 write_exp(b"E-", exp, true, w)?;
1422 }
1423 } else {
1424 return Err(DecimalFormatError::OutOfRange);
1425 }
1426
1427 Ok(())
1428 }
1429
1430 #[inline]
1432 pub fn format_with_sci<W: fmt::Write>(&self, max_width: u16, mut w: W) -> Result<(), DecimalFormatError> {
1433 const DOT_LEN: u16 = 1; if self.is_zero() {
1436 w.write_byte(b'0')?;
1437 return Ok(());
1438 }
1439
1440 let precision = self.precision() as i16;
1441 let sign_len = if self.negative() { 1 } else { 0 };
1442 let max_digits = max_width - sign_len;
1444
1445 let (use_sci, positive_exp, prec): (bool, bool, Option<usize>) = if self.scale < precision {
1446 let int_len = (precision - self.scale) as u16;
1448 if max_digits >= int_len {
1449 if max_digits == int_len {
1450 (false, true, Some(0))
1451 } else {
1452 let scale = (max_digits - int_len - DOT_LEN) as usize;
1454 if scale as i16 >= self.scale() {
1455 (false, true, None)
1456 } else {
1457 (false, true, Some(scale))
1458 }
1459 }
1460 } else {
1461 (true, true, None)
1463 }
1464 } else if self.scale - precision >= 5 {
1465 if max_digits < self.scale as u16 + DOT_LEN {
1466 (true, false, None)
1468 } else {
1469 (false, true, None)
1470 }
1471 } else {
1472 let scale = max_width as usize - 1;
1474 (false, true, Some(scale))
1475 };
1476
1477 if use_sci {
1478 const E_NOTATION_LEN: usize = 2; const SCI_INT_LEN: i16 = 2; let exp = (precision - self.scale - 1).unsigned_abs();
1483 let exp_len = E_NOTATION_LEN + if exp < 100 { 2 } else { 3 };
1485 let expect_scale = max_digits as i16 - exp_len as i16 - SCI_INT_LEN;
1487
1488 const MIN_SCALE: i16 = 1;
1489 if positive_exp {
1490 self.fmt_sci_internal::<W, true, MIN_SCALE>(expect_scale, exp, w)?;
1491 } else {
1492 self.fmt_sci_internal::<W, false, MIN_SCALE>(expect_scale, exp, w)?;
1493 }
1494 } else {
1495 self.fmt_internal(true, true, true, prec, w)?;
1496 }
1497
1498 Ok(())
1499 }
1500
1501 #[inline]
1506 pub fn format_with_sci_forced<W: fmt::Write>(
1507 &self,
1508 expect_scale: i16,
1509 with_zero_before_dot: bool,
1510 mut w: W,
1511 ) -> Result<(), DecimalFormatError> {
1512 const MAX_SCALE: usize = 56;
1514 if expect_scale > MAX_SCALE as i16 {
1515 return Err(DecimalFormatError::OutOfRange);
1516 }
1517 let precision = self.precision() as i16;
1518 let exp = (precision - self.scale - 1).unsigned_abs();
1519 let positive_exp = precision > self.scale;
1520
1521 if self.is_zero() && expect_scale > 0 {
1522 const ZERO_BUF: [u8; MAX_SCALE] = [b'0'; MAX_SCALE];
1523 if with_zero_before_dot {
1524 w.write_bytes(b"0.")?;
1525 } else {
1526 w.write_bytes(b" .")?;
1527 }
1528 w.write_bytes(&ZERO_BUF[..expect_scale as usize - 1])?;
1529 }
1530
1531 const MIN_SCALE: i16 = 0;
1532 if positive_exp {
1533 self.fmt_sci_internal::<W, true, MIN_SCALE>(expect_scale, exp, w)?;
1534 } else {
1535 self.fmt_sci_internal::<W, false, MIN_SCALE>(expect_scale, exp, w)?;
1536 }
1537 Ok(())
1538 }
1539
1540 #[inline]
1544 pub fn format_to_hex<W: fmt::Write>(&self, is_uppercase: bool, mut w: W) -> Result<(), DecimalFormatError> {
1545 const MAX_DECIMAL: Decimal =
1547 unsafe { Decimal::from_parts_unchecked(72370055773322622139731865630429942408, -38, false) };
1548
1549 if self.is_sign_negative() || self > MAX_DECIMAL {
1550 return Err(DecimalFormatError::OutOfRange);
1551 }
1552
1553 let integer = self.round(0);
1554 let real_num = POWERS_10[(-integer.scale) as usize] * integer.int_val;
1555 if is_uppercase {
1556 if real_num.high() != 0 {
1557 write!(&mut w, "{:X}", real_num.high())?;
1558 }
1559 write!(&mut w, "{:X}", real_num.low())?;
1560 } else {
1561 if real_num.high() != 0 {
1562 write!(&mut w, "{:x}", real_num.high())?;
1563 }
1564 write!(&mut w, "{:x}", real_num.low())?;
1565 }
1566
1567 Ok(())
1568 }
1569
1570 #[inline]
1572 pub fn format_to_json<W: fmt::Write>(&self, mut w: W) -> Result<(), DecimalFormatError> {
1573 if self.is_zero() {
1574 w.write_byte(b'0')?;
1575 return Ok(());
1576 }
1577
1578 const MAX_WIDTH: i16 = 40;
1579
1580 let precision = self.precision() as i16;
1581 let use_sci = if self.scale <= 0 {
1582 precision - self.scale > MAX_WIDTH
1583 } else {
1584 let mut int_val = self.int_val;
1585 let mut zero_count = 0;
1586 while int_val != 0 {
1587 if !int_val.is_multiple_of(10) {
1588 break;
1589 }
1590 zero_count += 1;
1591 int_val /= 10;
1592 }
1593 self.scale - zero_count > MAX_WIDTH
1594 };
1595
1596 if !use_sci {
1597 return self.fmt_internal(true, false, true, None, w);
1598 }
1599
1600 let mut dec = *self;
1601 let positive_exp = precision > dec.scale;
1602 let exp = (precision - dec.scale - 1).unsigned_abs();
1603 if positive_exp {
1604 dec.scale += exp as i16;
1605 dec.fmt_internal(true, false, true, None, &mut w)?;
1606 write_exp(b"E+", exp, false, w)?;
1607 } else {
1608 dec.scale -= exp as i16;
1609 dec.fmt_internal(true, false, true, None, &mut w)?;
1610 write_exp(b"E-", exp, false, w)?;
1611 };
1612
1613 Ok(())
1614 }
1615
1616 #[inline]
1620 fn pow_u64(&self, exponent: u64) -> Option<Decimal> {
1621 match exponent {
1622 0 => Some(Decimal::ONE),
1623 1 => Some(*self),
1624 2 => self.checked_mul(self),
1625 _ => {
1626 let x = *self;
1633 let mut n = exponent;
1634 let mut sum = Decimal::ONE;
1635 let mut power_x = x;
1636
1637 if n & 1 == 1 {
1640 sum = sum.checked_mul(power_x)?;
1641 }
1642 n >>= 1;
1643
1644 while n != 0 {
1645 power_x = power_x.checked_mul(power_x)?;
1646 if n & 1 == 1 {
1647 sum = sum.checked_mul(power_x)?;
1648 }
1649 n >>= 1;
1650 }
1651
1652 Some(sum)
1653 }
1654 }
1655 }
1656
1657 #[inline]
1660 fn pow_quick_range(&self, exponent: u64) -> bool {
1661 const BASE_UPPER_BOUND1: Decimal = unsafe { Decimal::from_parts_unchecked(1163, 0, false) };
1669 const EXP_UPPER_BOUND1: u64 = 42;
1670 const BASE_UPPER_BOUND2: Decimal = unsafe { Decimal::from_parts_unchecked(125, 0, false) };
1671 const EXP_UPPER_BOUND2: u64 = 61;
1672 const BASE_UPPER_BOUND3: Decimal = unsafe { Decimal::from_parts_unchecked(1, -1, false) };
1673 const EXP_UPPER_BOUND3: u64 = 126;
1674
1675 (exponent < EXP_UPPER_BOUND1 && *self < BASE_UPPER_BOUND1)
1676 || (exponent < EXP_UPPER_BOUND2 && *self < BASE_UPPER_BOUND2)
1677 || (exponent < EXP_UPPER_BOUND3 && *self < BASE_UPPER_BOUND3)
1678 }
1679
1680 #[inline]
1685 fn pow_i64(&self, exponent: i64) -> Option<Decimal> {
1686 if exponent >= 0 {
1687 return self.pow_u64(exponent as u64);
1688 }
1689 if self.is_zero() {
1691 return None;
1692 }
1693
1694 let x = *self;
1699 let y = exponent.unsigned_abs();
1700
1701 let result = if x.pow_quick_range(y) {
1703 Decimal::ONE.checked_div(x.pow_u64(y)?)?
1705 } else {
1706 match x.pow_u64(y / 2) {
1714 Some(p) => {
1715 let power = Decimal::ONE.checked_div(p)?.checked_div(p)?;
1716 if y % 2 == 1 { power.checked_div(x)? } else { power }
1717 }
1718 None => Decimal::ZERO,
1720 }
1721 };
1722
1723 Some(result)
1724 }
1725
1726 #[inline]
1730 fn pow_decimal_integral(&self, exponent: &Decimal) -> Option<Decimal> {
1731 debug_assert!((exponent.int_val == exponent.normalize().int_val) && (exponent.scale() <= 0));
1732
1733 if exponent.is_sign_negative() {
1734 if *exponent < Decimal::from(i16::MIN) {
1736 return self.pow_decimal(exponent);
1737 }
1738
1739 self.pow_i64(-(exponent.int_val as i64))
1740 } else {
1741 if *exponent > Decimal::from(u16::MAX) {
1743 return self.pow_decimal(exponent);
1744 }
1745
1746 self.pow_u64(exponent.int_val as u64)
1747 }
1748 }
1749
1750 #[inline]
1755 fn pow_decimal(&self, exponent: &Decimal) -> Option<Decimal> {
1756 debug_assert!((*self > Decimal::ZERO) || (exponent.normalize().scale() <= 0));
1757
1758 let x = self.abs();
1765 let b = *exponent;
1766
1767 let ln = x.ln()?;
1768 let exp = ln.checked_mul(b)?;
1769 let mut result = exp.exp()?;
1770
1771 if self.negative() && b.checked_rem(Decimal::TWO)? == Decimal::ONE {
1772 result = -result;
1773 }
1774
1775 Some(result)
1776 }
1777
1778 #[inline]
1783 pub fn checked_pow(&self, exponent: &Decimal) -> Option<Decimal> {
1784 if exponent.is_zero() {
1785 return Some(Decimal::ONE);
1786 }
1787 if self.is_zero() {
1788 if exponent.is_sign_negative() {
1790 return None;
1791 }
1792 return Some(Decimal::ZERO);
1793 }
1794 if *self == Decimal::ONE {
1795 return Some(Decimal::ONE);
1796 }
1797 if exponent == Decimal::ONE {
1798 return Some(*self);
1799 }
1800
1801 let exponent = exponent.normalize();
1802 if exponent.scale() <= 0 {
1804 return self.pow_decimal_integral(&exponent);
1805 }
1806
1807 if self.is_sign_negative() {
1809 return None;
1810 }
1811
1812 let x = *self;
1819 let n = exponent;
1820
1821 let a = n.trunc(0);
1822 let b = n.checked_sub(a)?;
1823
1824 let power_a = x.pow_decimal_integral(&a)?;
1825 let power_b = x.pow_decimal(&b)?;
1826
1827 let result = power_a.checked_mul(power_b)?;
1829
1830 Some(result)
1831 }
1832
1833 #[inline]
1836 pub fn ln(&self) -> Option<Decimal> {
1837 const ZERO_POINT_ONE: Decimal = unsafe { Decimal::from_parts_unchecked(1, 1, false) };
1838 const ONE_POINT_ONE: Decimal = unsafe { Decimal::from_parts_unchecked(11, 1, false) };
1839 const TEN: Decimal = unsafe { Decimal::from_parts_unchecked(10, 0, false) };
1840 const LOWER_BOUND: Decimal = unsafe { Decimal::from_parts_unchecked(9047, 4, false) };
1841 const R: Decimal = unsafe { Decimal::from_parts_unchecked(12217, 4, false) };
1843 const LN_10: Decimal =
1844 unsafe { Decimal::from_parts_unchecked(23025850929940456840179914546843642076, 37, false) };
1845 const LN_R: Decimal =
1847 unsafe { Decimal::from_parts_unchecked(2002433314278771112016301166984297937, 37, false) };
1848
1849 if self.is_sign_negative() || self.is_zero() {
1851 return None;
1852 }
1853
1854 if *self == Decimal::ONE {
1855 return Some(Decimal::ZERO);
1856 }
1857
1858 let mut x = *self;
1874 let mut n1 = 0;
1875 let mut n2 = 0;
1876
1877 while x > ONE_POINT_ONE {
1879 x = x.checked_mul(ZERO_POINT_ONE)?;
1880 n1 += 1;
1881 }
1882 while x <= ZERO_POINT_ONE {
1883 x = x.checked_mul(TEN)?;
1884 n1 -= 1;
1885 }
1886
1887 while x < LOWER_BOUND {
1889 x = x.checked_mul(R)?;
1890 n2 -= 1;
1891 }
1892
1893 let z = x;
1895 let y = z.checked_sub(Decimal::ONE)?.checked_div(z.checked_add(Decimal::ONE)?)?;
1896 let y_square = y.checked_mul(y)?;
1897
1898 let mut sum = y;
1900 let mut power_y = y;
1901 let mut last;
1902 let mut iter = 1;
1903
1904 loop {
1905 iter += 2;
1906 power_y = power_y.checked_mul(y_square)?;
1907 let term = power_y.checked_div(Decimal::from(iter))?;
1908
1909 if term.is_zero() {
1910 break;
1911 }
1912
1913 last = sum;
1914 sum = sum.checked_add(term)?;
1915
1916 if last == sum {
1917 break;
1918 }
1919 }
1920
1921 let ln_z = sum.checked_mul(Decimal::TWO)?;
1922
1923 let mut result = ln_z.checked_add(LN_10.checked_mul(Decimal::from(n1))?)?;
1925 result = result.checked_add(LN_R.checked_mul(Decimal::from(n2))?)?;
1926 Some(result)
1927 }
1928
1929 #[inline]
1933 fn exp_decimal(&self) -> Option<Decimal> {
1934 let x = *self;
1940 let mut term = x;
1941 let mut sum = Decimal::ONE.checked_add(x)?;
1942 let mut last;
1943 let mut iter = 1;
1944 loop {
1945 iter += 1;
1946
1947 term = term.checked_div(Decimal::from(iter))?.checked_mul(x)?;
1950
1951 if term.is_zero() {
1952 break;
1953 }
1954
1955 last = sum;
1956 sum = sum.checked_add(term)?;
1957
1958 if last == sum {
1959 break;
1960 }
1961 }
1962
1963 Some(sum)
1964 }
1965
1966 #[inline]
1969 pub fn exp(&self) -> Option<Decimal> {
1970 const UPPER_BOUND: Decimal = unsafe { Decimal::from_parts_unchecked(291, 0, false) };
1972 const LOWER_BOUND: Decimal = unsafe { Decimal::from_parts_unchecked(300, 0, true) };
1973
1974 if self.is_zero() {
1975 return Some(Decimal::ONE);
1976 }
1977 if *self >= UPPER_BOUND {
1978 return None;
1980 }
1981 if *self <= LOWER_BOUND {
1982 return Some(Decimal::ZERO);
1983 }
1984
1985 let x = *self;
2002 let a = x.trunc(0);
2003 let b = x.checked_sub(a)?;
2004
2005 let exp_a = if a.is_sign_positive() {
2006 NATURAL_EXP[a.int_val as usize]
2007 } else if a.int_val < UPPER_BOUND.int_val {
2008 Decimal::ONE.checked_div(NATURAL_EXP[a.int_val as usize])?
2010 } else {
2011 NATURAL_EXP_NEG[(a.int_val - UPPER_BOUND.int_val) as usize]
2013 };
2014
2015 let exp_b = if b.is_zero() {
2016 return Some(exp_a);
2018 } else {
2019 b.exp_decimal()?
2020 };
2021
2022 let result = exp_a.checked_mul(exp_b)?;
2024
2025 Some(result)
2026 }
2027}
2028
2029trait WriteExt: fmt::Write {
2030 #[inline(always)]
2031 fn write_byte(&mut self, byte: u8) -> fmt::Result {
2032 self.write_bytes(&[byte])
2033 }
2034
2035 #[inline(always)]
2036 fn write_bytes(&mut self, bytes: &[u8]) -> fmt::Result {
2037 let s = unsafe { std::str::from_utf8_unchecked(bytes) };
2038 self.write_str(s)
2039 }
2040}
2041
2042impl<W: fmt::Write> WriteExt for W {}
2043
2044#[inline]
2045fn write_exp<W: fmt::Write>(
2046 e_notation: &[u8],
2047 exp: u16,
2048 add_left_padding_zero: bool,
2049 mut w: W,
2050) -> Result<(), DecimalFormatError> {
2051 w.write_bytes(e_notation)?;
2052
2053 let mut buf = [b'0'; 3];
2055 let mut index = 2;
2056
2057 let mut val = exp;
2058 while val >= 10 {
2059 let v = val % 10;
2060 val /= 10;
2061 buf[index] += v as u8;
2062 index -= 1;
2063 }
2064 buf[index] += val as u8;
2065
2066 if index == 2 && add_left_padding_zero {
2068 index -= 1;
2069 }
2070
2071 w.write_bytes(&buf[index..])?;
2072 Ok(())
2073}
2074
2075impl AsRef<Decimal> for Decimal {
2076 #[inline]
2077 fn as_ref(&self) -> &Decimal {
2078 self
2079 }
2080}
2081
2082impl fmt::Display for Decimal {
2083 #[inline]
2084 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
2085 let mut buf = Buf::new();
2086 self.fmt_internal(false, false, false, f.precision(), &mut buf)
2087 .expect("failed to format decimal");
2088 let str = unsafe { std::str::from_utf8_unchecked(buf.as_slice()) };
2089 f.pad_integral(self.is_sign_positive(), "", str)
2090 }
2091}
2092
2093impl Default for Decimal {
2094 #[inline]
2095 fn default() -> Self {
2096 Decimal::ZERO
2097 }
2098}
2099
2100impl PartialEq for Decimal {
2101 #[inline]
2102 fn eq(&self, other: &Self) -> bool {
2103 self.cmp(other) == Ordering::Equal
2104 }
2105}
2106
2107impl PartialEq<&Decimal> for Decimal {
2108 #[inline]
2109 fn eq(&self, other: &&Decimal) -> bool {
2110 self.eq(*other)
2111 }
2112}
2113
2114impl PartialEq<Decimal> for &Decimal {
2115 #[inline]
2116 fn eq(&self, other: &Decimal) -> bool {
2117 (*self).eq(other)
2118 }
2119}
2120
2121impl PartialOrd for Decimal {
2122 #[inline]
2123 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
2124 Some(self.cmp(other))
2125 }
2126}
2127
2128impl PartialOrd<&Decimal> for Decimal {
2129 #[inline]
2130 fn partial_cmp(&self, other: &&Decimal) -> Option<Ordering> {
2131 self.partial_cmp(*other)
2132 }
2133}
2134
2135impl PartialOrd<Decimal> for &Decimal {
2136 #[inline]
2137 fn partial_cmp(&self, other: &Decimal) -> Option<Ordering> {
2138 (*self).partial_cmp(other)
2139 }
2140}
2141
2142impl Ord for Decimal {
2143 #[inline]
2144 fn cmp(&self, other: &Self) -> Ordering {
2145 if self.negative() != other.negative() {
2147 return if self.negative() {
2148 Ordering::Less
2149 } else {
2150 Ordering::Greater
2151 };
2152 }
2153
2154 let (left, right) = if self.negative() {
2155 debug_assert!(other.negative());
2157 (other, self)
2158 } else {
2159 (self, other)
2160 };
2161
2162 if left.is_zero() {
2163 return if right.is_zero() {
2164 Ordering::Equal
2165 } else {
2166 Ordering::Less
2167 };
2168 } else if right.is_zero() {
2169 return Ordering::Greater;
2170 }
2171
2172 if left.scale == right.scale {
2173 return left.int_val().cmp(&right.int_val());
2175 }
2176
2177 if left.scale < right.scale {
2178 left.rescale_cmp(right)
2179 } else {
2180 right.rescale_cmp(left).reverse()
2181 }
2182 }
2183}
2184
2185impl Hash for Decimal {
2186 #[inline]
2187 fn hash<H: Hasher>(&self, state: &mut H) {
2188 let n = self.normalize();
2189 n.int_val().hash(state);
2190 n.scale().hash(state);
2191 n.negative().hash(state);
2192 }
2193}
2194
2195#[cfg(test)]
2196mod tests {
2197 use super::*;
2198
2199 #[test]
2200 fn test_decimal_repr() {
2201 assert_eq!(std::mem::size_of::<Decimal>(), 20);
2202 assert_eq!(std::mem::align_of::<Decimal>(), 4);
2203 assert_eq!(std::mem::size_of::<Option<Decimal>>(), 24);
2204 assert_eq!(std::mem::align_of::<Option<Decimal>>(), 4);
2205 }
2206
2207 #[test]
2208 fn test_fmt_internal() {
2209 fn assert(
2210 int_val: u128,
2211 scale: i16,
2212 negative: bool,
2213 append_sign: bool,
2214 precision: Option<usize>,
2215 expected: &str,
2216 ) {
2217 let dec = Decimal::from_parts(int_val, scale, negative).unwrap();
2218 let mut buf = Buf::new();
2219 dec.fmt_internal(append_sign, false, false, precision, &mut buf)
2220 .unwrap();
2221 let str = unsafe { std::str::from_utf8_unchecked(buf.as_slice()) };
2222 assert_eq!(str, expected);
2223 }
2224
2225 assert(128, 0, false, false, None, "128");
2226 assert(128, -2, true, true, None, "-12800");
2227 assert(128, 4, true, true, None, "-0.0128");
2228 assert(128, 2, true, false, None, "1.28");
2229 assert(1280, 4, true, true, None, "-0.1280");
2230 assert(12856, 4, true, false, None, "1.2856");
2231 assert(12856, 4, true, false, Some(2), "1.29");
2232 assert(12856, 4, true, false, Some(6), "1.285600");
2233 assert(1285600, 6, false, false, None, "1.2856");
2234 }
2235
2236 #[test]
2237 fn test_display() {
2238 macro_rules! assert_display {
2239 ($num: expr, $scale: expr, $negative: expr, $fmt: expr,$expected: expr) => {{
2240 let dec = Decimal::from_parts($num, $scale, $negative).unwrap();
2241 let str = format!($fmt, dec);
2242 assert_eq!(str, $expected);
2243 }};
2244 }
2245
2246 assert_display!(0, -1, false, "{}", "0");
2247 assert_display!(1, 0, false, "{}", "1");
2248 assert_display!(1, 1, false, "{}", "0.1");
2249 assert_display!(1, -1, false, "{}", "10");
2250 assert_display!(10, 0, false, "{}", "10");
2251 assert_display!(10, 1, false, "{}", "1");
2252 assert_display!(10, -1, false, "{}", "100");
2253 assert_display!(128, 0, false, "{}", "128");
2254 assert_display!(128, -2, true, "{}", "-12800");
2255 assert_display!(128, 4, true, "{}", "-0.0128");
2256 assert_display!(128, 2, true, "{}", "-1.28");
2257 assert_display!(12800, 1, false, "{}", "1280");
2258 assert_display!(12800, 2, false, "{}", "128");
2259 assert_display!(12800, 3, false, "{}", "12.8");
2260 assert_display!(12856, 4, true, "{}", "-1.2856");
2261 assert_display!(12856, 4, true, "{:.2}", "-1.29");
2262 assert_display!(12856, 4, true, "{:.6}", "-1.285600");
2263 assert_display!(12856, 0, true, "{:.6}", "-12856.000000");
2264 assert_display!(1285600, 6, false, "{}", "1.2856");
2265 assert_display!(u64::MAX as u128, 0, false, "{}", u64::MAX.to_string());
2266 assert_display!(
2267 101,
2268 -98,
2269 false,
2270 "{:.10}",
2271 "10100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.0000000000"
2272 );
2273 assert_display!(101, 98, false, "{:.10}", "0.0000000000");
2274 }
2275
2276 #[test]
2277 fn test_precision() {
2278 fn assert_precision(val: &str, expected: u8) {
2279 let dec = val.parse::<Decimal>().unwrap();
2280 assert_eq!(dec.precision(), expected);
2281 }
2282
2283 assert_precision("0.0", 1);
2284 assert_precision("1", 1);
2285 assert_precision("10", 2);
2286 assert_precision("1.230", 3);
2287 assert_precision("123456123456", 12);
2288 assert_precision("123456.123456", 12);
2289 assert_precision("-123456.123456", 12);
2290 assert_precision("99999999999999999999999999999999999999", 38);
2291 }
2292
2293 #[test]
2294 fn test_encoding() {
2295 fn assert_encoding(num: &str) {
2296 let num = num.parse::<Decimal>().unwrap();
2297 let mut buf = Vec::new();
2298
2299 {
2301 let size = num.compact_encode(&mut buf).unwrap();
2302 assert_eq!(buf.len(), size);
2303 let decoded_num = Decimal::decode(&buf);
2304 assert_eq!(decoded_num, num);
2305 }
2306
2307 buf.clear();
2308
2309 {
2311 let size = num.encode(&mut buf).unwrap();
2312 assert_eq!(buf.len(), size);
2313 let decoded_num = Decimal::decode(&buf);
2314 assert_eq!(decoded_num, num);
2315 }
2316 }
2317
2318 assert_encoding("0");
2319 assert_encoding("255");
2320 assert_encoding("-255");
2321 assert_encoding("65535");
2322 assert_encoding("-65535");
2323 assert_encoding("65536");
2324 assert_encoding("4294967295");
2325 assert_encoding("-4294967295");
2326 assert_encoding("4294967296");
2327 assert_encoding("18446744073709551615");
2328 assert_encoding("-18446744073709551615");
2329 assert_encoding("18446744073709551616");
2330 assert_encoding("99999999999999999999999999999999999999");
2331 assert_encoding("-99999999999999999999999999999999999999");
2332 assert_encoding("184467440.73709551615");
2333 assert_encoding("-184467440.73709551615");
2334 }
2335
2336 #[test]
2337 fn test_cmp() {
2338 macro_rules! assert_cmp {
2339 ($left: expr, $cmp: tt, $right: expr) => {{
2340 let l = $left.parse::<Decimal>().unwrap();
2341 let r = $right.parse::<Decimal>().unwrap();
2342 assert!(l $cmp r, "{} {} {}", l, stringify!($cmp),r);
2343 }};
2344 }
2345
2346 assert_cmp!("0", ==, "0");
2347
2348 assert_cmp!("-1", <, "1");
2349 assert_cmp!("1", >, "-1");
2350
2351 assert_cmp!("1.1", ==, "1.1");
2352 assert_cmp!("1.2", >, "1.1");
2353 assert_cmp!("-1.2", <, "1.1");
2354 assert_cmp!("1.1", >, "-1.2");
2355
2356 assert_cmp!("1", <, "1e39");
2357 assert_cmp!("1", >, "1e-39");
2358 assert_cmp!("1.0e-100", >=, "1.0e-101");
2359 assert_cmp!("1.0e-101", <=, "1.0e-100");
2360 assert_cmp!("1.0e-100", !=, "1.0e-101");
2361
2362 assert_cmp!("1.12", <, "1.2");
2363 assert_cmp!("1.2", >, "1.12");
2364 assert_cmp!("-1.2", <, "-1.12");
2365 assert_cmp!("-1.12", >, "-1.2");
2366 assert_cmp!("-1.12", <, "1.2");
2367 assert_cmp!("1.12", >, "-1.2");
2368
2369 assert_cmp!("0.000000001", <,"100000000");
2370 assert_cmp!("100000000", >, "0.000000001");
2371
2372 assert_cmp!(
2373 "9999999999999999999999999999999999999.9", >, "9.9999999999999999999999999999999999999"
2374 );
2375 assert_cmp!(
2376 "9.9999999999999999999999999999999999999", >, "0"
2377 );
2378 assert_cmp!(
2379 "9.9999999999999999999999999999999999999", >, "1"
2380 );
2381 assert_cmp!(
2382 "-9999999999999999999999999999999999999.9", <, "-9.9999999999999999999999999999999999999"
2383 );
2384 assert_cmp!(
2385 "-9.9999999999999999999999999999999999999", <, "0"
2386 );
2387 assert_cmp!(
2388 "-9.9999999999999999999999999999999999999", <, "1"
2389 );
2390 assert_cmp!("4703178999618078116505370421100e39", >, "0");
2391 assert_cmp!("4703178999618078116505370421100e-39", >, "0");
2392 assert_cmp!("-4703178999618078116505370421100e39", <, "0");
2393 assert_cmp!("-4703178999618078116505370421100e-39", <, "0");
2394 assert_cmp!("0", <, "4703178999618078116505370421100e39");
2395 assert_cmp!("0", <, "4703178999618078116505370421100e-39");
2396 assert_cmp!("0", >, "-4703178999618078116505370421100e39");
2397 assert_cmp!("0", >, "-4703178999618078116505370421100e-39");
2398 }
2399
2400 #[test]
2401 fn test_abs() {
2402 fn assert_abs(val: &str, expected: &str) {
2403 let abs_val = val.parse::<Decimal>().unwrap().abs();
2404 let expected = expected.parse::<Decimal>().unwrap();
2405 assert_eq!(abs_val, expected);
2406 }
2407
2408 assert_abs("0.0", "0");
2409 assert_abs("123456.123456", "123456.123456");
2410 assert_abs("-123456.123456", "123456.123456");
2411 }
2412
2413 #[test]
2414 fn test_trunc() {
2415 fn assert_trunc(val: &str, scale: i16, expected: &str) {
2416 let decimal = val.parse::<Decimal>().unwrap().trunc(scale);
2417 let expected = expected.parse::<Decimal>().unwrap();
2418 assert_eq!(decimal, expected);
2419 }
2420
2421 assert_trunc("0", -1, "0");
2422 assert_trunc("123456", 0, "123456");
2423 assert_trunc("123456.123456", 6, "123456.123456");
2424 assert_trunc("123456.123456", 5, "123456.12345");
2425 assert_trunc("123456.123456", 4, "123456.1234");
2426 assert_trunc("123456.123456", 3, "123456.123");
2427 assert_trunc("123456.123456", 2, "123456.12");
2428 assert_trunc("123456.123456", 1, "123456.1");
2429 assert_trunc("123456.123456", 0, "123456");
2430 assert_trunc("123456.123456", -1, "123450");
2431 assert_trunc("123456.123456", -2, "123400");
2432 assert_trunc("123456.123456", -3, "123000");
2433 assert_trunc("123456.123456", -4, "120000");
2434 assert_trunc("123456.123456", -5, "100000");
2435 assert_trunc("9999.9", 1, "9999.9");
2436 assert_trunc("9999.9", -2, "9900");
2437 assert_trunc("9999.9", -4, "0");
2438 assert_trunc("1e125", 0, "1e125");
2439 assert_trunc("1e125", -125, "1e125");
2440 assert_trunc("1e-130", 0, "0");
2441 assert_trunc("1.7976931348623279769313486232797693134E-130", 131, "1.7E-130");
2442 assert_trunc(
2443 "1.7976931348623279769313486232797693134E-130",
2444 166,
2445 "1.797693134862327976931348623279769313E-130",
2446 );
2447 assert_trunc(
2448 "1.7976931348623279769313486232797693134E-130",
2449 167,
2450 "1.7976931348623279769313486232797693134E-130",
2451 );
2452 assert_trunc(
2453 "1.7976931348623279769313486232797693134E-130",
2454 168,
2455 "1.7976931348623279769313486232797693134E-130",
2456 );
2457 }
2458
2459 #[test]
2460 fn test_round() {
2461 fn assert_round(val: &str, scale: i16, expected: &str) {
2462 let decimal = val.parse::<Decimal>().unwrap().round(scale);
2463 let expected = expected.parse::<Decimal>().unwrap();
2464 assert_eq!(decimal, expected);
2465 }
2466
2467 assert_round("0", -1, "0");
2468 assert_round("123456", 0, "123456");
2469 assert_round("123456.123456", 6, "123456.123456");
2470 assert_round("123456.123456", 5, "123456.12346");
2471 assert_round("123456.123456", 4, "123456.1235");
2472 assert_round("123456.123456", 3, "123456.123");
2473 assert_round("123456.123456", 2, "123456.12");
2474 assert_round("123456.123456", 1, "123456.1");
2475 assert_round("123456.123456", 0, "123456");
2476 assert_round("123456.123456", -1, "123460");
2477 assert_round("123456.123456", -2, "123500");
2478 assert_round("123456.123456", -3, "123000");
2479 assert_round("123456.123456", -4, "120000");
2480 assert_round("123456.123456", -5, "100000");
2481 assert_round("9999.9", 1, "9999.9");
2482 assert_round("9999.9", -2, "10000");
2483 assert_round("9999.9", -4, "10000");
2484 assert_round("1.7976931348623279769313486232797693134E-130", 131, "1.8E-130");
2485 assert_round(
2486 "1.7976931348623279769313486232797693134E-130",
2487 166,
2488 "1.797693134862327976931348623279769313E-130",
2489 );
2490 assert_round(
2491 "1.7976931348623279769313486232797693134E-130",
2492 167,
2493 "1.7976931348623279769313486232797693134E-130",
2494 );
2495 assert_round(
2496 "1.7976931348623279769313486232797693134E-130",
2497 168,
2498 "1.7976931348623279769313486232797693134E-130",
2499 );
2500 }
2501
2502 #[test]
2503 fn test_round_with_precision() {
2504 fn assert(val: &str, precision: u8, scale: i16, expected: &str) {
2505 let mut decimal = val.parse::<Decimal>().unwrap();
2506 let overflowed = decimal.round_with_precision(precision, scale);
2507 assert!(!overflowed);
2508 let expected = expected.parse::<Decimal>().unwrap();
2509 assert_eq!(decimal, expected);
2510 }
2511
2512 fn assert_overflow(val: &str, precision: u8, scale: i16) {
2513 let mut decimal = val.parse::<Decimal>().unwrap();
2514 let overflowed = decimal.round_with_precision(precision, scale);
2515 assert!(overflowed);
2516 }
2517
2518 assert_overflow("123456", 5, 0);
2519 assert_overflow("123456", 5, 1);
2520 assert_overflow("123456", 6, 1);
2521 assert_overflow("123.456", 6, 4);
2522 assert_overflow("5e100", 5, -2);
2523 assert_overflow("5e100", 20, -80);
2524
2525 assert("123456", 5, -1, "123460");
2526 assert("123456", 5, -5, "100000");
2527 assert("123456", 5, -6, "0");
2528 assert("123456", 6, 0, "123456");
2529 assert("123456", 6, -1, "123460");
2530 assert("123.456", 6, 0, "123");
2531 assert("123.456", 6, 1, "123.5");
2532 assert("123.456", 6, 3, "123.456");
2533 assert("123.456", 6, -1, "120");
2534 assert("123.456", 6, -2, "100");
2535 assert("123.456", 6, -3, "0");
2536 assert("623.456", 6, -3, "1000");
2537 assert("123.456", 6, -4, "0");
2538 assert("123.456", 5, -4, "0");
2539 assert("123.456", 5, -3, "0");
2540 assert("123.456", 5, -2, "100");
2541 assert("123456", 5, -5, "100000");
2542 assert("123456", 5, -6, "0");
2543 assert("123456", 5, -7, "0");
2544 assert("5e100", 21, -80, "5e100");
2545 assert("5E-130", 10, 5, "0");
2546 assert("5E-47", 1, 10, "0");
2547 assert("-1E-130", 38, 10, "0");
2548 assert("0.000811111", 5, 3, "0.001");
2549 }
2550
2551 #[test]
2552 fn test_normalize_to() {
2553 fn assert_normalize(val: (u128, i16), scale: i16, expected: (u128, i16)) {
2554 let left = Decimal::from_parts(val.0, val.1, false).unwrap();
2555 let right = Decimal::from_parts(expected.0, expected.1, false).unwrap();
2556 assert_eq!(left, right);
2557 let normal = left.normalize_to_scale(scale);
2558 assert_eq!((normal.int_val, normal.scale), expected);
2559 }
2560
2561 assert_normalize((12300, MAX_SCALE), 2, (123, MAX_SCALE - 2));
2562 assert_normalize((12300, 2), 2, (12300, 2));
2563 assert_normalize((12300, 2), 3, (123000, 3));
2564 assert_normalize((12300, 2), 0, (123, 0));
2565 assert_normalize((12300, 2), -1, (123, 0));
2566 assert_normalize((123000, 2), -1, (123, -1));
2567 assert_normalize(
2568 (9_9999_9999_9999_9999_9999_9999_9999_9999_9999_u128, -2),
2569 2,
2570 (99_9999_9999_9999_9999_9999_9999_9999_9999_9990_u128, -1),
2571 );
2572 assert_normalize((12300, MIN_SCALE + 1), -100, (123000000000000000000000000000, -100));
2573 }
2574
2575 #[test]
2576 fn test_normalize() {
2577 fn assert_normalize(val: (u128, i16), expected: (u128, i16)) {
2578 let left = Decimal::from_parts(val.0, val.1, false).unwrap();
2579 let right = Decimal::from_parts(expected.0, expected.1, false).unwrap();
2580 assert_eq!(left, right);
2581 let normal = left.normalize();
2582 assert_eq!((normal.int_val, normal.scale), expected);
2583 }
2584
2585 assert_normalize((12300, MAX_SCALE), (123, MAX_SCALE - 2));
2586 assert_normalize((12300, 2), (123, 0));
2587 assert_normalize((1230, 0), (1230, 0));
2588 assert_normalize((12300, -2), (1230000, 0));
2589 assert_normalize(
2590 (9_9999_9999_9999_9999_9999_9999_9999_9999_9999_u128, -2),
2591 (99_9999_9999_9999_9999_9999_9999_9999_9999_9990_u128, -1),
2592 );
2593 assert_normalize((12300, MIN_SCALE + 1), (12300000000000000000000000000000000000, -92));
2594 }
2595
2596 #[test]
2597 fn test_hash() {
2598 use std::collections::hash_map::DefaultHasher;
2599
2600 let d1 = Decimal::from_parts(12345, 3, false).unwrap();
2601 let d2 = Decimal::from_parts(123450, 4, false).unwrap();
2602
2603 let mut hash1 = DefaultHasher::new();
2604 let mut hash2 = DefaultHasher::new();
2605
2606 d1.hash(&mut hash1);
2607 d2.hash(&mut hash2);
2608
2609 assert_eq!(hash1.finish(), hash2.finish());
2610 }
2611
2612 #[test]
2613 fn test_sqrt() {
2614 fn assert_sqrt(val: &str, expected: &str) {
2615 let num = val.parse::<Decimal>().unwrap();
2616 let expected = expected.parse::<Decimal>().unwrap();
2617 let result = num.sqrt().unwrap();
2618 assert_eq!(result, expected);
2619 }
2620
2621 assert_sqrt("0", "0");
2622 assert_sqrt("0.00000", "0");
2623 assert_sqrt("1", "1");
2624 assert_sqrt("1.001", "1.0004998750624609648232582877001097531");
2625 assert_sqrt("1.44", "1.2");
2626 assert_sqrt("2", "1.4142135623730950488016887242096980786");
2627 assert_sqrt("100", "10");
2628 assert_sqrt("49", "7");
2629 assert_sqrt("0.25", "0.5");
2630 assert_sqrt("0.0152399025", "0.12345");
2631 assert_sqrt("152399025", "12345");
2632 assert_sqrt("0.00400", "0.063245553203367586639977870888654370675");
2633 assert_sqrt("0.1", "0.31622776601683793319988935444327185337");
2634 assert_sqrt("2", "1.4142135623730950488016887242096980786");
2635 assert_sqrt("125348", "354.04519485512015631084871931761013143");
2636 assert_sqrt(
2637 "18446744073709551616.1099511",
2638 "4294967296.0000000000127999926917254925",
2639 );
2640 assert_sqrt(
2641 "3.1415926535897931159979634685441851615",
2642 "1.7724538509055159927515191031392484393",
2643 );
2644 assert_sqrt(
2645 "0.000000000089793115997963468544185161590576171875",
2646 "0.0000094759229628550415175617837401442254225",
2647 );
2648 assert_sqrt(
2649 "0.71777001097629639227453423431674136248",
2650 "0.84721308475276536670429805177990207040",
2651 );
2652 assert_sqrt(
2653 "0.012345679012345679012345679012345679012",
2654 "0.11111111111111111111111111111111111111",
2655 );
2656 assert_sqrt(
2657 "0.11088900000000000000000000000000000444",
2658 "0.33300000000000000000000000000000000667",
2659 );
2660 assert_sqrt(
2661 "17014118346046923173168730371588410572",
2662 "4124817371235594858.7903221175243613899",
2663 );
2664 assert_sqrt(
2665 "0.17014118346046923173168730371588410572",
2666 "0.41248173712355948587903221175243613899",
2667 );
2668 assert_sqrt("1e100", "1e50");
2669 assert_sqrt("1.01e100", "1.0049875621120890270219264912759576187e50");
2670 assert_sqrt("1e-100", "1e-50");
2671 assert_sqrt("1.01e-100", "1.0049875621120890270219264912759576187e-50");
2672 assert_sqrt("1.0e-130", "1.0e-65");
2673 }
2674
2675 #[test]
2676 fn test_ceil_floor() {
2677 fn assert_ceil_floor(val: &str, expected_ceil: &str, expected_floor: &str) {
2678 let decimal_ceil = val.parse::<Decimal>().unwrap().ceil();
2679 let decimal_floor = val.parse::<Decimal>().unwrap().floor();
2680 let expected_ceil = expected_ceil.parse::<Decimal>().unwrap();
2681 let expected_floor = expected_floor.parse::<Decimal>().unwrap();
2682 assert_eq!(decimal_ceil, expected_ceil);
2683 assert_eq!(decimal_floor, expected_floor);
2684 }
2685
2686 assert_ceil_floor("0", "0", "0");
2687 assert_ceil_floor("123456", "123456", "123456");
2688 assert_ceil_floor("12345600", "12345600", "12345600");
2689 assert_ceil_floor("-12345600", "-12345600", "-12345600");
2690 assert_ceil_floor("123456.123456", "123457", "123456");
2691 assert_ceil_floor("-123456.123456", "-123456", "-123457");
2692 assert_ceil_floor("0.00123456", "1", "0");
2693 assert_ceil_floor("-0.00123456", "0", "-1");
2694 assert_ceil_floor("1e100", "1e100", "1e100");
2695 assert_ceil_floor("1e-100", "1", "0");
2696 assert_ceil_floor("-1e100", "-1e100", "-1e100");
2697 assert_ceil_floor("-1e-100", "0", "-1");
2698 assert_ceil_floor("100e-2", "1", "1");
2699 assert_ceil_floor("-100e-2", "-1", "-1");
2700 }
2701
2702 #[test]
2703 fn test_simply_format() {
2704 fn assert_fmt(input: &str, expected: &str) {
2705 let mut s = String::with_capacity(256);
2706 let num = input.parse::<Decimal>().unwrap();
2707 num.simply_format(&mut s).unwrap();
2708 assert_eq!(s.as_str(), expected);
2709 }
2710
2711 assert_fmt("0", "0");
2712 assert_fmt("0.6796000", ".6796");
2713 assert_fmt("0.6796", ".6796");
2714 assert_fmt("-0.6796", "-.6796");
2715 assert_fmt("123456789.123456789", "123456789.123456789");
2716 assert_fmt("+123456789.123456789", "123456789.123456789");
2717 assert_fmt("-123456789.123456789", "-123456789.123456789");
2718 }
2719
2720 #[test]
2721 fn test_format_with_sci() {
2722 fn assert_fmt(input: &str, target_len: u16, expected: &str) {
2723 let mut s = String::with_capacity(256);
2724 let num = input.parse::<Decimal>().unwrap();
2725 num.format_with_sci(target_len, &mut s).unwrap();
2726 assert_eq!(s.as_str(), expected);
2727 }
2728
2729 fn assert_error(input: &str, target_len: u16) {
2730 let mut s = String::with_capacity(256);
2731 let num = input.parse::<Decimal>().unwrap();
2732 assert!(num.format_with_sci(target_len, &mut s).is_err());
2733 }
2734
2735 fn assert_fmt_with_scale(int_val: u128, scale: i16, negative: bool, target_len: u16, expected: &str) {
2736 let mut s = String::with_capacity(256);
2737 let num = Decimal::from_parts(int_val, scale, negative).unwrap();
2738 num.format_with_sci(target_len, &mut s).unwrap();
2739 assert_eq!(s.as_str(), expected);
2740 }
2741
2742 assert_fmt_with_scale(10000000000000000000, 19, false, 20, "1");
2744 assert_fmt_with_scale(110000000000000000000, 19, false, 20, "11");
2745 assert_fmt_with_scale(110000000000000000000, 18, true, 20, "-110");
2746 assert_fmt_with_scale(110100000000000000000, 19, false, 20, "11.01");
2747
2748 assert_fmt("0", 1, "0");
2750 assert_fmt("0", 5, "0");
2751 assert_fmt("6", 1, "6");
2752 assert_fmt("6", 5, "6");
2753 assert_error("10", 1);
2754 assert_fmt("10", 2, "10");
2755 assert_fmt("10", 5, "10");
2756 assert_error("100", 2);
2757 assert_fmt("100", 3, "100");
2758 assert_fmt("100", 5, "100");
2759 assert_fmt("-236.23", 20, "-236.23");
2760 assert_fmt("-236.23", 7, "-236.23");
2761
2762 assert_fmt("1000000000", 10, "1000000000");
2764 assert_fmt("-1000000000", 11, "-1000000000");
2765 assert_fmt("1000000000", 9, "1.000E+09");
2766 assert_fmt("-1000000000", 10, "-1.000E+09");
2767 assert_fmt("1000000000", 7, "1.0E+09");
2768 assert_fmt("-1000000000", 8, "-1.0E+09");
2769 assert_error("1000000000", 6);
2770 assert_error("-1000000000", 7);
2771
2772 assert_fmt("9999999999", 9, "1.000E+10");
2774 assert_fmt("9999999999", 7, "1.0E+10");
2775 assert_fmt("1899999999", 9, "1.900E+09");
2776 assert_fmt("1899999999", 7, "1.9E+09");
2777 assert_fmt("1989999999", 9, "1.990E+09");
2778 assert_fmt("1989999999", 7, "2.0E+09");
2779 assert_fmt("1999999999", 9, "2.000E+09");
2780 assert_fmt("1999999999", 7, "2.0E+09");
2781 assert_fmt("1666666666", 9, "1.667E+09");
2782 assert_fmt("1666666666", 7, "1.7E+09");
2783 assert_error("1666666666", 6);
2784 assert_fmt("9999999999.999999999", 25, "9999999999.999999999");
2785 assert_fmt("9999999999.999999999", 9, "1.000E+10");
2786 assert_fmt("-9999999999.999999999", 9, "-1.00E+10");
2787 assert_fmt("666666.666666", 10, "666666.667");
2788 assert_fmt(".0000123456789", 10, ".000012346");
2789 assert_fmt(".00000123456789", 10, "1.2346E-06");
2790 assert_fmt(".00000999999999", 10, "1.0000E-05");
2791 assert_fmt("-0.00000999999999", 10, "-1.000E-05");
2792 assert_fmt("-0.00000999999999", 20, "-.00000999999999");
2793 assert_fmt("-0.0000000000123456789", 14, "-1.2345679E-11");
2794 assert_fmt(".0000000000123456789", 14, "1.23456789E-11");
2795 assert_fmt("-0.0000000000123456789", 20, "-1.2345678900000E-11");
2796
2797 assert_fmt("-0.0000000000123456789", 21, "-.0000000000123456789");
2799 assert_fmt("0.135E-100", 8, "1.4E-101");
2800 assert_fmt("0.135E-100", 15, "1.35000000E-101");
2801 assert_fmt("0.135E-100", 25, "1.350000000000000000E-101");
2802 assert_fmt("0.135E-100", 30, "1.35000000000000000000000E-101");
2803 assert_fmt("-0.135E+100", 25, "-1.350000000000000000E+99");
2804 assert_fmt("-0.135E+100", 30, "-1.35000000000000000000000E+99");
2805 assert_fmt(
2806 "-0.135E-100",
2807 106,
2808 "-.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000135",
2809 );
2810 assert_fmt(
2811 "0.1E-126",
2812 127,
2813 "1.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000E-127",
2814 );
2815
2816 assert_fmt("666666.666666", 7, "666667");
2818 assert_fmt("666666.666666", 6, "666667");
2819 assert_error("666666.666666", 5);
2820
2821 fn assert_fmt2(num: Decimal, target_len: u16, expected: &str) {
2823 let mut s = String::with_capacity(256);
2824 num.format_with_sci(target_len, &mut s).unwrap();
2825 assert_eq!(s.as_str(), expected);
2826 }
2827
2828 let num = Decimal::from_parts(330, 3, false).unwrap();
2829 assert_fmt2(num, 10, ".33");
2830 assert_fmt2(num, 2, ".3");
2831 }
2832
2833 #[test]
2834 fn test_format_with_sci_forced() {
2835 fn assert_sci(input: &str, expect_scale: i16, with_zero_before_dot: bool, expect: &str) {
2836 let num = input.parse::<Decimal>().unwrap();
2837 let mut s = String::new();
2838 num.format_with_sci_forced(expect_scale, with_zero_before_dot, &mut s)
2839 .unwrap();
2840 assert_eq!(s.as_str(), expect);
2841 }
2842
2843 assert_sci("0", 0, false, "0E+00");
2844 assert_sci("0", 1, false, " .0E+00");
2845 assert_sci("0", 3, false, " .000E+00");
2846 assert_sci(
2847 "0",
2848 56,
2849 false,
2850 " .00000000000000000000000000000000000000000000000000000000E+00",
2851 );
2852 assert_sci("0", 0, true, "0E+00");
2853 assert_sci("0", 1, true, "0.0E+00");
2854 assert_sci("0", 3, true, "0.000E+00");
2855 assert_sci(
2856 "0",
2857 56,
2858 true,
2859 "0.00000000000000000000000000000000000000000000000000000000E+00",
2860 );
2861 assert_sci("0.6", 0, false, "6E-01");
2862 assert_sci("1.6", 0, false, "2E+00");
2863 assert_sci("1.2", 0, false, "1E+00");
2864 assert_sci(
2865 "3.234234E120",
2866 56,
2867 false,
2868 "3.23423400000000000000000000000000000000000000000000000000E+120",
2869 );
2870 assert_sci(
2871 "3.234234E-120",
2872 56,
2873 false,
2874 "3.23423400000000000000000000000000000000000000000000000000E-120",
2875 );
2876 assert_sci("3.234234E120", 3, false, "3.234E+120");
2877 assert_sci("3.234234E-120", 3, false, "3.234E-120");
2878 assert_sci(
2879 "0.345e100",
2880 56,
2881 false,
2882 "3.45000000000000000000000000000000000000000000000000000000E+99",
2883 );
2884 assert_sci(
2885 "0.345e-100",
2886 56,
2887 false,
2888 "3.45000000000000000000000000000000000000000000000000000000E-101",
2889 );
2890 assert_sci("3e2", 4, false, "3.0000E+02");
2891 assert_sci("300", 4, false, "3.0000E+02");
2892 assert_sci("0.03", 4, false, "3.0000E-02");
2893 assert_sci("3.36e60", 0, false, "3E+60");
2894 assert_sci("3.36e-60", 0, false, "3E-60");
2895 assert_sci("-3.36e60", 0, false, "-3E+60");
2896 assert_sci("-3.36e-60", 0, false, "-3E-60");
2897 assert_sci("3.36e60", 1, false, "3.4E+60");
2898 assert_sci("3.36e-60", 1, false, "3.4E-60");
2899 assert_sci("-3.36e60", 1, false, "-3.4E+60");
2900 assert_sci("-3.36e-60", 1, false, "-3.4E-60");
2901 }
2902
2903 #[test]
2904 fn test_pow() {
2905 fn assert_pow_uint(base: &str, exponent: u64, expected: &str) {
2906 let decimal = base.parse::<Decimal>().unwrap().pow_u64(exponent).unwrap();
2907 let expected = expected.parse::<Decimal>().unwrap();
2908 assert_eq!(decimal, expected);
2909 }
2910 fn assert_pow_int(base: &str, exponent: i64, expected: &str) {
2911 let decimal = base.parse::<Decimal>().unwrap().pow_i64(exponent).unwrap();
2912 let expected = expected.parse::<Decimal>().unwrap();
2913 assert_eq!(decimal, expected);
2914 }
2915 fn assert_pow_decimal(base: &str, exponent: &str, expected: &str) {
2916 let exponent = exponent.parse::<Decimal>().unwrap();
2917 let decimal = base.parse::<Decimal>().unwrap().checked_pow(&exponent).unwrap();
2918 let expected = expected.parse::<Decimal>().unwrap();
2919 assert_eq!(decimal, expected);
2920 }
2921
2922 assert_pow_uint("0", 0, "1");
2923 assert_pow_uint("0", 2, "0");
2924 assert_pow_uint("30.03", 11, "17910538937279543.381440174900003379415");
2925 assert_pow_uint("0.9999999", 123456, "0.98773029366878871282374552006725694652");
2926 assert_pow_uint(
2927 "2",
2928 418,
2929 "676921312041214565326761275425557544830000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
2930 );
2931 assert_pow_int("3.333", 3, "37.025927037");
2932 assert_pow_int("123456", -2, "0.000000000065610839816062225597621740797803625383");
2933 assert_pow_int("16.66666", -6, "0.000000046656111974556764327215254493713994963");
2934 assert_pow_int("15", -15, "0.0000000000000000022836582605211672220051325163651837732");
2935 assert_pow_int(
2936 "2",
2937 200,
2938 "1606938044258990275541962092341162602500000000000000000000000",
2939 );
2940 assert_pow_int("100", -9223372036854775808, "0");
2941 assert_pow_decimal("-3", "0", "1");
2942 assert_pow_decimal("3.333", "3", "37.025927037");
2943 assert_pow_decimal("3.3", "2.2", "13.827086118044145328600539201031810464");
2944 assert_pow_decimal("2", "50.1", "1206709641626009.0372720478765230064730");
2945 assert_pow_decimal("2", "-50.1", "0.00000000000000082869976795124193101335598234941507825");
2946 assert_pow_decimal("123456", "2.2", "158974271527.98285353227767713306007512");
2947 assert_pow_decimal(
2948 "123456",
2949 "-12.2",
2950 "0.0000000000000000000000000000000000000000000000000000000000000076480574247485409303800372083765338615",
2951 );
2952 assert_pow_decimal("123456.789", "0.9999999", "123456.64426370977396175023229704225849");
2953 assert_pow_decimal(
2954 "234567890123456.789",
2955 "5.8822",
2956 "3379043109285747020459941490972051546800000000000000000000000000000000000000000000000",
2957 );
2958 assert_pow_decimal("0.9999999", "0.789", "0.99999992109999916760496639898664270396");
2959 assert_pow_decimal("0.9999999", "123456.789", "0.98773021573686772017452509110356382471");
2960 assert_pow_decimal(
2961 "0.9",
2962 "22222220000000000000000000000000000000000000000000000000000000",
2963 "0",
2964 );
2965 assert_pow_decimal(
2966 "1",
2967 "22222220000000000000000000000000000000000000000000000000000000",
2968 "1",
2969 );
2970 assert_pow_decimal(
2971 "2",
2972 "418.1",
2973 "725506298471023093722890872060236907240000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
2974 );
2975 assert_pow_decimal(
2976 "1.0000000000000000000000000000000000001",
2977 "340282366920938463463374607431768211450",
2978 "600171577097065.40413095725314413792835",
2979 );
2980 assert_pow_decimal("100", "-170141183460469231731687303715884105720", "0");
2981 assert_pow_decimal("5", "-4188888888888888888444444444444444000000000000000000000000", "0");
2982 assert_pow_decimal(
2983 "1.000000000001",
2984 "1234567889",
2985 "1.0012353302816452027366495735797849363",
2986 );
2987 }
2988
2989 #[test]
2990 fn test_ln() {
2991 fn assert_ln(val: &str, expected: &str) {
2992 let decimal = val.parse::<Decimal>().unwrap().ln().unwrap();
2993 let expected = expected.parse::<Decimal>().unwrap();
2994 assert_eq!(decimal, expected);
2995 }
2996
2997 assert_ln(
2998 "1.0000000000000000000000000000000000001",
2999 "0.000000000000000000000000000000000000099999999999999999999999999999999999996",
3000 );
3001 assert_ln("0.000123456789", "-8.9996193497605301750219641082491662814");
3002 assert_ln("13.3", "2.5877640352277080810963887206466690594");
3003 assert_ln("1000", "6.9077552789821370520539743640530926228");
3004 assert_ln("12345.67891", "9.4210613950018353041649175905084849130");
3005 assert_ln("1500000000000000", "34.944241503018849642247884935729812251");
3006 assert_ln(
3007 "1500000000000000000000000000000.123456",
3008 "69.483017897929534902517756755995357669",
3009 );
3010 assert_ln(
3011 "15000000000000000000000000000000000000000000000000000000000000000000000000000",
3012 "175.40193217565563636734536367147602892",
3013 );
3014 }
3015
3016 #[test]
3017 fn test_exp() {
3018 fn assert_exp(exponent: &str, expected: &str) {
3019 let decimal = exponent.parse::<Decimal>().unwrap().exp().unwrap();
3020 let expected = expected.parse::<Decimal>().unwrap();
3021 assert_eq!(decimal, expected);
3022 }
3023
3024 assert_exp("1", "2.7182818284590452353602874713526624975");
3025 assert_exp("0.00000012", "1.0000001200000072000002880000086400002");
3026 assert_exp(
3027 "0.9999999999999999999999999999999999999",
3028 "2.7182818284590452353602874713526624971",
3029 );
3030 assert_exp("-0.00000012", "0.99999988000000719999971200000863999979");
3031 assert_exp(
3032 "-0.9999999999999999999999999999999999999",
3033 "0.36787944117144232159552377016146086748",
3034 );
3035 assert_exp("12.3456789", "229964.19456908213454430507162889547155");
3036 assert_exp("-50.1", "0.00000000000000000000017452050324689209452230894746470912110");
3037 assert_exp(
3038 "259.11111",
3039 "33925423113202888041488548716222730394000000000000000000000000000000000000000000000000000000000000000000000000000",
3040 );
3041 assert_exp(
3042 "290.123456",
3043 "997736847550168914657296864583252087210000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
3044 );
3045 }
3046
3047 #[test]
3048 fn generate_exp_array() {
3049 for i in 0..291 {
3051 let exponent = Decimal::from(i);
3052 let result = exponent.exp_decimal().unwrap();
3053
3054 if i % 5 == 0 {
3055 println!("// e^{}", i);
3056 }
3057 println!(
3058 "unsafe {{ Decimal::from_raw_parts({}, {}, {}) }},",
3059 result.int_val(),
3060 result.scale,
3061 result.negative(),
3062 );
3063 }
3064 }
3065
3066 #[test]
3067 fn generate_exp_negative_array() {
3068 const EXP_NEGATIVE_291: Decimal =
3070 unsafe { Decimal::from_raw_parts(41716298478166806118243377939293045745, 164, false) };
3071 for i in 291..300 {
3073 let result = EXP_NEGATIVE_291.checked_div(NATURAL_EXP[(i - 291) as usize]).unwrap();
3074
3075 if i % 5 == 0 {
3076 println!("// e^-{}", i);
3077 }
3078 println!(
3079 "unsafe {{ Decimal::from_raw_parts({}, {}, {}) }},",
3080 result.int_val(),
3081 result.scale,
3082 result.negative(),
3083 );
3084 }
3085 }
3086
3087 #[test]
3088 fn test_format_to_hex() {
3089 fn assert_fmt_hex(input: &str, is_capital: bool, expect: &str) {
3090 let mut s = String::new();
3091 let num = input.parse::<Decimal>().unwrap();
3092 num.format_to_hex(is_capital, &mut s).unwrap();
3093 assert_eq!(s.as_str(), expect);
3094 }
3095
3096 assert_fmt_hex("3", true, "3");
3097 assert_fmt_hex("15", true, "F");
3098 assert_fmt_hex("15", false, "f");
3099 assert_fmt_hex(
3100 "7e75",
3101 true,
3102 "f79dc0e8c518f31eb934b4522ad36a1d39f275c35e858000000000000000000"
3103 .to_uppercase()
3104 .as_str(),
3105 );
3106 assert_fmt_hex(
3107 "7e75",
3108 false,
3109 "f79dc0e8c518f31eb934b4522ad36a1d39f275c35e858000000000000000000",
3110 );
3111 assert_fmt_hex(
3112 "6e70",
3113 true,
3114 "8b18610932ab6b2906ea3dfeaa8da073a862d7e0d800000000000000000"
3115 .to_uppercase()
3116 .as_str(),
3117 );
3118 assert_fmt_hex(
3119 "6e70",
3120 false,
3121 "8b18610932ab6b2906ea3dfeaa8da073a862d7e0d800000000000000000",
3122 );
3123 assert_fmt_hex("999", true, "3E7");
3124 assert_fmt_hex("999", false, "3e7");
3125 assert_fmt_hex(
3126 "9.93879279687e53",
3127 true,
3128 "a6067cc8b3051f61f39c31e697c47c18e3c0000000000".to_uppercase().as_str(),
3129 );
3130 assert_fmt_hex(
3131 "9.93879279687e53",
3132 false,
3133 "a6067cc8b3051f61f39c31e697c47c18e3c0000000000",
3134 );
3135 assert_fmt_hex(
3136 "12345678901234567890123456789012345678e30",
3137 true,
3138 "753aaed77fe1aa5508b3e1db763b1a087e44a76fa433d81f80000000"
3139 .to_uppercase()
3140 .as_str(),
3141 );
3142 assert_fmt_hex(
3143 "12345678901234567890123456789012345678e30",
3144 false,
3145 "753aaed77fe1aa5508b3e1db763b1a087e44a76fa433d81f80000000",
3146 );
3147 assert_fmt_hex("253.658", true, "FE");
3148 assert_fmt_hex("253.658", false, "fe");
3149 assert_fmt_hex("0", true, "0");
3150 assert_fmt_hex("0", false, "0");
3151 assert_fmt_hex("0.2", true, "0");
3152 assert_fmt_hex("0.2", false, "0");
3153 assert_fmt_hex("0.7", true, "1");
3154 assert_fmt_hex("0.7", false, "1");
3155 assert_fmt_hex(
3157 "72370055773322622139731865630429942408e38",
3158 true,
3159 "fffffffffffffffffffffffffffffffe9e6c3ef3908c56c58cab20000000000"
3160 .to_uppercase()
3161 .as_str(),
3162 );
3163 assert_fmt_hex(
3164 "72370055773322622139731865630429942408e38",
3165 false,
3166 "fffffffffffffffffffffffffffffffe9e6c3ef3908c56c58cab20000000000",
3167 );
3168 }
3169
3170 #[test]
3171 fn test_format_to_json() {
3172 fn assert_fmt_json(input: &str, expect: &str) {
3173 let mut s = String::new();
3174 let num = input.parse::<Decimal>().unwrap();
3175 num.format_to_json(&mut s).unwrap();
3176 assert_eq!(s.as_str(), expect);
3177 }
3178
3179 assert_fmt_json("0", "0");
3180 assert_fmt_json("123", "123");
3181 assert_fmt_json("123.123", "123.123");
3182 assert_fmt_json("-123", "-123");
3183 assert_fmt_json("-123.123", "-123.123");
3184 assert_fmt_json("123e37", "1230000000000000000000000000000000000000");
3185 assert_fmt_json("123e38", "1.23E+40");
3186 assert_fmt_json("123e39", "1.23E+41");
3187 assert_fmt_json("12300e35", "1230000000000000000000000000000000000000");
3188 assert_fmt_json("12300e36", "1.23E+40");
3189 assert_fmt_json("12300e37", "1.23E+41");
3190 assert_fmt_json("-123e37", "-1230000000000000000000000000000000000000");
3191 assert_fmt_json("-123e38", "-1.23E+40");
3192 assert_fmt_json("-123e39", "-1.23E+41");
3193 assert_fmt_json("-12300e35", "-1230000000000000000000000000000000000000");
3194 assert_fmt_json("-12300e36", "-1.23E+40");
3195 assert_fmt_json("-12300e37", "-1.23E+41");
3196
3197 assert_fmt_json("123e-42", "1.23E-40");
3198 assert_fmt_json("123e-41", "1.23E-39");
3199 assert_fmt_json("123e-40", "0.0000000000000000000000000000000000000123");
3200 assert_fmt_json("12300e-44", "1.23E-40");
3201 assert_fmt_json("12300e-43", "1.23E-39");
3202 assert_fmt_json("12300e-42", "0.0000000000000000000000000000000000000123");
3203 assert_fmt_json("-123e-42", "-1.23E-40");
3204 assert_fmt_json("-123e-41", "-1.23E-39");
3205 assert_fmt_json("-123e-40", "-0.0000000000000000000000000000000000000123");
3206 assert_fmt_json("-12300e-44", "-1.23E-40");
3207 assert_fmt_json("-12300e-43", "-1.23E-39");
3208 assert_fmt_json("-12300e-42", "-0.0000000000000000000000000000000000000123");
3209
3210 assert_fmt_json("1234.1234e36", "1234123400000000000000000000000000000000");
3211 assert_fmt_json("1234.1234e37", "1.2341234E+40");
3212 assert_fmt_json("1234.1234e-36", "0.0000000000000000000000000000000012341234");
3213 assert_fmt_json("1234.1234e-37", "1.2341234E-34");
3214
3215 assert_fmt_json(
3216 "12345678901234567890123456789012345678e2",
3217 "1234567890123456789012345678901234567800",
3218 );
3219 assert_fmt_json(
3220 "12345678901234567890123456789012345678e3",
3221 "1.2345678901234567890123456789012345678E+40",
3222 );
3223 assert_fmt_json(
3224 "12345678901234567890123456789012345678e-40",
3225 "0.0012345678901234567890123456789012345678",
3226 );
3227 assert_fmt_json(
3228 "12345678901234567890123456789012345678e-41",
3229 "1.2345678901234567890123456789012345678E-4",
3230 );
3231
3232 assert_fmt_json(
3233 "1234567890123456789012345678901234567800e0",
3234 "1234567890123456789012345678901234567800",
3235 );
3236 assert_fmt_json(
3237 "1234567890123456789012345678901234567800e1",
3238 "1.2345678901234567890123456789012345678E+40",
3239 );
3240 assert_fmt_json(
3241 "1234567890123456789012345678901234567800e-42",
3242 "0.0012345678901234567890123456789012345678",
3243 );
3244 assert_fmt_json(
3245 "1234567890123456789012345678901234567800e-43",
3246 "1.2345678901234567890123456789012345678E-4",
3247 );
3248
3249 assert_fmt_json(
3250 "12345678901234567.890123456789012345678e19",
3251 "123456789012345678901234567890123456.78",
3252 );
3253 assert_fmt_json(
3254 "12345678901234567.890123456789012345678e21",
3255 "12345678901234567890123456789012345678",
3256 );
3257 assert_fmt_json(
3258 "12345678901234567.890123456789012345678e23",
3259 "1234567890123456789012345678901234567800",
3260 );
3261 assert_fmt_json(
3262 "12345678901234567.890123456789012345678e24",
3263 "1.2345678901234567890123456789012345678E+40",
3264 );
3265 assert_fmt_json(
3266 "12345678901234567.890123456789012345678e-15",
3267 "12.345678901234567890123456789012345678",
3268 );
3269 assert_fmt_json(
3270 "12345678901234567.890123456789012345678e-17",
3271 "0.12345678901234567890123456789012345678",
3272 );
3273 assert_fmt_json(
3274 "12345678901234567.890123456789012345678e-19",
3275 "0.0012345678901234567890123456789012345678",
3276 );
3277 assert_fmt_json(
3278 "12345678901234567.890123456789012345678e-21",
3279 "1.2345678901234567890123456789012345678E-5",
3280 );
3281
3282 assert_fmt_json(
3283 "0.00000000012345678901234567890123456789012345678e-1",
3284 "1.2345678901234567890123456789012345678E-11",
3285 );
3286 assert_fmt_json(
3287 "0.00000000012345678901234567890123456789012345678e0",
3288 "1.2345678901234567890123456789012345678E-10",
3289 );
3290 assert_fmt_json(
3291 "0.00000000012345678901234567890123456789012345678e6",
3292 "1.2345678901234567890123456789012345678E-4",
3293 );
3294 assert_fmt_json(
3295 "0.00000000012345678901234567890123456789012345678e7",
3296 "0.0012345678901234567890123456789012345678",
3297 );
3298 assert_fmt_json(
3299 "0.00000000012345678901234567890123456789012345678e47",
3300 "12345678901234567890123456789012345678",
3301 );
3302 assert_fmt_json(
3303 "0.00000000012345678901234567890123456789012345678e49",
3304 "1234567890123456789012345678901234567800",
3305 );
3306 assert_fmt_json(
3307 "0.00000000012345678901234567890123456789012345678e50",
3308 "1.2345678901234567890123456789012345678E+40",
3309 );
3310 }
3311
3312 #[test]
3313 fn test_unchecked_add() {
3314 fn assert_unchecked_add<const DECIMAL_MODEL: u8>(val1: &str, val2: &str, expected: &str, scale: i16) {
3315 let mut var1 = val1.parse::<Decimal>().unwrap();
3316 let ret = var1.round_with_precision(38, scale);
3317 assert!(!ret);
3318 let mut var2 = val2.parse::<Decimal>().unwrap();
3319 let ret = var2.round_with_precision(38, scale);
3320 assert!(!ret);
3321 let expected = expected.parse::<Decimal>().unwrap();
3322
3323 let result = unsafe { var1.add_with_same_scale_unchecked::<DECIMAL_MODEL>(&var2, scale) };
3324 assert_eq!(result, expected);
3325 }
3326
3327 assert_unchecked_add::<DECIMAL64>("2.34", "3.45", "5.79", 2);
3328 assert_unchecked_add::<DECIMAL64>("2.34", "-3.45", "-1.11", 2);
3329 assert_unchecked_add::<DECIMAL64>("0", "-3.45", "-3.45", 2);
3330 assert_unchecked_add::<DECIMAL64>("-2.34", "3.45", "1.11", 2);
3331 assert_unchecked_add::<DECIMAL64>("-2.34", "-3.45", "-5.79", 2);
3332 assert_unchecked_add::<DECIMAL64>("0", "0", "0", 2);
3333 assert_unchecked_add::<DECIMAL64>("9999999999999999.99", "9999999999999999.99", "19999999999999999.98", 2);
3334 assert_unchecked_add::<DECIMAL64>("0", "9999999999999999.99", "9999999999999999.99", 2);
3335 assert_unchecked_add::<DECIMAL64>(
3336 "-9999999999999999.99",
3337 "-9999999999999999.99",
3338 "-19999999999999999.98",
3339 2,
3340 );
3341 assert_unchecked_add::<DECIMAL64>("-9999999999999999.99", "9999999999999999.99", "0", 2);
3342 assert_unchecked_add::<DECIMAL64>("0", "9999999999999999.99", "9999999999999999.99", 2);
3343
3344 assert_unchecked_add::<DECIMAL128>("2.34", "3.45", "5.79", 2);
3345 assert_unchecked_add::<DECIMAL128>("2.34", "-3.45", "-1.11", 2);
3346 assert_unchecked_add::<DECIMAL128>("0", "-3.45", "-3.45", 2);
3347 assert_unchecked_add::<DECIMAL128>("-2.34", "3.45", "1.11", 2);
3348 assert_unchecked_add::<DECIMAL128>("-2.34", "-3.45", "-5.79", 2);
3349 assert_unchecked_add::<DECIMAL128>("0", "0", "0", 2);
3350 assert_unchecked_add::<DECIMAL128>("9999999999999999.99", "9999999999999999.99", "19999999999999999.98", 2);
3351 assert_unchecked_add::<DECIMAL128>("0", "9999999999999999.99", "9999999999999999.99", 2);
3352 assert_unchecked_add::<DECIMAL128>(
3353 "-9999999999999999.99",
3354 "-9999999999999999.99",
3355 "-19999999999999999.98",
3356 2,
3357 );
3358 assert_unchecked_add::<DECIMAL128>("-9999999999999999.99", "9999999999999999.99", "0", 2);
3359 assert_unchecked_add::<DECIMAL128>("0", "9999999999999999.99", "9999999999999999.99", 2);
3360
3361 assert_unchecked_add::<DECIMAL128>(
3362 "99999999999999999999999999999999999.99",
3363 "99999999999999999999999999999999999.99",
3364 "199999999999999999999999999999999999.98",
3365 2,
3366 );
3367
3368 assert_unchecked_add::<DECIMAL128>(
3369 "-99999999999999999999999999999999999.99",
3370 "-99999999999999999999999999999999999.99",
3371 "-199999999999999999999999999999999999.98",
3372 2,
3373 );
3374
3375 assert_unchecked_add::<DECIMAL128>(
3376 "-99999999999999999999999999999999999.99",
3377 "99999999999999999999999999999999999.99",
3378 "0",
3379 2,
3380 );
3381
3382 assert_unchecked_add::<DECIMAL128>(
3383 "9999999999999999999999999999999999999",
3384 "9999999999999999999999999999999999999",
3385 "19999999999999999999999999999999999998",
3386 0,
3387 );
3388
3389 assert_unchecked_add::<DECIMAL128>(
3390 "0.9999999999999999999999999999999999999",
3391 "0.9999999999999999999999999999999999999",
3392 "1.9999999999999999999999999999999999998",
3393 37,
3394 );
3395
3396 fn assert_unchecked_add_with_negative<const DECIMAL_MODEL: u8>(
3397 val1: &str,
3398 val2: &str,
3399 expected: &str,
3400 scale: i16,
3401 negative: bool,
3402 ) {
3403 let mut var1 = val1.parse::<Decimal>().unwrap();
3404 let ret = var1.round_with_precision(38, scale);
3405 assert!(!ret);
3406 let mut var2 = val2.parse::<Decimal>().unwrap();
3407 let ret = var2.round_with_precision(38, scale);
3408 assert!(!ret);
3409 let expected = expected.parse::<Decimal>().unwrap();
3410
3411 let result =
3412 unsafe { var1.add_with_same_scale_and_negative_unchecked::<DECIMAL_MODEL>(&var2, scale, negative) };
3413 assert_eq!(result, expected);
3414 }
3415
3416 assert_unchecked_add_with_negative::<DECIMAL64>("2.34", "3.45", "5.79", 2, false);
3417 assert_unchecked_add_with_negative::<DECIMAL64>("0", "-3.45", "-3.45", 2, true);
3418 assert_unchecked_add_with_negative::<DECIMAL64>("-2.34", "-3.45", "-5.79", 2, true);
3419 assert_unchecked_add_with_negative::<DECIMAL64>("0", "0", "0", 0, false);
3420 assert_unchecked_add_with_negative::<DECIMAL64>(
3421 "9999999999999999.99",
3422 "9999999999999999.99",
3423 "19999999999999999.98",
3424 2,
3425 false,
3426 );
3427 assert_unchecked_add_with_negative::<DECIMAL64>("0", "9999999999999999.99", "9999999999999999.99", 2, false);
3428 assert_unchecked_add_with_negative::<DECIMAL64>(
3429 "-9999999999999999.99",
3430 "-9999999999999999.99",
3431 "-19999999999999999.98",
3432 2,
3433 true,
3434 );
3435
3436 assert_unchecked_add_with_negative::<DECIMAL128>("2.34", "3.45", "5.79", 2, false);
3437 assert_unchecked_add_with_negative::<DECIMAL128>("0", "-3.45", "-3.45", 2, true);
3438 assert_unchecked_add_with_negative::<DECIMAL128>("-2.34", "-3.45", "-5.79", 2, true);
3439 assert_unchecked_add_with_negative::<DECIMAL128>("0", "0", "0", 0, false);
3440 assert_unchecked_add_with_negative::<DECIMAL128>(
3441 "9999999999999999.99",
3442 "9999999999999999.99",
3443 "19999999999999999.98",
3444 2,
3445 false,
3446 );
3447 assert_unchecked_add_with_negative::<DECIMAL128>("0", "9999999999999999.99", "9999999999999999.99", 2, false);
3448 assert_unchecked_add_with_negative::<DECIMAL128>(
3449 "-9999999999999999.99",
3450 "-9999999999999999.99",
3451 "-19999999999999999.98",
3452 2,
3453 true,
3454 );
3455 assert_unchecked_add_with_negative::<DECIMAL128>(
3456 "99999999999999999999999999999999999.99",
3457 "99999999999999999999999999999999999.99",
3458 "199999999999999999999999999999999999.98",
3459 2,
3460 false,
3461 );
3462
3463 assert_unchecked_add_with_negative::<DECIMAL128>(
3464 "-99999999999999999999999999999999999.99",
3465 "-99999999999999999999999999999999999.99",
3466 "-199999999999999999999999999999999999.98",
3467 2,
3468 true,
3469 );
3470
3471 let zero_decimal = unsafe { Decimal::from_raw_parts(0, 2, true) };
3472 let val = unsafe { Decimal::from_raw_parts(38, 2, true) };
3473 let ret = unsafe { zero_decimal.add_with_same_scale_unchecked::<DECIMAL64>(&val, 2) };
3474 assert_eq!(ret, val);
3475 let ret = unsafe { val.add_with_same_scale_unchecked::<DECIMAL64>(&zero_decimal, 2) };
3476 assert_eq!(ret, val);
3477 }
3478
3479 #[test]
3480 fn test_unchecked_sub() {
3481 fn assert_unchecked_sub<const DECIMAL_MODEL: u8>(val1: &str, val2: &str, expected: &str, scale: i16) {
3482 let mut var1 = val1.parse::<Decimal>().unwrap();
3483 let ret = var1.round_with_precision(38, scale);
3484 assert!(!ret);
3485 let mut var2 = val2.parse::<Decimal>().unwrap();
3486 let ret = var2.round_with_precision(38, scale);
3487 assert!(!ret);
3488 let expected = expected.parse::<Decimal>().unwrap();
3489
3490 let result = unsafe { var1.sub_with_same_scale_unchecked::<DECIMAL_MODEL>(&var2, scale) };
3491 assert_eq!(result, expected);
3492 }
3493 assert_unchecked_sub::<DECIMAL64>("2.34", "3.45", "-1.11", 2);
3494 assert_unchecked_sub::<DECIMAL64>("3.45", "2.34", "1.11", 2);
3495 assert_unchecked_sub::<DECIMAL64>("-2.34", "-3.45", "1.11", 2);
3496 assert_unchecked_sub::<DECIMAL64>("-3.45", "-2.34", "-1.11", 2);
3497 assert_unchecked_sub::<DECIMAL64>("0", "-3.45", "3.45", 2);
3498 assert_unchecked_sub::<DECIMAL64>("-3.45", "0", "-3.45", 2);
3499 assert_unchecked_sub::<DECIMAL64>("-2.34", "3.45", "-5.79", 2);
3500 assert_unchecked_sub::<DECIMAL64>("3.45", "-2.34", "5.79", 2);
3501 assert_unchecked_sub::<DECIMAL64>("2.34", "-3.45", "5.79", 2);
3502 assert_unchecked_sub::<DECIMAL64>("-3.45", "2.34", "-5.79", 2);
3503 assert_unchecked_sub::<DECIMAL64>("0", "0", "0", 2);
3504 assert_unchecked_sub::<DECIMAL64>("9999999999999999.99", "9999999999999999.99", "0", 2);
3505 assert_unchecked_sub::<DECIMAL64>("-9999999999999999.99", "-9999999999999999.99", "0", 2);
3506 assert_unchecked_sub::<DECIMAL64>("9999999999999999.99", "-9999999999999999.99", "19999999999999999.98", 2);
3507 assert_unchecked_sub::<DECIMAL64>(
3508 "-9999999999999999.99",
3509 "9999999999999999.99",
3510 "-19999999999999999.98",
3511 2,
3512 );
3513 assert_unchecked_sub::<DECIMAL64>("0", "9999999999999999.99", "-9999999999999999.99", 2);
3514 assert_unchecked_sub::<DECIMAL64>("-9999999999999999.99", "0", "-9999999999999999.99", 2);
3515 assert_unchecked_sub::<DECIMAL64>("0", "-9999999999999999.99", "9999999999999999.99", 2);
3516
3517 assert_unchecked_sub::<DECIMAL128>("2.34", "3.45", "-1.11", 2);
3518 assert_unchecked_sub::<DECIMAL128>("3.45", "2.34", "1.11", 2);
3519 assert_unchecked_sub::<DECIMAL128>("-2.34", "-3.45", "1.11", 2);
3520 assert_unchecked_sub::<DECIMAL128>("-3.45", "-2.34", "-1.11", 2);
3521 assert_unchecked_sub::<DECIMAL128>("0", "-3.45", "3.45", 2);
3522 assert_unchecked_sub::<DECIMAL128>("-3.45", "0", "-3.45", 2);
3523 assert_unchecked_sub::<DECIMAL128>("-2.34", "3.45", "-5.79", 2);
3524 assert_unchecked_sub::<DECIMAL128>("3.45", "-2.34", "5.79", 2);
3525 assert_unchecked_sub::<DECIMAL128>("2.34", "-3.45", "5.79", 2);
3526 assert_unchecked_sub::<DECIMAL128>("-3.45", "2.34", "-5.79", 2);
3527 assert_unchecked_sub::<DECIMAL128>("0", "0", "0", 2);
3528 assert_unchecked_sub::<DECIMAL128>("9999999999999999.99", "9999999999999999.99", "0", 2);
3529 assert_unchecked_sub::<DECIMAL128>("-9999999999999999.99", "-9999999999999999.99", "0", 2);
3530 assert_unchecked_sub::<DECIMAL128>("9999999999999999.99", "-9999999999999999.99", "19999999999999999.98", 2);
3531 assert_unchecked_sub::<DECIMAL128>(
3532 "-9999999999999999.99",
3533 "9999999999999999.99",
3534 "-19999999999999999.98",
3535 2,
3536 );
3537 assert_unchecked_sub::<DECIMAL128>("0", "9999999999999999.99", "-9999999999999999.99", 2);
3538 assert_unchecked_sub::<DECIMAL128>("-9999999999999999.99", "0", "-9999999999999999.99", 2);
3539 assert_unchecked_sub::<DECIMAL128>("0", "-9999999999999999.99", "9999999999999999.99", 2);
3540
3541 assert_unchecked_sub::<DECIMAL128>(
3542 "-99999999999999999999999999999999999.99",
3543 "99999999999999999999999999999999999.99",
3544 "-199999999999999999999999999999999999.98",
3545 2,
3546 );
3547
3548 assert_unchecked_sub::<DECIMAL128>(
3549 "99999999999999999999999999999999999.99",
3550 "-99999999999999999999999999999999999.99",
3551 "199999999999999999999999999999999999.98",
3552 2,
3553 );
3554
3555 assert_unchecked_sub::<DECIMAL128>(
3556 "99999999999999999999999999999999999.99",
3557 "0",
3558 "99999999999999999999999999999999999.99",
3559 2,
3560 );
3561 }
3562
3563 #[test]
3564 fn test_unchecked_mul() {
3565 fn assert_unchecked_mul<const DECIMAL_MODEL: u8>(val1: &str, val2: &str, expected: &str, scale: i16) {
3566 let var1 = val1.parse::<Decimal>().unwrap();
3567 let var2 = val2.parse::<Decimal>().unwrap();
3568 let mut expected = expected.parse::<Decimal>().unwrap();
3569 let ret = expected.round_with_precision(38, scale);
3570 assert!(!ret);
3571 let result = unsafe { var1.mul_unchecked::<DECIMAL_MODEL>(&var2, scale) };
3572 assert_eq!(result, expected);
3573 }
3574
3575 assert_unchecked_mul::<DECIMAL64>("2.03", "3.18", "6.4554", 4);
3576 assert_unchecked_mul::<DECIMAL64>("2.03", "-3.18", "-6.4554", 4);
3577 assert_unchecked_mul::<DECIMAL64>("-2.03", "3.18", "-6.4554", 4);
3578 assert_unchecked_mul::<DECIMAL64>("999999999", "999999999", "999999998000000001", 0);
3579 assert_unchecked_mul::<DECIMAL64>("999999999", "9999999999", "9999999989000000001", 0);
3580 assert_unchecked_mul::<DECIMAL64>("999999999", "9999999999", "9999999989000000001", 0);
3581 assert_unchecked_mul::<DECIMAL64>("0.999999999", "0.9999999999", "0.9999999989000000001", 19);
3582 assert_unchecked_mul::<DECIMAL64>("0", "0.9999999999", "0", 19);
3583
3584 assert_unchecked_mul::<DECIMAL128>("2.03", "3.18", "6.4554", 4);
3585 assert_unchecked_mul::<DECIMAL128>("2.03", "-3.18", "-6.4554", 4);
3586 assert_unchecked_mul::<DECIMAL128>("-2.03", "3.18", "-6.4554", 4);
3587 assert_unchecked_mul::<DECIMAL128>("999999999", "999999999", "999999998000000001", 0);
3588 assert_unchecked_mul::<DECIMAL128>("999999999", "9999999999", "9999999989000000001", 0);
3589 assert_unchecked_mul::<DECIMAL128>("999999.999", "99999.99999", "99999999890.00000001", 8);
3590 assert_unchecked_mul::<DECIMAL128>("0.999999999", "0.9999999999", "0.9999999989000000001", 19);
3591 assert_unchecked_mul::<DECIMAL128>("0", "0.9999999999", "0", 19);
3592
3593 assert_unchecked_mul::<DECIMAL128>(
3594 "9999999999999999999",
3595 "9999999999999999999",
3596 "99999999999999999980000000000000000001",
3597 0,
3598 );
3599
3600 assert_unchecked_mul::<DECIMAL128>(
3601 "9999999999999999999",
3602 "9999999999999999999",
3603 "99999999999999999980000000000000000001",
3604 0,
3605 );
3606 assert_unchecked_mul::<DECIMAL128>(
3607 "0.9999999999999999999",
3608 "0.9999999999999999999",
3609 "0.99999999999999999980000000000000000001",
3610 38,
3611 );
3612 assert_unchecked_mul::<DECIMAL128>(
3613 "999999999999.9999999",
3614 "99999999999999.99999",
3615 "99999999999999999980000000.000000000001",
3616 12,
3617 );
3618 }
3619
3620 #[test]
3621 fn test_unchecked_and_compare() {
3622 unsafe {
3623 let left = Decimal::from_raw_parts(123, 2, true);
3624 let right = Decimal::from_raw_parts(0, 1, false);
3625 let mul_val = left.mul_unchecked::<DECIMAL128>(&right, 3);
3626 let expect = Decimal::from_raw_parts(0, 45, false);
3627 assert_eq!(mul_val.cmp(&expect), Ordering::Equal);
3628 }
3629
3630 unsafe {
3631 let left = Decimal::from_raw_parts(0, 2, true);
3632 let right = Decimal::from_raw_parts(0, 2, true);
3633 let val = left.sub_with_same_scale_unchecked::<DECIMAL128>(&right, 2);
3634 let expect = Decimal::from_raw_parts(0, 45, false);
3635 assert_eq!(val.cmp(&expect), Ordering::Equal);
3636 }
3637
3638 unsafe {
3639 let left = Decimal::from_raw_parts(0, 2, true);
3640 let right = Decimal::from_raw_parts(0, 2, true);
3641 let val = left.add_with_same_scale_unchecked::<DECIMAL128>(&right, 2);
3642 let expect = Decimal::from_raw_parts(0, 45, false);
3643 assert_eq!(val.cmp(&expect), Ordering::Equal);
3644 }
3645
3646 unsafe {
3647 let left = Decimal::from_raw_parts(0, 2, true);
3648 let right = Decimal::from_raw_parts(0, 2, true);
3649 let val = left.add_with_same_scale_and_negative_unchecked::<DECIMAL128>(&right, 2, true);
3650 let expect = Decimal::from_raw_parts(0, 45, false);
3651 assert_eq!(val.cmp(&expect), Ordering::Equal);
3652 }
3653 }
3654
3655 #[test]
3656 fn test_has_frac() {
3657 fn assert_has_frac(int_val: u128, scale: i16, expected: bool) {
3658 let decimal = Decimal::from_parts(int_val, scale, false).unwrap();
3659 let has_frac = decimal.has_fract();
3660 println!("decimal: {}, has_fract: {}", decimal, has_frac);
3661 assert_eq!(has_frac, expected);
3662 }
3663
3664 assert_has_frac(0, 0, false);
3665 assert_has_frac(0, 1, false);
3666 assert_has_frac(0, -1, false);
3667 assert_has_frac(0, MAX_SCALE, false);
3668 assert_has_frac(0, MIN_SCALE, false);
3669 assert_has_frac(1, 0, false);
3670 assert_has_frac(1, 1, true);
3671 assert_has_frac(1, -1, false);
3672 assert_has_frac(1, MAX_SCALE, true);
3673 assert_has_frac(1, MIN_SCALE, false);
3674 assert_has_frac(MAX_I128_REPR as u128, 0, false);
3675 assert_has_frac(MAX_I128_REPR as u128, 1, true);
3676 assert_has_frac(MAX_I128_REPR as u128, -1, false);
3677 assert_has_frac(MAX_I128_REPR as u128, MAX_SCALE, true);
3678 assert_has_frac(MAX_I128_REPR as u128, MIN_SCALE, false);
3679 assert_has_frac(99_9999_9999_9999_9999_9999_0000_0000_0000_0000_u128, 0, false);
3680 assert_has_frac(99_9999_9999_9999_9999_9999_0000_0000_0000_0000_u128, 16, false);
3681 assert_has_frac(99_9999_9999_9999_9999_9999_0000_0000_0000_0000_u128, 17, true);
3682 assert_has_frac(99_9999_9999_9999_9999_9999_0000_0000_0000_0000_u128, MAX_SCALE, true);
3683 assert_has_frac(99_9999_9999_9999_9999_9999_0000_0000_0000_0000_u128, MIN_SCALE, false);
3684 assert_has_frac(
3685 90_0000_0000_0000_0000_0000_0000_0000_0000_0000_u128,
3686 MAX_PRECISION as i16,
3687 true,
3688 );
3689 assert_has_frac(
3690 90_0000_0000_0000_0000_0000_0000_0000_0000_0000_u128,
3691 MAX_PRECISION as i16 - 1,
3692 false,
3693 );
3694 }
3695}