fastnum 0.7.5

Fast decimal numbers library
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
macro_rules! test_impl {
    (D, $bits: literal) => {
        paste::paste! { test_impl!(SIGNED: $bits, [< dec $bits >], [<D $bits>]); }
    };
    (UD, $bits: literal) => {
        paste::paste! { test_impl!(UNSIGNED: $bits, [< udec $bits >], [<UD $bits>]); }
    };
    (UNSIGNED: $bits: tt, $dec: ident, $D: ident) => {
        mod $dec {
            use rstest::*;
            use fastnum::{*, decimal::{*, RoundingMode::*}};

            super::test_impl!(COMMON:: $bits, $dec, $D, THIS);
            super::test_impl!(UNSIGNED:: $bits, $dec, $D, THIS);
        }
    };
    (SIGNED: $bits: tt, $dec: ident, $D: ident) => {
        mod $dec {
            use rstest::*;
            use fastnum::{*, decimal::{*, RoundingMode::*}};

            super::test_impl!(COMMON:: $bits, $dec, $D, THIS);
            super::test_impl!(SIGNED:: $bits, $dec, $D, THIS);
        }
    };
    (COMMON:: 512, $dec: ident, $D: ident, THIS) => {
        super::test_impl!(COMMON:: 256, $dec, $D);

        #[rstest(::trace)]
        #[case($dec!(1),                                           $dec!(3),                                          $dec!(0.3333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333))]
        #[case($dec!(1),                                           $dec!(9),                                          $dec!(0.11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111))]
        #[case($dec!(1),                                           $dec!(9.9),                                        $dec!(0.10101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101))]
        #[case($dec!(1),                                           $dec!(9.09),                                       $dec!(0.11001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110011001100110))]
        #[case($dec!(1),                                           $dec!(9.009),                                      $dec!(0.11100011100011100011100011100011100011100011100011100011100011100011100011100011100011100011100011100011100011100011100011100011100011100011100011100011100))]
        #[case($dec!(1),                                           $dec!(99999),                                      $dec!(0.000010000100001000010000100001000010000100001000010000100001000010000100001000010000100001000010000100001000010000100001000010000100001000010000100001000010000))]
        #[case($dec!(1),                                           $dec!(999999),                                     $dec!(0.0000010000010000010000010000010000010000010000010000010000010000010000010000010000010000010000010000010000010000010000010000010000010000010000010000010000010000))]
        #[case($dec!(1),                                           $dec!(7),                                          $dec!(0.1428571428571428571428571428571428571428571428571428571428571428571428571428571428571428571428571428571428571428571428571428571428571428571428571428571429))]
        #[case($dec!(1),                                           $dec!(73),                                         $dec!(0.01369863013698630136986301369863013698630136986301369863013698630136986301369863013698630136986301369863013698630136986301369863013698630136986301369863014))]
        #[case($dec!(2),                                           $dec!(3),                                          $dec!(0.6666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666667))]
        #[case($dec!(8),                                           $dec!(9),                                          $dec!(0.8888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888889))]
        #[case($dec!(5),                                           $dec!(11),                                         $dec!(0.4545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545))]
        #[case($dec!(5),                                           $dec!(14),                                         $dec!(0.3571428571428571428571428571428571428571428571428571428571428571428571428571428571428571428571428571428571428571428571428571428571428571428571428571428571))]
        #[case($dec!(5),                                           $dec!(18),                                         $dec!(0.2777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777778))]
        #[case($dec!(7),                                           $dec!(11),                                         $dec!(0.6363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636364))]
        #[case($dec!(25),                                          $dec!(39),                                         $dec!(0.6410256410256410256410256410256410256410256410256410256410256410256410256410256410256410256410256410256410256410256410256410256410256410256410256410256410))]
        #[case($dec!(36),                                          $dec!(55),                                         $dec!(0.6545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545454545))]
        #[case($dec!(222),                                         $dec!(1111),                                       $dec!(0.1998199819981998199819981998199819981998199819981998199819981998199819981998199819981998199819981998199819981998199819981998199819981998199819981998199820))]
        #[case($dec!(73),                                          $dec!(72),                                         $dec!(1.0138888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888889))]
        #[case($dec!(79),                                          $dec!(12345),                                      $dec!(0.006399351964358039692183070068853786958282705548805184285135682462535439449169704333738355609558525718914540299716484406642365330093155123531794248683677602))]
        #[case($dec!(99),                                          $dec!(98),                                         $dec!(1.0102040816326530612244897959183673469387755102040816326530612244897959183673469387755102040816326530612244897959183673469387755102040816326530612244897959))]
        #[case($dec!(999),                                         $dec!(998),                                        $dec!(1.0010020040080160320641282565130260521042084168336673346693386773547094188376753507014028056112224448897795591182364729458917835671342685370741482965931864))]
        #[case($dec!(2048),                                        $dec!(1025),                                       $dec!(1.998048780487804878048780487804878048780487804878048780487804878048780487804878048780487804878048780487804878048780487804878048780487804878048780487804878))]
        #[case($dec!(1),                                           $dec!(2.71828182845904523536028747135266249775),   $dec!(0.3678794411714423215955237701614608674467919185102941350233065609792706323673346672495632434215969087581719789411441235948976404676922678808421577415895686))]
        #[case($dec!(0.3),                                         $dec!(340282366920938463463374607431768211455),    $dec!(8.816207631167156309765524029166842583665900181455939745191796852676530644623877935735147063631769331147180691715892213489627491384067345218278290070790250e-40))]
        #[case($dec!(0.3),                                         $dec!(34028236692093846346337460743176821159),     $dec!(8.816207631167156309765524029166842580168251916642689671910324348242368819688960158808527556813722752727023292393285020651327884127911762486042486929252940e-39))]
        #[case($dec!(1.2345678),                                   $dec!(1.9876543),                                  $dec!(0.6211179680490717123193907511985358822205652159935457589380608086627538802899478043037966914065489154728767472291333558355695957793062908373956175377177007))]
        #[case($dec!(340282366920938463463374607431768211455),     $dec!(9.99),                                       $dec!(34062298991084931277615075818995816962.46246246246246246246246246246246246246246246246246246246246246246246246246246246246246246246246246246246246246246246))]
        #[case($dec!(68056473384187692692674921486353642291),      $dec!(11),                                         $dec!(6186952125835244790243174680577603844.636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636363636))]
        #[case($dec!(690564733841876926926749214863536423),        $dec!(340282366920938463463374607431768211455),    $dec!(0.002029387358770557187699218413430556142210039229539867821776938377050593712992056598562795349234526470017453188311102645450353170213566637751809681718379401))]
        #[case($dec!(340282366920938463463374607431768211455),     $dec!(340282366920938463463374607431768211454),    $dec!(1.0000000000000000000000000000000000000029387358770557187699218413430556141945639362290404076930226519694216439477791514505312714387389783679225704053481984))]
        #[case($dec!(340282366920938463463374607431768211454),     $dec!(340282366920938463463374607431768211455),    $dec!(0.9999999999999999999999999999999999999970612641229442812300781586569443858054446999395146867516027343824411564517920406880882843121227435562842731027613693))]
        #[case($dec!(20000),                                       $dec!(9),                                          $dec!(2222.222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222))]
        #[case($dec!(18446744073709551614),                        $dec!(18446744073709551615),                       $dec!(0.9999999999999999999457898913757247782966886240794471956586297869658311405777418118997379155710431557592864253533519365178082821543144448620350578672179409))]
        #[case($dec!(18446744073709551613),                        $dec!(18446744073709551615),                       $dec!(0.9999999999999999998915797827514495565933772481588943913172595739316622811554836237994758311420863115185728507067038730356165643086288897240701157344358818))]
        #[case($dec!(18446744073709551612),                        $dec!(18446744073709551615),                       $dec!(0.9999999999999999998373696741271743348900658722383415869758893608974934217332254356992137467131294672778592760600558095534248464629433345861051736016538227))]
        #[case($dec!(18446744073709551613),                        $dec!(18446744073709551614),                       $dec!(0.9999999999999999999457898913757247782937498882023914768882300180494357907000260307085917221132092181494609554744036202910221171980511873301157617450998075))]
        #[case($dec!(436696),                                      $dec!(9),                                          $dec!(48521.77777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777778))]
        #[case($dec!(1175000),                                     $dec!(11),                                         $dec!(106818.18181818181818181818181818181818181818181818181818181818181818181818181818181818181818181818181818181818181818181818181818181818181818181818181818182))]
        #[case($dec!(436696),                                      $dec!(15),                                         $dec!(29113.06666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666667))]
        #[case($dec!(1),                                           $dec!(2.718281828459045235),                       $dec!(0.3678794411714423216442833771435764278421734458730042128760708475531603457815965409448360397113284966249805199023642630079036160307712867960226923981288397))]
        #[case($dec!(18446744073709551615),                        $dec!(18446744073709551614),                       $dec!(1.0000000000000000000542101086242752217062501117976085231117699819505642092999739692914082778867907818505390445255963797089778828019488126698842382549001925))]
        #[case($dec!(18446744073709551615),                        $dec!(18446744073709551613),                       $dec!(1.0000000000000000001084202172485504434183776953493284837649767384983720992663983211695382940825419699510602078965064253063819545331745257615735857038235936))]
        #[case($dec!(18446744073709551615),                        $dec!(18446744073709551515),                       $dec!(1.0000000000000000054210108624275221997184963626124682958508096694831610344227045330156352762341155331244476483601570638849001008570840461192537745353992050))]
        #[case($dec!(1),                                           $dec!(18446744073709551615),                       $dec!(0.5421010862427522170331137592055280434137021303416885942225818810026208442895684424071357464664806348219171784568555513796494213278205908875911283048815046e-19))]
        #[case($dec!(20),                                          $dec!(9),                                          $dec!(2.222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222))]
        #[case($dec!(20000000000000000000),                        $dec!(9),                                          $dec!(2222222222222222222.222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222))]
        #[case($dec!(3195385192916917),                            $dec!(3195385192946695),                           $dec!(0.9999999999906809357238901267196182952346769709862282809728288362001108644161032480654986823174314581800500581709641690609171089789775421589131704675771359))]
        #[case($dec!(1393723067526993),                            $dec!(1393723067519475),                           $dec!(1.0000000000053941849533856181569103684842284283809270103490494509401181751933234745991674743750204977048257657593792521568034455053218475188822667739692612))]
        #[case($dec!(0.70710678118654752440084436210484903932),    $dec!(0.70710678118654752440084436210484903925),   $dec!(1.0000000000000000000000000000000000000989949493661166534161182106946788655047540625527727302447351633187025469849352546065537428274621591426007457237444114))]
        #[case($dec!(13407807929942597099574024998205846127479365820592393377723561443721764030073546976801874298166903427690031858186486050853753882811946569946433649006084095), $dec!(13407807929942597099574024998205846127479365820592393377723561443721764030073546976801874298166903427690031858186486050853753882811946569946433649006084094),    $dec!(1.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001))]
        #[case($dec!(13407807929942597099574024998205846127479365820592393377723561443721764030073546976801874298166903427690031858186486050853753882811946569946433649006084095), $dec!(13407807929942597099574024998205846127479365820592393377723561443721764030073546976801874298166903427690031858186486050853753882811946569946433649006084093),    $dec!(1.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001))]
        #[case($dec!(13407807929942597099574024998205846127479365820592393377723561443721764030073546976801874298166903427690031858186486050853753882811946569946433649006084095), $dec!(13407807929942597099574024998205846127479365820592393377723561443721764030073546976801874298166903427690031858186486050853753882811946569946433649006084),       $dec!(1000.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000071))]
        #[case($dec!(1000),                                        $dec!(330.189681705037027119772492465920151004),   $dec!(3.028562233792980000000000000000000000000009711765769060619232670478400000000000000031142960610379458573195966019940921472000099866905632080493364284487695))]
        fn test_div_512(
            #[case] a: $D,
            #[case] b: $D,
            #[case] expected: $D,
        ) {
            let d = a / b;

            assert_eq!(d, expected);
            assert_eq!(d.fractional_digits_count(), expected.fractional_digits_count());
            assert!(d.is_op_inexact());
            assert!(d.is_op_rounded());
        }

        #[rstest(::trace)]
        #[case($dec!(1),       $dec!(3),                                          $dec!(0.3333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333), HalfUp)]
        #[case($dec!(1),       $dec!(3),                                          $dec!(0.3333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333), Down)]
        #[case($dec!(1),       $dec!(3),                                          $dec!(0.3333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333334), Up)]
        #[case($dec!(2),       $dec!(3),                                          $dec!(0.6666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666667), HalfUp)]
        #[case($dec!(2),       $dec!(3),                                          $dec!(0.6666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666), Down)]
        #[case($dec!(2),       $dec!(3),                                          $dec!(0.6666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666667), Up)]
        #[case($dec!(8),       $dec!(9),                                          $dec!(0.8888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888889), HalfUp)]
        #[case($dec!(8),       $dec!(9),                                          $dec!(0.8888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888), Down)]
        #[case($dec!(12.34),   $dec!(1.233),                                      $dec!(10.008110300081103000811030008110300081103000811030008110300081103000811030008110300081103000811030008110300081103000811030008110300081103000811030008110300), HalfUp)]
        #[case($dec!(125348),  $dec!(352.2283),                                   $dec!(355.8714617763535752237966114591019517738921035021887792661748076460636467881768727839301952739175131583691600021917602872909416988924512879856615723381682), HalfUp)]
        #[case($dec!(1),       $dec!(2.71828182845904523536028747135266249775),   $dec!(0.3678794411714423215955237701614608674467919185102941350233065609792706323673346672495632434215969087581719789411441235948976404676922678808421577415895686), HalfUp)]
        fn test_div_round_512(
            #[case] a: $D,
            #[case] b: $D,
            #[case] expected: $D,
            #[case] mode: RoundingMode,
        ) {
            let ctx = Context::default().with_rounding_mode(mode);
            let d = a.with_ctx(ctx) / b.with_ctx(ctx);

            assert_eq!(d, expected);
            assert_eq!(d.fractional_digits_count(), expected.fractional_digits_count());

            assert!(d.is_op_inexact());
            assert!(d.is_op_rounded());
        }

        // #[rstest(::trace)]
        // fn test_div_exact_512(
        //     #[case] a: $D,
        //     #[case] b: $D,
        //     #[case] expected: $D,
        // ) {
        //     let d = a / b;
        //
        //     assert_eq!(d, expected);
        //     assert_eq!(d.fractional_digits_count(), expected.fractional_digits_count());
        //     assert!(d.is_op_ok());
        // }
    };
    (UNSIGNED:: 512, $dec: ident, $D: ident, THIS) => {
        super::test_impl!(UNSIGNED:: 256, $dec, $D);
    };
    (SIGNED:: 512, $dec: ident, $D: ident, THIS) => {
        super::test_impl!(SIGNED:: 256, $dec, $D);
    };


    (COMMON:: 256, $dec: ident, $D: ident, THIS) => {
        super::test_impl!(COMMON:: 256, $dec, $D);

        #[rstest(::trace)]
        #[case($dec!(1),                                                                               $dec!(3),                                                                              $dec!(0.33333333333333333333333333333333333333333333333333333333333333333333333333333))]
        #[case($dec!(1),                                                                               $dec!(9),                                                                              $dec!(0.111111111111111111111111111111111111111111111111111111111111111111111111111111))]
        #[case($dec!(1),                                                                               $dec!(9.9),                                                                            $dec!(0.101010101010101010101010101010101010101010101010101010101010101010101010101010))]
        #[case($dec!(1),                                                                               $dec!(9.09),                                                                           $dec!(0.110011001100110011001100110011001100110011001100110011001100110011001100110011))]
        #[case($dec!(1),                                                                               $dec!(9.009),                                                                          $dec!(0.111000111000111000111000111000111000111000111000111000111000111000111000111000))]
        #[case($dec!(1),                                                                               $dec!(99999),                                                                          $dec!(0.0000100001000010000100001000010000100001000010000100001000010000100001000010000100))]
        #[case($dec!(1),                                                                               $dec!(999999),                                                                         $dec!(0.00000100000100000100000100000100000100000100000100000100000100000100000100000100000))]
        #[case($dec!(1),                                                                               $dec!(7),                                                                              $dec!(0.14285714285714285714285714285714285714285714285714285714285714285714285714286))]
        #[case($dec!(1),                                                                               $dec!(73),                                                                             $dec!(0.013698630136986301369863013698630136986301369863013698630136986301369863013699))]
        #[case($dec!(2),                                                                               $dec!(3),                                                                              $dec!(0.66666666666666666666666666666666666666666666666666666666666666666666666666667))]
        #[case($dec!(8),                                                                               $dec!(9),                                                                              $dec!(0.88888888888888888888888888888888888888888888888888888888888888888888888888889))]
        #[case($dec!(5),                                                                               $dec!(11),                                                                             $dec!(0.45454545454545454545454545454545454545454545454545454545454545454545454545455))]
        #[case($dec!(5),                                                                               $dec!(14),                                                                             $dec!(0.35714285714285714285714285714285714285714285714285714285714285714285714285714))]
        #[case($dec!(5),                                                                               $dec!(18),                                                                             $dec!(0.27777777777777777777777777777777777777777777777777777777777777777777777777778))]
        #[case($dec!(7),                                                                               $dec!(11),                                                                             $dec!(0.63636363636363636363636363636363636363636363636363636363636363636363636363636))]
        #[case($dec!(25),                                                                              $dec!(39),                                                                             $dec!(0.64102564102564102564102564102564102564102564102564102564102564102564102564103))]
        #[case($dec!(36),                                                                              $dec!(55),                                                                             $dec!(0.65454545454545454545454545454545454545454545454545454545454545454545454545455))]
        #[case($dec!(222),                                                                             $dec!(1111),                                                                           $dec!(0.19981998199819981998199819981998199819981998199819981998199819981998199819982))]
        #[case($dec!(73),                                                                              $dec!(72),                                                                             $dec!(1.01388888888888888888888888888888888888888888888888888888888888888888888888889))]
        #[case($dec!(79),                                                                              $dec!(12345),                                                                          $dec!(0.0063993519643580396921830700688537869582827055488051842851356824625354394491697))]
        #[case($dec!(99),                                                                              $dec!(98),                                                                             $dec!(1.01020408163265306122448979591836734693877551020408163265306122448979591836735))]
        #[case($dec!(999),                                                                             $dec!(998),                                                                            $dec!(1.00100200400801603206412825651302605210420841683366733466933867735470941883768))]
        #[case($dec!(2048),                                                                            $dec!(1025),                                                                           $dec!(1.9980487804878048780487804878048780487804878048780487804878048780487804878049))]
        #[case($dec!(1),                                                                               $dec!(2.71828182845904523536028747135266249775),                                       $dec!(0.36787944117144232159552377016146086744679191851029413502330656097927063236733))]
        #[case($dec!(0.3),                                                                             $dec!(340282366920938463463374607431768211455),                                        $dec!(8.8162076311671563097655240291668425836659001814559397451917968526765306446239e-40))]
        #[case($dec!(0.3),                                                                             $dec!(34028236692093846346337460743176821159),                                         $dec!(8.8162076311671563097655240291668425801682519166426896719103243482423688196890e-39))]
        #[case($dec!(1.2345678),                                                                       $dec!(1.9876543),                                                                      $dec!(0.62111796804907171231939075119853588222056521599354575893806080866275388028995))]
        #[case($dec!(340282366920938463463374607431768211455),                                         $dec!(9.99),                                                                           $dec!(34062298991084931277615075818995816962.462462462462462462462462462462462462462))]
        #[case($dec!(68056473384187692692674921486353642291),                                          $dec!(11),                                                                             $dec!(6186952125835244790243174680577603844.6363636363636363636363636363636363636364))]
        #[case($dec!(690564733841876926926749214863536423),                                            $dec!(340282366920938463463374607431768211455),                                        $dec!(0.0020293873587705571876992184134305561422100392295398678217769383770505937129921))]
        #[case($dec!(340282366920938463463374607431768211455),                                         $dec!(340282366920938463463374607431768211454),                                        $dec!(1.00000000000000000000000000000000000000293873587705571876992184134305561419456))]
        #[case($dec!(340282366920938463463374607431768211454),                                         $dec!(340282366920938463463374607431768211455),                                        $dec!(0.99999999999999999999999999999999999999706126412294428123007815865694438580544))]
        #[case($dec!(115792089237316195423570985008687907853269984665640564039457584007913129639935),  $dec!(115792089237316195423570985008687907853269984665640564039457584007913129639934), $dec!(1.00000000000000000000000000000000000000000000000000000000000000000000000000001))]
        #[case($dec!(115792089237316195423570985008687907853269984665640564039457584007913129639935),  $dec!(115792089237316195423570985008687907853269984665640564039457584007913129639933), $dec!(1.00000000000000000000000000000000000000000000000000000000000000000000000000002))]
        #[case($dec!(115792089237316195423570985008687907853269984665640564039457584007913129639935),  $dec!(115792089237316195423570985008687907853269984665640564039457584007913129639835), $dec!(1.00000000000000000000000000000000000000000000000000000000000000000000000000086))]
        #[case($dec!(20000),                                                                           $dec!(9),                                                                              $dec!(2222.2222222222222222222222222222222222222222222222222222222222222222222222222))]
        #[case($dec!(18446744073709551614),                                                            $dec!(18446744073709551615),                                                           $dec!(0.99999999999999999994578989137572477829668862407944719565862978696583114057774))]
        #[case($dec!(18446744073709551613),                                                            $dec!(18446744073709551615),                                                           $dec!(0.99999999999999999989157978275144955659337724815889439131725957393166228115548))]
        #[case($dec!(18446744073709551612),                                                            $dec!(18446744073709551615),                                                           $dec!(0.99999999999999999983736967412717433489006587223834158697588936089749342173323))]
        #[case($dec!(18446744073709551613),                                                            $dec!(18446744073709551614),                                                           $dec!(0.99999999999999999994578989137572477829374988820239147688823001804943579070003))]
        #[case($dec!(2000000000000000000),                                                             $dec!(9),                                                                              $dec!(222222222222222222.22222222222222222222222222222222222222222222222222222222222))]
        #[case($dec!(436696),                                                                          $dec!(9),                                                                              $dec!(48521.777777777777777777777777777777777777777777777777777777777777777777777778))]
        #[case($dec!(1175000),                                                                         $dec!(11),                                                                             $dec!(106818.181818181818181818181818181818181818181818181818181818181818181818181818))]
        #[case($dec!(436696),                                                                          $dec!(15),                                                                             $dec!(29113.066666666666666666666666666666666666666666666666666666666666666666666667))]
        #[case($dec!(1),                                                                               $dec!(2.718281828459045235),                                                           $dec!(0.36787944117144232164428337714357642784217344587300421287607084755316034578160))]
        #[case($dec!(18446744073709551615),                                                            $dec!(18446744073709551614),                                                           $dec!(1.00000000000000000005421010862427522170625011179760852311176998195056420929997))]
        #[case($dec!(18446744073709551615),                                                            $dec!(18446744073709551613),                                                           $dec!(1.00000000000000000010842021724855044341837769534932848376497673849837209926640))]
        #[case($dec!(18446744073709551615),                                                            $dec!(18446744073709551515),                                                           $dec!(1.00000000000000000542101086242752219971849636261246829585080966948316103442270))]
        #[case($dec!(1),                                                                               $dec!(18446744073709551615),                                                           $dec!(0.54210108624275221703311375920552804341370213034168859422258188100262084428957e-19))]
        #[case($dec!(3195385192916917),                                                                $dec!(3195385192946695),                                                               $dec!(0.99999999999068093572389012671961829523467697098622828097282883620011086441610))]
        #[case($dec!(1393723067526993),                                                                $dec!(1393723067519475),                                                               $dec!(1.00000000000539418495338561815691036848422842838092701034904945094011817519332))]
        #[case($dec!(0.70710678118654752440084436210484903932),                                        $dec!(0.70710678118654752440084436210484903925),                                       $dec!(1.00000000000000000000000000000000000009899494936611665341611821069467886550475))]
        #[case($dec!(1000),                                                                            $dec!(330.189681705037027119772492465920151004),                                       $dec!(3.0285622337929800000000000000000000000000097117657690606192326704784000000000))]
        fn test_div_256(
            #[case] a: $D,
            #[case] b: $D,
            #[case] expected: $D,
        ) {
            let d = a / b;

            assert_eq!(d, expected);
            assert_eq!(d.fractional_digits_count(), expected.fractional_digits_count());
            assert!(d.is_op_inexact());
            assert!(d.is_op_rounded());
        }

        #[rstest(::trace)]
        #[case($dec!(1),       $dec!(3),                                          $dec!(0.33333333333333333333333333333333333333333333333333333333333333333333333333333), HalfUp)]
        #[case($dec!(1),       $dec!(3),                                          $dec!(0.33333333333333333333333333333333333333333333333333333333333333333333333333333), Down)]
        #[case($dec!(1),       $dec!(3),                                          $dec!(0.33333333333333333333333333333333333333333333333333333333333333333333333333334), Up)]
        #[case($dec!(2),       $dec!(3),                                          $dec!(0.66666666666666666666666666666666666666666666666666666666666666666666666666667), HalfUp)]
        #[case($dec!(2),       $dec!(3),                                          $dec!(0.66666666666666666666666666666666666666666666666666666666666666666666666666666), Down)]
        #[case($dec!(2),       $dec!(3),                                          $dec!(0.66666666666666666666666666666666666666666666666666666666666666666666666666667), Up)]
        #[case($dec!(8),       $dec!(9),                                          $dec!(0.88888888888888888888888888888888888888888888888888888888888888888888888888889), HalfUp)]
        #[case($dec!(8),       $dec!(9),                                          $dec!(0.88888888888888888888888888888888888888888888888888888888888888888888888888889), Up)]
        #[case($dec!(8),       $dec!(9),                                          $dec!(0.88888888888888888888888888888888888888888888888888888888888888888888888888888), Down)]
        #[case($dec!(12.34),   $dec!(1.233),                                      $dec!(10.0081103000811030008110300081103000811030008110300081103000811030008110300081), Down)]
        #[case($dec!(12.34),   $dec!(1.233),                                      $dec!(10.0081103000811030008110300081103000811030008110300081103000811030008110300081), HalfUp)]
        #[case($dec!(12.34),   $dec!(1.233),                                      $dec!(10.0081103000811030008110300081103000811030008110300081103000811030008110300082), Up)]
        #[case($dec!(125348),  $dec!(352.2283),                                   $dec!(355.87146177635357522379661145910195177389210350218877926617480764606364678817), Down)]
        #[case($dec!(125348),  $dec!(352.2283),                                   $dec!(355.87146177635357522379661145910195177389210350218877926617480764606364678818), HalfUp)]
        #[case($dec!(125348),  $dec!(352.2283),                                   $dec!(355.87146177635357522379661145910195177389210350218877926617480764606364678818), Up)]
        #[case($dec!(1),       $dec!(2.71828182845904523536028747135266249775),   $dec!(0.36787944117144232159552377016146086744679191851029413502330656097927063236733), Down)]
        #[case($dec!(1),       $dec!(2.71828182845904523536028747135266249775),   $dec!(0.36787944117144232159552377016146086744679191851029413502330656097927063236733), HalfUp)]
        #[case($dec!(1),       $dec!(2.71828182845904523536028747135266249775),   $dec!(0.36787944117144232159552377016146086744679191851029413502330656097927063236734), Up)]
        fn test_div_round_256(
            #[case] a: $D,
            #[case] b: $D,
            #[case] expected: $D,
            #[case] mode: RoundingMode,
        ) {
            let ctx = Context::default().with_rounding_mode(mode);
            let d = a.with_ctx(ctx) / b.with_ctx(ctx);

            assert_eq!(d, expected);
            assert_eq!(d.fractional_digits_count(), expected.fractional_digits_count());
            assert!(d.is_op_inexact());
            assert!(d.is_op_rounded());
        }
    };
    (COMMON:: 256, $dec: ident, $D: ident) => {
        super::test_impl!(COMMON:: 128, $dec, $D);

        #[rstest(::trace)]
        #[case($dec!(1),                    $dec!(4611686018427387904),     $dec!(2.1684043449710088680149056017398834228515625E-19))]
        fn test_div_exact_256(
            #[case] a: $D,
            #[case] b: $D,
            #[case] expected: $D,
        ) {
            let d = a / b;

            assert_eq!(d, expected);
            assert_eq!(d.fractional_digits_count(), expected.fractional_digits_count());
            assert!(d.is_op_ok());
        }

    };
    (UNSIGNED:: 256, $dec: ident, $D: ident, THIS) => {
        super::test_impl!(UNSIGNED:: 256, $dec, $D);
    };
    (UNSIGNED:: 256, $dec: ident, $D: ident) => {
        super::test_impl!(UNSIGNED:: 128, $dec, $D);
    };
    (SIGNED:: 256, $dec: ident, $D: ident, THIS) => {
        super::test_impl!(SIGNED:: 256, $dec, $D);
    };
    (SIGNED:: 256, $dec: ident, $D: ident) => {
        super::test_impl!(SIGNED:: 128, $dec, $D);
    };

    (COMMON:: 128, $dec: ident, $D: ident, THIS) => {
        super::test_impl!(COMMON:: 128, $dec, $D);

        #[rstest(::trace)]
        #[case($dec!(1),                                           $dec!(3),                                          $dec!(0.333333333333333333333333333333333333333))]
        #[case($dec!(1),                                           $dec!(9),                                          $dec!(0.111111111111111111111111111111111111111))]
        #[case($dec!(1),                                           $dec!(9.9),                                        $dec!(0.101010101010101010101010101010101010101))]
        #[case($dec!(1),                                           $dec!(9.09),                                       $dec!(0.110011001100110011001100110011001100110))]
        #[case($dec!(1),                                           $dec!(9.009),                                      $dec!(0.111000111000111000111000111000111000111))]
        #[case($dec!(1),                                           $dec!(99999),                                      $dec!(0.0000100001000010000100001000010000100001000))]
        #[case($dec!(1),                                           $dec!(999999),                                     $dec!(0.00000100000100000100000100000100000100000100))]
        #[case($dec!(1),                                           $dec!(7),                                          $dec!(0.142857142857142857142857142857142857143))]
        #[case($dec!(1),                                           $dec!(73),                                         $dec!(0.0136986301369863013698630136986301369863))]
        #[case($dec!(2),                                           $dec!(3),                                          $dec!(0.66666666666666666666666666666666666667))]
        #[case($dec!(8),                                           $dec!(9),                                          $dec!(0.88888888888888888888888888888888888889))]
        #[case($dec!(5),                                           $dec!(11),                                         $dec!(0.45454545454545454545454545454545454545))]
        #[case($dec!(5),                                           $dec!(14),                                         $dec!(0.35714285714285714285714285714285714286))]
        #[case($dec!(5),                                           $dec!(18),                                         $dec!(0.277777777777777777777777777777777777778))]
        #[case($dec!(7),                                           $dec!(11),                                         $dec!(0.63636363636363636363636363636363636364))]
        #[case($dec!(25),                                          $dec!(39),                                         $dec!(0.64102564102564102564102564102564102564))]
        #[case($dec!(36),                                          $dec!(55),                                         $dec!(0.65454545454545454545454545454545454545))]
        #[case($dec!(222),                                         $dec!(1111),                                       $dec!(0.199819981998199819981998199819981998200))]
        #[case($dec!(73),                                          $dec!(72),                                         $dec!(1.01388888888888888888888888888888888889))]
        #[case($dec!(79),                                          $dec!(12345),                                      $dec!(0.0063993519643580396921830700688537869583))]
        #[case($dec!(99),                                          $dec!(98),                                         $dec!(1.01020408163265306122448979591836734694))]
        #[case($dec!(999),                                         $dec!(998),                                        $dec!(1.00100200400801603206412825651302605210))]
        #[case($dec!(2048),                                        $dec!(1025),                                       $dec!(1.99804878048780487804878048780487804878))]
        #[case($dec!(1),                                           $dec!(2.71828182845904523536028747135266249775),   $dec!(0.36787944117144232159552377016146086745))]
        #[case($dec!(0.3),                                         $dec!(340282366920938463463374607431768211455),    $dec!(8.8162076311671563097655240291668425837e-40))]
        #[case($dec!(0.3),                                         $dec!(34028236692093846346337460743176821159),     $dec!(8.8162076311671563097655240291668425802e-39))]
        #[case($dec!(3195385192916917),                            $dec!(3195385192946695),                           $dec!(0.99999999999068093572389012671961829523))]
        #[case($dec!(1393723067526993),                            $dec!(1393723067519475),                           $dec!(1.00000000000539418495338561815691036848))]
        #[case($dec!(1.2345678),                                   $dec!(1.9876543),                                  $dec!(0.62111796804907171231939075119853588222))]
        #[case($dec!(340282366920938463463374607431768211455),     $dec!(9.99),                                       $dec!(34062298991084931277615075818995816962))]
        #[case($dec!(68056473384187692692674921486353642291),      $dec!(11),                                         $dec!(6186952125835244790243174680577603844.6))]
        #[case($dec!(690564733841876926926749214863536423),        $dec!(340282366920938463463374607431768211455),    $dec!(0.00202938735877055718769921841343055614221))]
        #[case($dec!(340282366920938463463374607431768211455),     $dec!(340282366920938463463374607431768211454),    $dec!(1.00000000000000000000000000000000000000))]
        #[case($dec!(20000),                                       $dec!(9),                                          $dec!(2222.22222222222222222222222222222222222))]
        #[case($dec!(18446744073709551614),                        $dec!(18446744073709551615),                       $dec!(0.99999999999999999994578989137572477830))]
        #[case($dec!(18446744073709551613),                        $dec!(18446744073709551615),                       $dec!(0.99999999999999999989157978275144955659))]
        #[case($dec!(18446744073709551612),                        $dec!(18446744073709551615),                       $dec!(0.99999999999999999983736967412717433489))]
        #[case($dec!(18446744073709551613),                        $dec!(18446744073709551614),                       $dec!(0.99999999999999999994578989137572477829))]
        #[case($dec!(2000000000000000000),                         $dec!(9),                                          $dec!(222222222222222222.222222222222222222222))]
        #[case($dec!(436696),                                      $dec!(9),                                          $dec!(48521.777777777777777777777777777777778))]
        #[case($dec!(1175000),                                     $dec!(11),                                         $dec!(106818.181818181818181818181818181818182))]
        #[case($dec!(436696),                                      $dec!(15),                                         $dec!(29113.0666666666666666666666666666666667))]
        #[case($dec!(3195385192916917),                            $dec!(3195385192946695),                           $dec!(0.99999999999068093572389012671961829523))]
        #[case($dec!(1393723067526993),                            $dec!(1393723067519475),                           $dec!(1.00000000000539418495338561815691036848))]
        #[case($dec!(1),                                           $dec!(2.718281828459045235),                       $dec!(0.36787944117144232164428337714357642784))]
        #[case($dec!(18446744073709551615),                        $dec!(18446744073709551614),                       $dec!(1.00000000000000000005421010862427522171))]
        #[case($dec!(18446744073709551615),                        $dec!(18446744073709551613),                       $dec!(1.00000000000000000010842021724855044342))]
        #[case($dec!(18446744073709551615),                        $dec!(18446744073709551515),                       $dec!(1.00000000000000000542101086242752219972))]
        #[case($dec!(1),                                           $dec!(4611686018427387904),                        $dec!(2.16840434497100886801490560173988342285e-19))]
        #[case($dec!(1),                                           $dec!(18446744073709551615),                       $dec!(0.54210108624275221703311375920552804341e-19))]
        #[case($dec!(1),                                           $dec!(4611686018427387904),                        $dec!(2.16840434497100886801490560173988342285e-19))]
        #[case($dec!(20),                                          $dec!(9),                                          $dec!(2.22222222222222222222222222222222222222))]
        #[case($dec!(20000000000000000000),                        $dec!(9),                                          $dec!(2222222222222222222.22222222222222222222))]
        #[case($dec!(1),                                           $dec!(3),                                          $dec!(0.333333333333333333333333333333333333333))]
        #[case($dec!(2),                                           $dec!(3),                                          $dec!(0.66666666666666666666666666666666666667))]
        #[case($dec!(1),                                           $dec!(9),                                          $dec!(0.111111111111111111111111111111111111111))]
        #[case($dec!(3195385192916917),                            $dec!(3195385192946695),                           $dec!(0.99999999999068093572389012671961829523))]
        #[case($dec!(1393723067526993),                            $dec!(1393723067519475),                           $dec!(1.00000000000539418495338561815691036848))]
        #[case($dec!(1.2345678),                                   $dec!(1.9876543),                                  $dec!(0.62111796804907171231939075119853588222))]
        #[case($dec!(1),                                           $dec!(2.71828182845904523536028747135266249775),   $dec!(0.36787944117144232159552377016146086745))]
        #[case($dec!(340282366920938463463374607431768211454),     $dec!(340282366920938463463374607431768211455),    $dec!(1.00000000000000000000000000000000000000))]
        #[case($dec!(0.70710678118654752440084436210484903932),    $dec!(0.70710678118654752440084436210484903925),   $dec!(1.00000000000000000000000000000000000010))]
        #[case($dec!(1000),                                        $dec!(330.189681705037027119772492465920151004),   $dec!(3.02856223379298000000000000000000000000))]
        fn test_div_128(
            #[case] a: $D,
            #[case] b: $D,
            #[case] expected: $D,
        ) {
            let d = a / b;

            assert_eq!(d, expected);
            assert_eq!(d.fractional_digits_count(), expected.fractional_digits_count());
            assert!(d.is_op_inexact());
            assert!(d.is_op_rounded());
        }

        #[rstest(::trace)]
        #[case($dec!(1),                   $dec!(3),                  $dec!(0.333333333333333333333333333333333333333), HalfUp)]
        #[case($dec!(1),                   $dec!(3),                  $dec!(0.333333333333333333333333333333333333333), Down)]
        #[case($dec!(1),                   $dec!(3),                  $dec!(0.333333333333333333333333333333333333334), Up)]
        #[case($dec!(1),                   $dec!(9),                  $dec!(0.111111111111111111111111111111111111111), HalfUp)]
        #[case($dec!(1),                   $dec!(9),                  $dec!(0.111111111111111111111111111111111111111), Down)]
        #[case($dec!(1),                   $dec!(9),                  $dec!(0.111111111111111111111111111111111111112), Up)]
        #[case($dec!(1),                   $dec!(9.09),               $dec!(0.110011001100110011001100110011001100110), Down)]
        #[case($dec!(1),                   $dec!(9.09),               $dec!(0.110011001100110011001100110011001100110), HalfUp)]
        #[case($dec!(1),                   $dec!(9.09),               $dec!(0.110011001100110011001100110011001100110), Up)]
        #[case($dec!(1),                   $dec!(9.009),              $dec!(0.111000111000111000111000111000111000111), Down)]
        #[case($dec!(1),                   $dec!(9.009),              $dec!(0.111000111000111000111000111000111000111), HalfUp)]
        #[case($dec!(1),                   $dec!(9.009),              $dec!(0.111000111000111000111000111000111000111), Up)]
        #[case($dec!(1),                   $dec!(7),                  $dec!(0.142857142857142857142857142857142857142), Down)]
        #[case($dec!(1),                   $dec!(7),                  $dec!(0.142857142857142857142857142857142857143), HalfUp)]
        #[case($dec!(1),                   $dec!(7),                  $dec!(0.142857142857142857142857142857142857143), Up)]
        #[case($dec!(1.2345678),           $dec!(1.9876543),          $dec!(0.62111796804907171231939075119853588222), Down)]
        #[case($dec!(1.2345678),           $dec!(1.9876543),          $dec!(0.62111796804907171231939075119853588222), HalfUp)]
        #[case($dec!(1.2345678),           $dec!(1.9876543),          $dec!(0.62111796804907171231939075119853588222), Up)]
        fn test_div_round_128(
            #[case] a: $D,
            #[case] b: $D,
            #[case] expected: $D,
            #[case] mode: RoundingMode,
        ) {
            let ctx = Context::default().with_rounding_mode(mode);
            let d = a.with_ctx(ctx) / b.with_ctx(ctx);

            assert_eq!(d, expected);
            assert_eq!(d.fractional_digits_count(), expected.fractional_digits_count());
            assert!(d.is_op_inexact());
            assert!(d.is_op_rounded());
        }
    };
    (COMMON:: 128, $dec: ident, $D: ident) => {
        super::test_impl!(COMMON:: 64, $dec, $D);

        #[rstest(::trace)]
        #[case($dec!(500549251119075878721813), $dec!(209481029831),  $dec!(2389472934723))]
        #[case($dec!(500549251119075878721813), $dec!(2389472934723), $dec!(209481029831))]
        fn test_div_exact_128(
            #[case] a: $D,
            #[case] b: $D,
            #[case] expected: $D,
        ) {
            let d = a / b;

            assert_eq!(d, expected);
            assert_eq!(d.fractional_digits_count(), expected.fractional_digits_count());
            assert!(d.is_op_ok());
        }

    };
    (UNSIGNED:: 128, $dec: ident, $D: ident, THIS) => {
        super::test_impl!(UNSIGNED:: 128, $dec, $D);
    };
    (UNSIGNED:: 128, $dec: ident, $D: ident) => {
        super::test_impl!(UNSIGNED:: 64, $dec, $D);
    };
    (SIGNED:: 128, $dec: ident, $D: ident, THIS) => {
        super::test_impl!(SIGNED:: 128, $dec, $D);
    };
    (SIGNED:: 128, $dec: ident, $D: ident) => {
        super::test_impl!(SIGNED:: 64, $dec, $D);
    };

    (COMMON:: 64, $dec: ident, $D: ident, THIS) => {
        super::test_impl!(COMMON:: 64, $dec, $D);

        #[rstest(::trace)]
        #[case($dec!(1),                       $dec!(3),                      $dec!(0.3333333333333333333))]
        #[case($dec!(1),                       $dec!(7),                      $dec!(0.14285714285714285714))]
        #[case($dec!(1),                       $dec!(9),                      $dec!(0.11111111111111111111))]
        #[case($dec!(1),                       $dec!(9.9),                    $dec!(0.10101010101010101010))]
        #[case($dec!(1),                       $dec!(9.09),                   $dec!(0.11001100110011001100))]
        #[case($dec!(1),                       $dec!(9.009),                  $dec!(0.11100011100011100011))]
        #[case($dec!(1),                       $dec!(99999),                  $dec!(0.000010000100001000010000))]
        #[case($dec!(1),                       $dec!(999999),                 $dec!(0.0000010000010000010000010))]
        #[case($dec!(1),                       $dec!(73),                     $dec!(0.013698630136986301370))]
        #[case($dec!(1),                       $dec!(2.718281828459045235),   $dec!(0.3678794411714423216))]
        #[case($dec!(2),                       $dec!(3),                      $dec!(0.6666666666666666667))]
        #[case($dec!(8),                       $dec!(9),                      $dec!(0.8888888888888888889))]
        #[case($dec!(5),                       $dec!(11),                     $dec!(0.4545454545454545455))]
        #[case($dec!(5),                       $dec!(14),                     $dec!(0.3571428571428571429))]
        #[case($dec!(5),                       $dec!(18),                     $dec!(0.2777777777777777778))]
        #[case($dec!(7),                       $dec!(11),                     $dec!(0.6363636363636363636))]
        #[case($dec!(25),                      $dec!(39),                     $dec!(0.6410256410256410256))]
        #[case($dec!(36),                      $dec!(55),                     $dec!(0.6545454545454545455))]
        #[case($dec!(222),                     $dec!(1111),                   $dec!(0.1998199819981998200))]
        #[case($dec!(73),                      $dec!(72),                     $dec!(1.0138888888888888889))]
        #[case($dec!(79),                      $dec!(12345),                  $dec!(0.006399351964358039692))]
        #[case($dec!(99),                      $dec!(98),                     $dec!(1.0102040816326530612))]
        #[case($dec!(999),                     $dec!(998),                    $dec!(1.0010020040080160321))]
        #[case($dec!(2048),                    $dec!(1025),                   $dec!(1.998048780487804878))]
        #[case($dec!(0.3),                     $dec!(3402823669209384634),    $dec!(8.816207631167156311e-20))]
        #[case($dec!(0.3),                     $dec!(340282366920938463),     $dec!(8.816207631167156322e-19))]
        #[case($dec!(3195385192916917),        $dec!(3195385192946695),       $dec!(0.9999999999906809357))]
        #[case($dec!(1393723067526993),        $dec!(1393723067519475),       $dec!(1.0000000000053941850))]
        #[case($dec!(1.2345678),               $dec!(1.9876543),              $dec!(0.6211179680490717123))]
        #[case($dec!(1),                       $dec!(4611686018427387904),    $dec!(2.168404344971008868e-19))]
        #[case($dec!(20000),                   $dec!(9),                      $dec!(2222.222222222222222))]
        #[case($dec!(1),                       $dec!(18446744073709551615),   $dec!(0.5421010862427522170e-19))]
        #[case($dec!(18446744073709551614),    $dec!(18446744073709551615),   $dec!(0.9999999999999999999))]
        #[case($dec!(18446744073709551613),    $dec!(18446744073709551615),   $dec!(0.9999999999999999999))]
        #[case($dec!(18446744073709551612),    $dec!(18446744073709551615),   $dec!(0.9999999999999999998))]
        #[case($dec!(18446744073709551613),    $dec!(18446744073709551614),   $dec!(0.9999999999999999999))]
        #[case($dec!(2000000000000000000),     $dec!(9),                      $dec!(222222222222222222.2))]
        #[case($dec!(436696),                  $dec!(9),                      $dec!(48521.77777777777778))]
        #[case($dec!(1175000),                 $dec!(11),                     $dec!(106818.18181818181818))]
        #[case($dec!(436696),                  $dec!(15),                     $dec!(29113.06666666666667))]
        #[case($dec!(3195385192916917),        $dec!(3195385192946695),       $dec!(0.9999999999906809357))]
        #[case($dec!(1393723067526993),        $dec!(1393723067519475),       $dec!(1.0000000000053941850))]
        #[case($dec!(18446744073709551615),    $dec!(18446744073709551614),   $dec!(1.0000000000000000001))]
        #[case($dec!(18446744073709551615),    $dec!(18446744073709551613),   $dec!(1.0000000000000000001))]
        #[case($dec!(18446744073709551615),    $dec!(18446744073709551515),   $dec!(1.0000000000000000054))]
        fn test_div_64(#[case] a: $D, #[case] b: $D, #[case] expected: $D) {
            let d = a / b;
            assert_eq!(d, expected);
            assert_eq!(d.fractional_digits_count(), expected.fractional_digits_count());
            assert!(d.is_op_inexact());
            assert!(d.is_op_rounded());
        }

        #[rstest(::trace)]
        #[case($dec!(1),   $dec!(3),    $dec!(0.3333333333333333333), Down)]
        #[case($dec!(1),   $dec!(3),    $dec!(0.3333333333333333333), HalfUp)]
        #[case($dec!(1),   $dec!(3),    $dec!(0.3333333333333333334), Up)]
        fn test_div_round_64(
            #[case] a: $D,
            #[case] b: $D,
            #[case] expected: $D,
            #[case] mode: RoundingMode,
        ) {
            let ctx = Context::default().with_rounding_mode(mode);
            let d = a.with_ctx(ctx) / b.with_ctx(ctx);

            assert_eq!(d, expected);
            assert_eq!(d.fractional_digits_count(), expected.fractional_digits_count());
            assert!(d.is_op_inexact());
            assert!(d.is_op_rounded());
        }
    };
    (COMMON:: 64, $dec: ident, $D: ident) => {
        #[rstest(::trace)]
        #[case($dec!(0), $dec!(1), $dec!(0))]
        #[case($dec!(0), $dec!(10), $dec!(0))]
        #[case($dec!(2), $dec!(1), $dec!(2))]
        #[case($dec!(2e1), $dec!(1), $dec!(2e1))]
        #[case($dec!(10), $dec!(10), $dec!(1))]
        #[case($dec!(100), $dec!(10.0), $dec!(1e1))]
        #[case($dec!(20.0), $dec!(200), $dec!(0.1))]
        #[case($dec!(4.0), $dec!(2), $dec!(2.0))]
        #[case($dec!(15.0), $dec!(3), $dec!(5.0))]
        #[case($dec!(1), $dec!(2), $dec!(0.5))]
        #[case($dec!(1.0), $dec!(2), $dec!(0.5))]
        #[case($dec!(1.00), $dec!(2), $dec!(0.50))]
        #[case($dec!(1.000), $dec!(2), $dec!(0.500))]
        #[case($dec!(1.0000), $dec!(2), $dec!(0.5000))]
        #[case($dec!(1.00000), $dec!(2), $dec!(0.50000))]
        #[case($dec!(1.000000), $dec!(2), $dec!(0.500000))]
        #[case($dec!(1.0000000), $dec!(2), $dec!(0.5000000))]
        #[case($dec!(2.00), $dec!(1.00), $dec!(2))]
        #[case($dec!(1), $dec!(4), $dec!(0.25))]
        #[case($dec!(1), $dec!(8), $dec!(0.125))]
        #[case($dec!(2), $dec!(16), $dec!(0.125))]
        #[case($dec!(1), $dec!(25), $dec!(0.04))]
        #[case($dec!(1), $dec!(32), $dec!(0.03125))]
        #[case($dec!(1), $dec!(64), $dec!(0.015625))]
        #[case($dec!(1), $dec!(1024), $dec!(0.0009765625))]
        #[case($dec!(1), $dec!(2e-2), $dec!(5e1))]
        #[case($dec!(1), $dec!(0.2), $dec!(5))]
        #[case($dec!(1.0), $dec!(0.02), $dec!(5e1))]
        #[case($dec!(1), $dec!(0.020), $dec!(5e1))]
        #[case($dec!(5.0), $dec!(4.00), $dec!(1.25))]
        #[case($dec!(5.0), $dec!(4.000), $dec!(1.25))]
        #[case($dec!(5), $dec!(4.000), $dec!(1.25))]
        #[case($dec!(5), $dec!(4), $dec!(125e-2))]
        #[case($dec!(100), $dec!(5), $dec!(20))]
        #[case($dec!(240), $dec!(1000), $dec!(0.24))]
        #[case($dec!(3e0), $dec!(2e0), $dec!(1.5))]
        #[case($dec!(30e-1), $dec!(2e0), $dec!(1.5))]
        #[case($dec!(300e-2), $dec!(2e0), $dec!(1.50))]
        #[case($dec!(3000e-3), $dec!(2e0), $dec!(1.500))]
        #[case($dec!(3e0), $dec!(20e-1), $dec!(1.5))]
        #[case($dec!(30e-1), $dec!(20e-1), $dec!(1.5))]
        #[case($dec!(300e-2), $dec!(20e-1), $dec!(1.5))]
        #[case($dec!(3000e-3), $dec!(20e-1), $dec!(1.50))]
        #[case($dec!(3e0), $dec!(200e-2), $dec!(1.5))]
        #[case($dec!(30e-1), $dec!(200e-2), $dec!(1.5))]
        #[case($dec!(300e-2), $dec!(200e-2), $dec!(1.5))]
        #[case($dec!(3000e-3), $dec!(200e-2), $dec!(1.5))]
        #[case($dec!(3e0), $dec!(2000e-3), $dec!(1.5))]
        #[case($dec!(30e-1), $dec!(2000e-3), $dec!(1.5))]
        #[case($dec!(300e-2), $dec!(2000e-3), $dec!(1.5))]
        #[case($dec!(3000e-3), $dec!(2000e-3), $dec!(1.5))]
        #[case($dec!(2.4), $dec!(1), $dec!(2.4))]
        #[case($dec!(2.40), $dec!(1), $dec!(2.40))]
        #[case($dec!(2.400), $dec!(1), $dec!(2.400))]
        #[case($dec!(2.4), $dec!(2), $dec!(1.2))]
        #[case($dec!(2.400), $dec!(2), $dec!(1.200))]
        #[case($dec!(2.), $dec!(2), $dec!(1))]
        #[case($dec!(20), $dec!(20), $dec!(1))]
        #[case($dec!(15.22756), $dec!(1.234), $dec!(12.34))]
        #[case($dec!(15.22756), $dec!(12.34), $dec!(1.234))]
        #[case($dec!(187), $dec!(187), $dec!(1))]
        #[case($dec!(5), $dec!(2), $dec!(2.5))]
        #[case($dec!(50), $dec!(20), $dec!(2.5))]
        #[case($dec!(500), $dec!(200), $dec!(2.5))]
        #[case($dec!(50.0), $dec!(20.0), $dec!(2.5))]
        #[case($dec!(5.00), $dec!(2.00), $dec!(2.5))]
        #[case($dec!(5), $dec!(2.0), $dec!(2.5))]
        #[case($dec!(5), $dec!(20), $dec!(0.25))]
        #[case($dec!(5), $dec!(2.000), $dec!(2.5))]
        #[case($dec!(5), $dec!(0.20), $dec!(25))]
        #[case($dec!(5), $dec!(0.200), $dec!(25))]
        #[case($dec!(10), $dec!(1), $dec!(10))]
        #[case($dec!(100), $dec!(1), $dec!(100))]
        #[case($dec!(1000), $dec!(1), $dec!(1000))]
        #[case($dec!(1000), $dec!(100), $dec!(10))]
        #[case($dec!(0.5625), $dec!(2), $dec!(0.28125))]
        #[case($D::MAX, $D::MAX, $dec!(1))]
        fn test_div(#[case] a: $D, #[case] b: $D, #[case] expected: $D) {
            let d = a / b;

            assert_eq!(d, expected);
            assert_eq!(d.fractional_digits_count(), expected.fractional_digits_count());
            assert!(d.is_op_ok());

            let mut a = a;

            a /= b;
            assert_eq!(a, expected);
            assert_eq!(a.fractional_digits_count(), expected.fractional_digits_count());
            assert!(a.is_op_ok());
        }

        #[rstest(::trace)]
        #[case($dec!(1e-2),    $dec!(1e32765),    $dec!(1e-32767),       signals![])]
        #[case($dec!(1.23e-2), $dec!(1e32763),    $dec!(1.23e-32765),    signals![!SN])]
        #[case($dec!(1e-2),    $dec!(1e32767),    $D::ZERO,              signals![!INEXACT, !ROUND, !SN, !UFW])]
        #[case($dec!(1e5),     $dec!(1e-32765),   $dec!(100e32768),      signals![!CP, !ROUND])]
        fn test_div_signals(
            #[case] a: $D,
            #[case] b: $D,
            #[case] expected: $D,
            #[case] signals: Signals
        ) {
            let d = a / b;

            assert_eq!(d, expected);
            assert_eq!(d.fractional_digits_count(), expected.fractional_digits_count());
            assert_eq!(d.op_signals(), signals);
        }

        #[rstest(::trace)]
        #[case($dec!(0), $dec!(0))]
        #[case($D::MAX, $dec!(0))]
        #[case($D::MAX, $D::ZERO)]
        #[should_panic(expected = "(fastnum) division by zero")]
        fn test_div_zero_panic(#[case] a: $D, #[case] b: $D) {
            let _ = a / b;
        }

        #[rstest(::trace)]
        #[case($dec!(1e-32767), $D::MAX)]
        #[should_panic(expected = "(fastnum) underflow was occurred while performing arithmetic operation")]
        fn test_div_underflow_panic(#[case] a: $D, #[case] b: $D) {
            let ctx = Context::default().with_signal_traps(SignalsTraps::default().set(Signals::OP_UNDERFLOW));
            let _ = a.with_ctx(ctx) / b.with_ctx(ctx);
        }

        #[rstest(::trace)]
        #[case($D::MAX, $dec!(1e-32767))]
        #[should_panic(expected = "(fastnum) overflow was occurred while performing arithmetic operation")]
        fn test_div_overflow_panic(#[case] a: $D, #[case] b: $D) {
            let _ = a / b;
        }

        #[rstest(::trace)]
        #[case($D::NAN, $dec!(1))]
        #[case($dec!(1), $D::NAN)]
        #[case($D::NAN, $D::NAN)]
        #[should_panic(expected = "(fastnum) invalid operation")]
        fn test_div_nan_panic(#[case] a: $D, #[case] b: $D) {
            let _ = a / b;
        }
    };
    (UNSIGNED:: 64, $dec: ident, $D: ident, THIS) => {
        super::test_impl!(UNSIGNED:: 64, $dec, $D);
    };
    (UNSIGNED:: 64, $dec: ident, $D: ident) => {

    };
    (SIGNED:: 64, $dec: ident, $D: ident, THIS) => {
        super::test_impl!(SIGNED:: 64, $dec, $D);
    };
    (SIGNED:: 64, $dec: ident, $D: ident) => {
        #[rstest(::trace)]
        #[case($D::MIN, $dec!(1), $D::MIN)]
        #[case($D::MIN, $D::MIN, $dec!(1))]
        #[case($dec!(-50), $dec!(5), $dec!(-10))]
        #[case($dec!(200), $dec!(-5), $dec!(-40.))]
        #[case($dec!(-2.4), $dec!(1), $dec!(-2.4))]
        #[case($dec!(-2.4), $dec!(-1), $dec!(2.4))]
        #[case($dec!(2.4), $dec!(-1), $dec!(-2.4))]
        #[case($dec!(1), $dec!(-2), $dec!(-0.5))]
        #[case($dec!(1), $dec!(-4), $dec!(-0.25))]
        #[case($dec!(1), $dec!(-8), $dec!(-0.125))]
        #[case($dec!(1), $dec!(-16), $dec!(-0.0625))]
        #[case($dec!(1), $dec!(-32), $dec!(-0.03125))]
        #[case($dec!(1), $dec!(-64), $dec!(-0.015625))]
        #[case($dec!(-1), $dec!(2), $dec!(-0.5))]
        #[case($dec!(-1), $dec!(4), $dec!(-0.25))]
        #[case($dec!(-1), $dec!(8), $dec!(-0.125))]
        #[case($dec!(-1), $dec!(16), $dec!(-0.0625))]
        #[case($dec!(-1), $dec!(32), $dec!(-0.03125))]
        #[case($dec!(-1), $dec!(64), $dec!(-0.015625))]
        #[case($dec!(-1), $dec!(-2), $dec!(0.5))]
        #[case($dec!(-1), $dec!(-4), $dec!(0.25))]
        #[case($dec!(-1), $dec!(-8), $dec!(0.125))]
        #[case($dec!(-1), $dec!(-16), $dec!(0.0625))]
        #[case($dec!(-1), $dec!(-32), $dec!(0.03125))]
        #[case($dec!(-1), $dec!(-64), $dec!(0.015625))]
        fn test_div_signed(#[case] a: $D, #[case] b: $D, #[case] expected: $D) {
            let d = a / b;

            assert_eq!(d, expected);
            assert_eq!(d.fractional_digits_count(), expected.fractional_digits_count());
            assert!(d.is_op_ok());

            let mut a = a;

            a /= b;
            assert_eq!(a, expected);
            assert_eq!(a.fractional_digits_count(), expected.fractional_digits_count());
            assert!(a.is_op_ok());
        }

        #[rstest(::trace)]
        #[case($dec!(0), $dec!(-0))]
        #[case($dec!(-0), $dec!(-0))]
        #[case($dec!(-0), $dec!(0))]
        #[should_panic(expected = "(fastnum) division by zero")]
        fn test_div_zero_panic_signed(#[case] a: $D, #[case] b: $D) {
            let _ = a / b;
        }
    };
}

pub(crate) use test_impl;