File Coverage

Decimal128.xs
Criterion Covered Total %
statement 853 1036 82.3
branch 674 1160 58.1
condition n/a
subroutine n/a
pod n/a
total 1527 2196 69.5


line stmt bran cond sub pod time code
1              
2             #ifdef __MINGW32__
3             #ifndef __USE_MINGW_ANSI_STDIO
4             #define __USE_MINGW_ANSI_STDIO 1
5             #endif
6             #endif
7              
8             #define PERL_NO_GET_CONTEXT 1
9              
10             #include "EXTERN.h"
11             #include "perl.h"
12             #include "XSUB.h"
13              
14              
15             #include
16              
17             #ifdef OLDPERL
18             #define SvUOK SvIsUV
19             #endif
20              
21             #ifndef Newx
22             # define Newx(v,n,t) New(0,v,n,t)
23             #endif
24              
25             /*************************************************************************************
26             In certain situations SvIVX and SvUVX cause crashes on mingw-w64 x64 builds.
27             Behaviour varies with different versions of perl, different versions of gcc
28             and different versions of mingw-runtime.
29             I've just taken a blanket approach - I don't think the minimal gain in
30             performance offered by SvIVX/SvUVX over SvIV/SvUV justifies going to much trouble.
31             Hence we define the following:
32             *************************************************************************************/
33             #ifdef __MINGW64__
34             #define M_D128_SvIV SvIV
35             #define M_D128_SvUV SvUV
36             #else
37             #define M_D128_SvIV SvIVX
38             #define M_D128_SvUV SvUVX
39             #endif
40              
41             #if (defined(DEBUGGING) && defined(NV_IS_DOUBLE)) || defined(__MINGW64__)
42             typedef _Decimal128 D128 __attribute__ ((aligned(8)));
43             #else
44             typedef _Decimal128 D128;
45             #endif
46              
47             int nnum = 0; /* flag that is incremented whenever _atodecimal is handed something non-numeric */
48              
49             D128 add_on[113] = {
50             1e0DL, 2e0DL, 4e0DL, 8e0DL, 16e0DL, 32e0DL, 64e0DL, 128e0DL, 256e0DL, 512e0DL, 1024e0DL,
51             2048e0DL, 4096e0DL, 8192e0DL, 16384e0DL, 32768e0DL, 65536e0DL, 131072e0DL, 262144e0DL,
52             524288e0DL, 1048576e0DL, 2097152e0DL, 4194304e0DL, 8388608e0DL, 16777216e0DL, 33554432e0DL,
53             67108864e0DL, 134217728e0DL, 268435456e0DL, 536870912e0DL, 1073741824e0DL, 2147483648e0DL,
54             4294967296e0DL, 8589934592e0DL, 17179869184e0DL, 34359738368e0DL, 68719476736e0DL,
55             137438953472e0DL, 274877906944e0DL, 549755813888e0DL, 1099511627776e0DL, 2199023255552e0DL,
56             4398046511104e0DL, 8796093022208e0DL, 17592186044416e0DL, 35184372088832e0DL,
57             70368744177664e0DL, 140737488355328e0DL, 281474976710656e0DL, 562949953421312e0DL,
58             1125899906842624e0DL, 2251799813685248e0DL, 4503599627370496e0DL, 9007199254740992e0DL,
59             18014398509481984e0DL, 36028797018963968e0DL, 72057594037927936e0DL, 144115188075855872e0DL,
60             288230376151711744e0DL, 576460752303423488e0DL, 1152921504606846976e0DL,
61             2305843009213693952e0DL, 4611686018427387904e0DL, 9223372036854775808e0DL,
62             18446744073709551616e0DL, 36893488147419103232e0DL, 73786976294838206464e0DL,
63             147573952589676412928e0DL, 295147905179352825856e0DL, 590295810358705651712e0DL,
64             1180591620717411303424e0DL, 2361183241434822606848e0DL, 4722366482869645213696e0DL,
65             9444732965739290427392e0DL, 18889465931478580854784e0DL, 37778931862957161709568e0DL,
66             75557863725914323419136e0DL, 151115727451828646838272e0DL, 302231454903657293676544e0DL,
67             604462909807314587353088e0DL, 1208925819614629174706176e0DL, 2417851639229258349412352e0DL,
68             4835703278458516698824704e0DL, 9671406556917033397649408e0DL, 19342813113834066795298816e0DL,
69             38685626227668133590597632e0DL, 77371252455336267181195264e0DL,
70             154742504910672534362390528e0DL, 309485009821345068724781056e0DL,
71             618970019642690137449562112e0DL, 1237940039285380274899124224e0DL,
72             2475880078570760549798248448e0DL, 4951760157141521099596496896e0DL,
73             9903520314283042199192993792e0DL, 19807040628566084398385987584e0DL,
74             39614081257132168796771975168e0DL, 79228162514264337593543950336e0DL,
75             158456325028528675187087900672e0DL, 316912650057057350374175801344e0DL,
76             633825300114114700748351602688e0DL, 1267650600228229401496703205376e0DL,
77             2535301200456458802993406410752e0DL, 5070602400912917605986812821504e0DL,
78             10141204801825835211973625643008e0DL, 20282409603651670423947251286016e0DL,
79             40564819207303340847894502572032e0DL, 81129638414606681695789005144064e0DL,
80             162259276829213363391578010288128e0DL, 324518553658426726783156020576256e0DL,
81             649037107316853453566312041152512e0DL, 1298074214633706907132624082305024e0DL,
82             2596148429267413814265248164610048e0DL, 5192296858534827628530496329220096e0DL };
83              
84 49565           int _is_nan(D128 x) {
85 49565 100         if(x == x) return 0;
86 38           return 1;
87             }
88              
89 49574           int _is_inf(D128 x) {
90 49574 50         if(x != x) return 0; /* NaN */
91 49574 100         if(x == 0.DL) return 0; /* Zero */
92 49197 100         if(x/x != x/x) {
93 76 100         if(x < 0.DL) return -1;
94 42           else return 1;
95             }
96 49121           return 0; /* Finite Real */
97             }
98              
99             /* Replaced */
100             /*
101             //int _is_neg_zero(D128 x) {
102             // char * buffer;
103             //
104             // if(x != 0.DL) return 0;
105             //
106             // Newx(buffer, 2, char);
107             // sprintf(buffer, "%.0f", (double)x);
108             //
109             // if(strcmp(buffer, "-0")) {
110             // Safefree(buffer);
111             // return 0;
112             // }
113             //
114             // Safefree(buffer);
115             // return 1;
116             //}
117             */
118              
119 227636           int _is_neg_zero(D128 d128) {
120              
121 227636           int n = sizeof(D128);
122 227636           void * p = &d128;
123              
124             /*****************************************************
125             We perform the following oddness because of gcc's
126             buggy optimization of signed zero _Decimal128.
127             See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80692
128             ******************************************************/
129 227636 100         if(d128 != 0.0DL) {
130 226352 50         if(d128 * -1.0DL == 0.0DL) return 1; /* it's a -0 */
131 226352           return 0; /* it's not zero */
132             }
133              
134             #ifdef WE_HAVE_BENDIAN /* Big Endian architecture */
135             if(((unsigned char*)p)[0] >= 128) return 1;
136             #else
137 1284 100         if(((unsigned char*)p)[n - 1] >= 128) return 1;
138             #endif
139 564           return 0;
140             }
141              
142 0           SV * _is_nan_NV(pTHX_ SV * x) {
143 0 0         if(SvNV(x) == SvNV(x)) return newSViv(0);
    0          
    0          
144 0           return newSViv(1);
145             }
146              
147 0           SV * _is_inf_NV(pTHX_ SV * x) {
148 0 0         if(SvNV(x) != SvNV(x)) return 0; /* NaN */
    0          
    0          
149 0 0         if(SvNV(x) == 0.0) return newSViv(0); /* Zero */
    0          
150 0 0         if(SvNV(x)/SvNV(x) != SvNV(x)/SvNV(x)) {
    0          
    0          
    0          
    0          
151 0 0         if(SvNV(x) < 0.0) return newSViv(-1);
    0          
152 0           else return newSViv(1);
153             }
154 0           return newSVnv(0); /* Finite Real */
155             }
156              
157 0           SV * _is_neg_zero_NV(pTHX_ SV * x) {
158             char buffer[3];
159              
160 0 0         if(SvNV(x) != 0.0) return newSViv(0);
    0          
161              
162 0 0         sprintf(buffer, "%.0f", (double)SvNV(x));
163              
164 0 0         if(strcmp(buffer, "-0")) {
165 0           return newSViv(0);
166             }
167              
168 0           return newSViv(1);
169             }
170              
171 47154           D128 _exp10 (int power) {
172              
173 47154           D128 ret = 1.DL;
174              
175 47154 100         if(power < 0) {
176 22554 50         while(power < -1000) {
177 0           ret *= 1e-1000DL;
178 0           power += 1000;
179             }
180 84800 100         while(power < -100) {
181 62246           ret *= 1e-100DL;
182 62246           power += 100;
183             }
184 209300 100         while(power < -10) {
185 186746           ret *= 1e-10DL;
186 186746           power += 10;
187             }
188 197855 100         while(power) {
189 175301           ret *= 1e-1DL;
190 175301           power++;
191             }
192             }
193             else {
194 24600 50         while(power > 1000) {
195 0           ret *= 1e1000DL;
196 0           power -= 1000;
197             }
198 86829 100         while(power > 100) {
199 62229           ret *= 1e100DL;
200 62229           power -= 100;
201             }
202 191963 100         while(power > 10) {
203 167363           ret *= 1e10DL;
204 167363           power -= 10;
205             }
206 125976 100         while(power) {
207 101376           ret *= 1e1DL;
208 101376           power--;
209             }
210             }
211 47154           return ret;
212             }
213              
214 89           D128 _get_inf(int sign) {
215 89 100         if(sign < 0) return -1.DL/0.DL;
216 72           return 1.DL/0.DL;
217             }
218              
219 46           D128 _get_nan(void) {
220 46           D128 inf = _get_inf(1);
221 46           return inf/inf;
222             }
223              
224 48986           D128 _atodecimal(pTHX_ char * s) {
225             /*
226             plagiarising code available at
227             https://www.ibm.com/developerworks/community/wikis/home?lang=en_US#!/wiki/Power%20Systems/page/POWER6%20Decimal%20Floating%20Point%20(DFP)
228             The aim is that nnum be incremented iff looks_like_number() would return false for the given string
229             */
230              
231 48986           D128 top = 0.DL, bot = 0.DL, result = 0.DL, div = 10.DL;
232 48986           int negative = 0, i = 0, exponent = 0, count = 0;
233              
234 48986 100         if(!strcmp(s, "0 but true")) return 0.DL;
235              
236 49030 100         while(s[0] == ' ' || s[0] == '\t' || s[0] == '\n' || s[0] == '\r' || s[0] == '\f') s++;
    100          
    100          
    100          
    100          
237              
238 48985 100         if(s[0] == '-') {
239 24456           negative = -1;
240 24456           s++;
241             }
242             else {
243 24529 100         if(s[0] == '+') s++;
244             }
245              
246 48985 100         if((s[0] == 'i' || s[0] == 'I') && (s[1] == 'n' || s[1] == 'N') && (s[2] == 'f' || s[2] == 'F')) {
    100          
    50          
    0          
    50          
    0          
247 21 100         if((s[3] == 'i' || s[3] == 'I') && (s[4] == 'n' || s[4] == 'N') && (s[5] == 'i' || s[5] == 'I') &&
    50          
    50          
    0          
    50          
    0          
    100          
248 3 50         (s[6] == 't' || s[6] == 'T') && (s[7] == 'y' || s[7] == 'Y')) count = 5;
    100          
    50          
249 21           for(i = 3 + count;;i++) {
250 25 100         if(s[i] == 0) return _get_inf(negative);
251 8 100         if(s[i] != ' ' && s[i] != '\t' && s[i] != '\n' && s[i] != '\r' && s[i] != '\f') {
    50          
    50          
    50          
    50          
252 4           nnum++;
253 4 50         if(SvIV(get_sv("Math::Decimal128::NNW", 0)))
    50          
254 0           warn("string argument contains at least one non-numeric character");
255 4           return _get_inf(negative);
256             }
257 4           }
258             }
259              
260 48964 100         if((s[0] == 'n' || s[0] == 'N') && (s[1] == 'a' || s[1] == 'A') && (s[2] == 'n' || s[2] == 'N')) {
    50          
    50          
    0          
    50          
    0          
261 14           for(i = 3;;i++) {
262 14 50         if(s[i] == 0) return _get_nan();
263 0 0         if(s[i] != ' ' && s[i] != '\t' && s[i] != '\n' && s[i] != '\r' && s[i] != '\f') {
    0          
    0          
    0          
    0          
264 0           nnum++;
265 0 0         if(SvIV(get_sv("Math::Decimal128::NNW", 0)))
    0          
266 0           warn("string argument contains at least one non-numeric character");
267 0           return _get_nan();
268             }
269 0           }
270             }
271              
272             /* Must be a digit or a decimal point */
273 48950 100         if(!isdigit(s[0]) && s[0] != '.') {
    100          
274 7           nnum++;
275 7 50         if(SvIV(get_sv("Math::Decimal128::NNW", 0)))
    50          
276 0           warn("string argument contains at least one non-numeric character");
277 7 100         result = negative ? result * -1.DL : result;
278 7           return result;
279             }
280              
281 654098 100         for(; isdigit(*s); s++) {
282 605155           top = top * 10.DL;
283 605155           top = top + *s - '0';
284             }
285              
286 48943 100         if(s[0] == '.') {
287 24721           s++;
288 239130 100         for(i = 0; isdigit(s[i]) ;i++) {
289 214409           bot += (D128)(s[i] - '0') / (D128)div;
290 214409           div *= 10.DL;
291             }
292             }
293              
294 48943           result = top + bot;
295 48943 100         if(negative) result *= -1.DL;
296              
297 48943 100         if(s[i] == 'e' || s[i] == 'E') {
    100          
298 47154           s += i + 1;
299 47154 100         if(*s == '-') {
300 22554           s++;
301 107484 100         for(i = 0; isdigit(s[i]);i++) exponent = (exponent * 10) + (s[i] - '0');
302 119849347 100         while(exponent > 398) {
303 119826793           result /= 10.DL;
304 119826793           exponent--;
305             }
306 22554           result *= _exp10(-exponent);
307              
308             /* Check for non-numeric trailing characters, and increment nnum */
309             /* (and return immediately) if we hit one */
310 0           for(;;i++) {
311 22554 100         if(s[i] == 0) return result;
312 1 50         if(s[i] != ' ' && s[i] != '\t' && s[i] != '\n' && s[i] != '\r' && s[i] != '\f') {
    50          
    50          
    50          
    50          
313 1           nnum++;
314 1 50         if(SvIV(get_sv("Math::Decimal128::NNW", 0)))
    50          
315 0           warn("string argument contains at least one non-numeric character");
316 1           return result;
317             }
318 0           }
319             }
320              
321 24600 100         if(*s == '+') s++;
322 112696 100         for(i = 0; isdigit(s[i]);i++) exponent = (exponent * 10) + (s[i] - '0');
323 120296457 100         while(exponent > 384) {
324 120271857           result *= 10.DL;
325 120271857           exponent--;
326             }
327 24600           result *= _exp10(exponent);
328              
329              
330             /* Check for non-numeric trailing characters, and increment nnum */
331             /* (and return immediately) if we hit one */
332 1           for(;;i++) {
333 24601 100         if(s[i] == 0) return result;
334 4 100         if(s[i] != ' ' && s[i] != '\t' && s[i] != '\n' && s[i] != '\r' && s[i] != '\f') {
    50          
    50          
    50          
    50          
335 3           nnum++;
336 3 50         if(SvIV(get_sv("Math::Decimal128::NNW", 0)))
    50          
337 0           warn("string argument contains at least one non-numeric character");
338 3           return result;
339             }
340 1           }
341             }
342              
343             /* Check for non-numeric trailing characters, and increment nnum */
344             /* (and return immediately) if we hit one */
345 3           for(;;i++) {
346 1792 100         if(s[i] == 0) return result;
347 10 100         if(s[i] != ' ' && s[i] != '\t' && s[i] != '\n' && s[i] != '\r' && s[i] != '\f') {
    50          
    50          
    50          
    50          
348 7           nnum++;
349 7 50         if(SvIV(get_sv("Math::Decimal128::NNW", 0)))
    50          
350 0           warn("string argument contains at least one non-numeric character");
351 7           return result;
352             }
353 3           }
354             }
355              
356 8           SV * _DEC128_MAX(pTHX) {
357             D128 * d128;
358             SV * obj_ref, * obj;
359              
360 8           Newx(d128, 1, D128);
361 8 50         if(d128 == NULL) croak("Failed to allocate memory in DEC128_MAX() function");
362              
363 8           obj_ref = newSV(0);
364 8           obj = newSVrv(obj_ref, "Math::Decimal128");
365              
366 8           *d128 = 9999999999999999999999999999999999e6111DL;
367              
368              
369 8           sv_setiv(obj, INT2PTR(IV,d128));
370 8           SvREADONLY_on(obj);
371 8           return obj_ref;
372             }
373              
374 9           SV * _DEC128_MIN(pTHX) {
375             D128 * d128;
376             SV * obj_ref, * obj;
377              
378 9           Newx(d128, 1, D128);
379 9 50         if(d128 == NULL) croak("Failed to allocate memory in DEC128_MIN() function");
380              
381 9           obj_ref = newSV(0);
382 9           obj = newSVrv(obj_ref, "Math::Decimal128");
383              
384 9           *d128 = 1e-6176DL;
385              
386              
387 9           sv_setiv(obj, INT2PTR(IV,d128));
388 9           SvREADONLY_on(obj);
389 9           return obj_ref;
390             }
391              
392              
393 30           SV * NaND128(pTHX) {
394             D128 * d128;
395             SV * obj_ref, * obj;
396              
397 30           Newx(d128, 1, D128);
398 30 50         if(d128 == NULL) croak("Failed to allocate memory in NaND128 function");
399              
400 30           obj_ref = newSV(0);
401 30           obj = newSVrv(obj_ref, "Math::Decimal128");
402              
403 30           *d128 = _get_nan();
404              
405 30           sv_setiv(obj, INT2PTR(IV,d128));
406 30           SvREADONLY_on(obj);
407 30           return obj_ref;
408             }
409              
410 18           SV * InfD128(pTHX_ int sign) {
411             D128 * d128;
412             SV * obj_ref, * obj;
413              
414 18           Newx(d128, 1, D128);
415 18 50         if(d128 == NULL) croak("Failed to allocate memory in InfD128 function");
416              
417 18           obj_ref = newSV(0);
418 18           obj = newSVrv(obj_ref, "Math::Decimal128");
419              
420 18           *d128 = _get_inf(sign);
421              
422 18           sv_setiv(obj, INT2PTR(IV,d128));
423 18           SvREADONLY_on(obj);
424 18           return obj_ref;
425             }
426              
427 47722           SV * ZeroD128(pTHX_ int sign) {
428             D128 * d128;
429             SV * obj_ref, * obj;
430              
431 47722           Newx(d128, 1, D128);
432 47722 50         if(d128 == NULL) croak("Failed to allocate memory in ZeroD128 function");
433              
434 47722           obj_ref = newSV(0);
435 47722           obj = newSVrv(obj_ref, "Math::Decimal128");
436              
437 47722           *d128 = 0.DL;
438 47722 100         if(sign < 0) *d128 *= -1;
439              
440 47722           sv_setiv(obj, INT2PTR(IV,d128));
441 47722           SvREADONLY_on(obj);
442 47722           return obj_ref;
443             }
444              
445 2429           SV * UnityD128(pTHX_ int sign) {
446             D128 * d128;
447             SV * obj_ref, * obj;
448              
449 2429           Newx(d128, 1, D128);
450 2429 50         if(d128 == NULL) croak("Failed to allocate memory in UnityD128 function");
451              
452 2429           obj_ref = newSV(0);
453 2429           obj = newSVrv(obj_ref, "Math::Decimal128");
454              
455 2429           *d128 = 1.DL;
456             /* *d128 = (D128)strtold("1e0", NULL); */
457 2429 100         if(sign < 0) *d128 *= -1;
458              
459 2429           sv_setiv(obj, INT2PTR(IV,d128));
460 2429           SvREADONLY_on(obj);
461 2429           return obj_ref;
462             }
463              
464 4868           SV * Exp10l(pTHX_ int power) {
465             D128 * d128;
466             SV * obj_ref, * obj;
467              
468             /* Remove the following condition, and allow 0/(+-inf to be returned
469             when the power goes outside the range.
470             if(power < -6176 || power > 6144)
471             croak("Argument supplied to Exp10 function (%d) is out of allowable range", power);
472             */
473              
474 4868           Newx(d128, 1, D128);
475 4868 50         if(d128 == NULL) croak("Failed to allocate memory in Exp10() function");
476              
477 4868           obj_ref = newSV(0);
478 4868           obj = newSVrv(obj_ref, "Math::Decimal128");
479              
480 4868           *d128 = 1.DL;
481 4868 100         if(power < 0) {
482 4252 100         while(power < -1000) {
483 2448           *d128 *= 1e-1000DL;
484 2448           power += 1000;
485             }
486 4317 100         while(power < -100) {
487 2513           *d128 *= 1e-100DL;
488 2513           power += 100;
489             }
490 13152 100         while(power < -10) {
491 11348           *d128 *= 1e-10DL;
492 11348           power += 10;
493             }
494 11669 100         while(power) {
495 9865           *d128 *= 1e-1DL;
496 9865           power++;
497             }
498             }
499             else {
500 5320 100         while(power > 1000) {
501 2256           *d128 *= 1e1000DL;
502 2256           power -= 1000;
503             }
504 5586 100         while(power > 100) {
505 2522           *d128 *= 1e100DL;
506 2522           power -= 100;
507             }
508 17205 100         while(power > 10) {
509 14141           *d128 *= 1e10DL;
510 14141           power -= 10;
511             }
512 16988 100         while(power) {
513 13924           *d128 *= 1e1DL;
514 13924           power--;
515             }
516             }
517              
518 4868           sv_setiv(obj, INT2PTR(IV,d128));
519 4868           SvREADONLY_on(obj);
520 4868           return obj_ref;
521             }
522              
523 0           SV * _testvalD128_1(pTHX_ int sign) {
524             D128 * d128;
525             SV * obj_ref, * obj;
526              
527 0           Newx(d128, 1, D128);
528 0 0         if(d128 == NULL) croak("Failed to allocate memory in _testvalD128() function");
529              
530 0           obj_ref = newSV(0);
531 0           obj = newSVrv(obj_ref, "Math::Decimal128");
532              
533 0           *d128 = 93071992547409938307199254740993e0DL;
534              
535 0 0         if(sign < 0) *d128 *= -1;
536              
537 0           sv_setiv(obj, INT2PTR(IV,d128));
538 0           SvREADONLY_on(obj);
539 0           return obj_ref;
540             }
541              
542              
543 2           SV * _testvalD128_2(pTHX_ int sign) {
544             D128 * d128;
545             SV * obj_ref, * obj;
546              
547 2           Newx(d128, 1, D128);
548 2 50         if(d128 == NULL) croak("Failed to allocate memory in _testvalD128() function");
549              
550 2           obj_ref = newSV(0);
551 2           obj = newSVrv(obj_ref, "Math::Decimal128");
552              
553 2           *d128 = 2547409938307199254740993e0DL;
554              
555 2 100         if(sign < 0) *d128 *= -1;
556              
557 2           sv_setiv(obj, INT2PTR(IV,d128));
558 2           SvREADONLY_on(obj);
559 2           return obj_ref;
560             }
561              
562 0           SV * _testvalD128_3(pTHX_ int sign) {
563             D128 * d128;
564             SV * obj_ref, * obj;
565              
566 0           Newx(d128, 1, D128);
567 0 0         if(d128 == NULL) croak("Failed to allocate memory in _testvalD128() function");
568              
569 0           obj_ref = newSV(0);
570 0           obj = newSVrv(obj_ref, "Math::Decimal128");
571              
572 0           *d128 = 9938307199254740993e0DL;
573              
574 0 0         if(sign < 0) *d128 *= -1;
575              
576 0           sv_setiv(obj, INT2PTR(IV,d128));
577 0           SvREADONLY_on(obj);
578 0           return obj_ref;
579             }
580              
581 0           SV * _testvalD128_4(pTHX_ int sign) {
582             D128 * d128;
583             SV * obj_ref, * obj;
584              
585 0           Newx(d128, 1, D128);
586 0 0         if(d128 == NULL) croak("Failed to allocate memory in _testvalD128() function");
587              
588 0           obj_ref = newSV(0);
589 0           obj = newSVrv(obj_ref, "Math::Decimal128");
590              
591 0           *d128 = 4740993e0DL;
592              
593 0 0         if(sign < 0) *d128 *= -1;
594              
595 0           sv_setiv(obj, INT2PTR(IV,d128));
596 0           SvREADONLY_on(obj);
597 0           return obj_ref;
598             }
599              
600 373638           SV * _MEtoD128(pTHX_ char * msd, char * nsd, char * lsd, SV * exponent) {
601              
602             D128 * d128;
603             SV * obj_ref, * obj;
604 373638 50         int exp = (int)SvIV(exponent), i;
605             long double m;
606              
607 373638           Newx(d128, 1, D128);
608 373638 50         if(d128 == NULL) croak("Failed to allocate memory in MEtoD128() function");
609              
610 373638           obj_ref = newSV(0);
611 373638           obj = newSVrv(obj_ref, "Math::Decimal128");
612              
613 373638           m = strtold(msd, NULL);
614 373638           *d128 = (D128)m * 1e24DL;
615              
616 373638           m = strtold(nsd, NULL);
617 373638           *d128 += (D128)m * 1e12DL;
618              
619 373638           m = strtold(lsd, NULL);
620 373638           *d128 += (D128)m;
621              
622 373638 100         if(exp < 0) {
623 167942262 100         for(i = 0; i > exp; --i) *d128 *= 1e-1DL;
624             }
625             else {
626 164155700 100         for(i = 0; i < exp; ++i) *d128 *= 10.DL;
627             }
628              
629 373638           sv_setiv(obj, INT2PTR(IV,d128));
630 373638           SvREADONLY_on(obj);
631 373638           return obj_ref;
632             }
633              
634 11           void _assignME(pTHX_ SV * a, char * msd, char * nsd, char * lsd, SV * c) {
635             long double man;
636 11 50         int exp = (int)SvIV(c), i;
637             D128 all;
638              
639 11           man = strtold(msd, NULL);
640 11           all = (D128)man * 1e24DL;
641              
642 11           man = strtold(nsd, NULL);
643 11           all += (D128)man * 1e12DL;
644              
645 11           man = strtold(lsd, NULL);
646 11           all += (D128)man;
647              
648 11           *(INT2PTR(D128 *, M_D128_SvIV(SvRV(a)))) = all;
649              
650 11 100         if(exp < 0) {
651 15 100         for(i = 0; i > exp; --i) *(INT2PTR(D128 *, M_D128_SvIV(SvRV(a)))) *= 1e-1DL;
652             }
653             else {
654 14807 100         for(i = 0; i < exp; ++i) *(INT2PTR(D128 *, M_D128_SvIV(SvRV(a)))) *= 10.DL;
655             }
656 11           }
657              
658 65           SV * NVtoD128(pTHX_ SV * x) {
659              
660             D128 * d128;
661             SV * obj_ref, * obj;
662              
663 65           Newx(d128, 1, D128);
664 65 50         if(d128 == NULL) croak("Failed to allocate memory in NVtoD128 function");
665              
666 65           obj_ref = newSV(0);
667 65           obj = newSVrv(obj_ref, "Math::Decimal128");
668              
669 65 100         *d128 = (D128)SvNV(x);
670              
671 65           sv_setiv(obj, INT2PTR(IV,d128));
672 65           SvREADONLY_on(obj);
673 65           return obj_ref;
674             }
675              
676 17           SV * UVtoD128(pTHX_ SV * x) {
677              
678             D128 * d128;
679             SV * obj_ref, * obj;
680              
681 17           Newx(d128, 1, D128);
682 17 50         if(d128 == NULL) croak("Failed to allocate memory in UVtoD128 function");
683              
684 17           obj_ref = newSV(0);
685 17           obj = newSVrv(obj_ref, "Math::Decimal128");
686              
687 17 100         *d128 = (D128)SvUV(x);
688              
689 17           sv_setiv(obj, INT2PTR(IV,d128));
690 17           SvREADONLY_on(obj);
691 17           return obj_ref;
692             }
693              
694 18           SV * IVtoD128(pTHX_ SV * x) {
695              
696             D128 * d128;
697             SV * obj_ref, * obj;
698              
699 18           Newx(d128, 1, D128);
700 18 50         if(d128 == NULL) croak("Failed to allocate memory in IVtoD128 function");
701              
702 18           obj_ref = newSV(0);
703 18           obj = newSVrv(obj_ref, "Math::Decimal128");
704              
705 18 50         *d128 = (D128)SvIV(x);
706              
707 18           sv_setiv(obj, INT2PTR(IV,d128));
708 18           SvREADONLY_on(obj);
709 18           return obj_ref;
710             }
711              
712 23800           SV * PVtoD128(pTHX_ char * x) {
713             D128 * d128;
714             SV * obj_ref, * obj;
715              
716 23800           Newx(d128, 1, D128);
717 23800 50         if(d128 == NULL) croak("Failed to allocate memory in PVtoD128 function");
718              
719 23800           obj_ref = newSV(0);
720 23800           obj = newSVrv(obj_ref, "Math::Decimal128");
721              
722 23800           *d128 = _atodecimal(aTHX_ x);
723              
724 23800           sv_setiv(obj, INT2PTR(IV,d128));
725 23800           SvREADONLY_on(obj);
726 23800           return obj_ref;
727             }
728              
729 0           SV * STRtoD128(pTHX_ char * x) {
730             #ifdef STRTOD128_AVAILABLE
731             D128 * d128;
732             char * ptr;
733             SV * obj_ref, * obj;
734              
735             Newx(d128, 1, D128);
736             if(d128 == NULL) croak("Failed to allocate memory in STRtoD128 function");
737              
738             *d128 = strtod128(x, &ptr);
739              
740             obj_ref = newSV(0);
741             obj = newSVrv(obj_ref, "Math::Decimal128");
742              
743             sv_setiv(obj, INT2PTR(IV,d128));
744             SvREADONLY_on(obj);
745             return obj_ref;
746             #else
747 0           croak("The strtod128() function has not been made available");
748             #endif
749             }
750              
751 74           int have_strtod128(void) {
752             #ifdef STRTOD128_AVAILABLE
753             return 1;
754             #else
755 74           return 0;
756             #endif
757             }
758              
759 3           SV * D128toNV(pTHX_ SV * d128) {
760 3           return newSVnv((NV)(*(INT2PTR(D128*, M_D128_SvIV(SvRV(d128))))));
761             }
762              
763 828554           void DESTROY(pTHX_ SV * rop) {
764 828554           Safefree(INT2PTR(D128 *, M_D128_SvIV(SvRV(rop))));
765 828554           }
766              
767 2           void assignIVl(pTHX_ SV * a, SV * val) {
768              
769 2 50         if(sv_isobject(a)) {
770 2 50         const char * h = HvNAME(SvSTASH(SvRV(a)));
    50          
    50          
    0          
    50          
    50          
771 2 50         if(strEQ(h, "Math::Decimal128")) {
772 2 50         *(INT2PTR(D128 *, M_D128_SvIV(SvRV(a)))) = (D128)SvIV(val);
773             }
774 2           else croak("Invalid object supplied to Math::Decimal128::assignIVl function");
775             }
776 0           else croak("Invalid argument supplied to Math::Decimal128::assignIVl function");
777              
778 2           }
779              
780 1           void assignUVl(pTHX_ SV * a, SV * val) {
781              
782 1 50         if(sv_isobject(a)) {
783 1 50         const char * h = HvNAME(SvSTASH(SvRV(a)));
    50          
    50          
    0          
    50          
    50          
784 1 50         if(strEQ(h, "Math::Decimal128")) {
785 1 50         *(INT2PTR(D128 *, M_D128_SvIV(SvRV(a)))) = (D128)SvUV(val);
786             }
787 1           else croak("Invalid object supplied to Math::Decimal128::assignUVl function");
788             }
789 0           else croak("Invalid argument supplied to Math::Decimal128::assignUVl function");
790              
791 1           }
792              
793 2           void assignNVl(pTHX_ SV * a, SV * val) {
794              
795 2 50         if(sv_isobject(a)) {
796 2 50         const char * h = HvNAME(SvSTASH(SvRV(a)));
    50          
    50          
    0          
    50          
    50          
797 2 50         if(strEQ(h, "Math::Decimal128")) {
798 2 50         *(INT2PTR(D128 *, M_D128_SvIV(SvRV(a)))) = (D128)SvNV(val);
799             }
800 2           else croak("Invalid object supplied to Math::Decimal128::assignNVl function");
801             }
802 0           else croak("Invalid argument supplied to Math::Decimal128::assignNVl function");
803              
804 2           }
805              
806 25101           void assignPVl(pTHX_ SV * a, char * s) {
807 25101           *(INT2PTR(D128 *, M_D128_SvIV(SvRV(a)))) = _atodecimal(aTHX_ s);
808 25101           }
809              
810 1           void assignD128(pTHX_ SV * a, SV * val) {
811              
812 2 50         if(sv_isobject(a) && sv_isobject(val)) {
    50          
813 1 50         const char * h = HvNAME(SvSTASH(SvRV(a)));
    50          
    50          
    0          
    50          
    50          
814 1 50         const char * hh = HvNAME(SvSTASH(SvRV(val)));
    50          
    50          
    0          
    50          
    50          
815 1 50         if(strEQ(h, "Math::Decimal128") && strEQ(hh, "Math::Decimal128")) {
    50          
816 1           *(INT2PTR(D128 *, M_D128_SvIV(SvRV(a)))) = *(INT2PTR(D128 *, M_D128_SvIV(SvRV(val))));
817             }
818 0           else croak("Invalid object supplied to Math::Decimal128::assignD128 function");
819             }
820 0           else croak("Invalid argument supplied to Math::Decimal128::assignD128 function");
821              
822 1           }
823              
824 2           void assignNaNl(pTHX_ SV * a) {
825              
826 2 50         if(sv_isobject(a)) {
827 2 50         const char * h = HvNAME(SvSTASH(SvRV(a)));
    50          
    50          
    0          
    50          
    50          
828 2 50         if(strEQ(h, "Math::Decimal128")) {
829 2           *(INT2PTR(D128 *, M_D128_SvIV(SvRV(a)))) = _get_nan();
830             }
831 2           else croak("Invalid object supplied to Math::Decimal128::assignNaN function");
832             }
833 0           else croak("Invalid argument supplied to Math::Decimal128::assignNaN function");
834 2           }
835              
836 4           void assignInfl(pTHX_ SV * a, int sign) {
837              
838 4 50         if(sv_isobject(a)) {
839 4 50         const char * h = HvNAME(SvSTASH(SvRV(a)));
    50          
    50          
    0          
    50          
    50          
840 4 50         if(strEQ(h, "Math::Decimal128")) {
841 4           *(INT2PTR(D128 *, M_D128_SvIV(SvRV(a)))) = _get_inf(sign);
842             }
843 4           else croak("Invalid object supplied to Math::Decimal128::assignInf function");
844             }
845 0           else croak("Invalid argument supplied to Math::Decimal128::assignInf function");
846 4           }
847              
848 41           SV * _overload_add(pTHX_ SV * a, SV * b, SV * third) {
849              
850             D128 * d128;
851             SV * obj_ref, * obj;
852              
853 41           Newx(d128, 1, D128);
854 41 50         if(d128 == NULL) croak("Failed to allocate memory in _overload_add function");
855              
856 41           obj_ref = newSV(0);
857 41           obj = newSVrv(obj_ref, "Math::Decimal128");
858              
859 41           sv_setiv(obj, INT2PTR(IV,d128));
860 41           SvREADONLY_on(obj);
861              
862 41 50         if(SvUOK(b)) {
863 0           *d128 = *(INT2PTR(D128 *, M_D128_SvIV(SvRV(a)))) + (D128)M_D128_SvUV(b);
864 0           return obj_ref;
865             }
866              
867 41 100         if(SvIOK(b)) {
868 3           *d128 = *(INT2PTR(D128 *, M_D128_SvIV(SvRV(a)))) + (D128)M_D128_SvIV(b);
869 3           return obj_ref;
870             }
871              
872 38 100         if(SvPOK(b) && !SvNOK(b)) {
    50          
873 17 50         *d128 = *(INT2PTR(D128 *, M_D128_SvIV(SvRV(a)))) + _atodecimal(aTHX_ SvPV_nolen(b));
874 17           return obj_ref;
875             }
876              
877 21 50         if(sv_isobject(b)) {
878 21 50         const char *h = HvNAME(SvSTASH(SvRV(b)));
    50          
    50          
    0          
    50          
    50          
879 21 50         if(strEQ(h, "Math::Decimal128")) {
880 21           *d128 = *(INT2PTR(D128 *, M_D128_SvIV(SvRV(a)))) + *(INT2PTR(D128 *, M_D128_SvIV(SvRV(b))));
881 21           return obj_ref;
882             }
883 0           croak("Invalid object supplied to Math::Decimal128::_overload_add function");
884             }
885 0           croak("Invalid argument supplied to Math::Decimal128::_overload_add function");
886             }
887              
888 2502           SV * _overload_mul(pTHX_ SV * a, SV * b, SV * third) {
889              
890             D128 * d128;
891             SV * obj_ref, * obj;
892              
893 2502           Newx(d128, 1, D128);
894 2502 50         if(d128 == NULL) croak("Failed to allocate memory in _overload_mul function");
895              
896 2502           obj_ref = newSV(0);
897 2502           obj = newSVrv(obj_ref, "Math::Decimal128");
898              
899 2502           sv_setiv(obj, INT2PTR(IV,d128));
900 2502           SvREADONLY_on(obj);
901              
902 2502 100         if(SvUOK(b)) {
903 3           *d128 = *(INT2PTR(D128 *, M_D128_SvIV(SvRV(a)))) * (D128)M_D128_SvUV(b);
904 3           return obj_ref;
905             }
906              
907 2499 100         if(SvIOK(b)) {
908 65           *d128 = *(INT2PTR(D128 *, M_D128_SvIV(SvRV(a)))) * (D128)M_D128_SvIV(b);
909 65           return obj_ref;
910             }
911              
912 2434 100         if(SvPOK(b) && !SvNOK(b)) {
    50          
913 1 50         *d128 = *(INT2PTR(D128 *, M_D128_SvIV(SvRV(a)))) * _atodecimal(aTHX_ SvPV_nolen(b));
914 1           return obj_ref;
915             }
916              
917 2433 50         if(sv_isobject(b)) {
918 2433 50         const char *h = HvNAME(SvSTASH(SvRV(b)));
    50          
    50          
    0          
    50          
    50          
919 2433 50         if(strEQ(h, "Math::Decimal128")) {
920 2433           *d128 = *(INT2PTR(D128 *, M_D128_SvIV(SvRV(a)))) * *(INT2PTR(D128 *, M_D128_SvIV(SvRV(b))));
921 2433           return obj_ref;
922             }
923 0           croak("Invalid object supplied to Math::Decimal128::_overload_mul function");
924             }
925 0           croak("Invalid argument supplied to Math::Decimal128::_overload_mul function");
926             }
927              
928 34           SV * _overload_sub(pTHX_ SV * a, SV * b, SV * third) {
929              
930             D128 * d128;
931             SV * obj_ref, * obj;
932              
933 34           Newx(d128, 1, D128);
934 34 50         if(d128 == NULL) croak("Failed to allocate memory in _overload_sub function");
935              
936 34           obj_ref = newSV(0);
937 34           obj = newSVrv(obj_ref, "Math::Decimal128");
938              
939 34           sv_setiv(obj, INT2PTR(IV,d128));
940 34           SvREADONLY_on(obj);
941              
942 34 50         if(SvUOK(b)) {
943 0 0         if(third == &PL_sv_yes) *d128 = (D128)M_D128_SvUV(b) - *(INT2PTR(D128 *, M_D128_SvIV(SvRV(a))));
944 0           else *d128 = *(INT2PTR(D128 *, M_D128_SvIV(SvRV(a)))) - (D128)M_D128_SvUV(b);
945 0           return obj_ref;
946             }
947              
948 34 100         if(SvIOK(b)) {
949 4 100         if(third == &PL_sv_yes) *d128 = (D128)M_D128_SvIV(b) - *(INT2PTR(D128 *, M_D128_SvIV(SvRV(a))));
950 3           else *d128 = *(INT2PTR(D128 *, M_D128_SvIV(SvRV(a)))) - (D128)M_D128_SvIV(b);
951 4           return obj_ref;
952             }
953              
954 30 100         if(SvPOK(b) && !SvNOK(b)) {
    50          
955 14 50         if(third == &PL_sv_yes) *d128 = _atodecimal(aTHX_ SvPV_nolen(b)) - *(INT2PTR(D128 *, M_D128_SvIV(SvRV(a))));
    0          
956 14 50         else *d128 = *(INT2PTR(D128 *, M_D128_SvIV(SvRV(a)))) - _atodecimal(aTHX_ SvPV_nolen(b));
957 14           return obj_ref;
958             }
959              
960 16 50         if(sv_isobject(b)) {
961 16 50         const char *h = HvNAME(SvSTASH(SvRV(b)));
    50          
    50          
    0          
    50          
    50          
962 16 50         if(strEQ(h, "Math::Decimal128")) {
963 16           *d128 = *(INT2PTR(D128 *, M_D128_SvIV(SvRV(a)))) - *(INT2PTR(D128 *, M_D128_SvIV(SvRV(b))));
964 16           return obj_ref;
965             }
966 0           croak("Invalid object supplied to Math::Decimal128::_overload_sub function");
967             }
968             /* replaced by _overload_neg
969             if(third == &PL_sv_yes) {
970             *d128 = *(INT2PTR(D128 *, M_D128_SvIV(SvRV(a)))) * -1.DL;
971             return obj_ref;
972             }
973             */
974 0           croak("Invalid argument supplied to Math::Decimal128::_overload_sub function");
975             }
976              
977 4           SV * _overload_neg(pTHX_ SV * a, SV * b, SV * third) {
978              
979             D128 * d128;
980             SV * obj_ref, * obj;
981              
982 4           Newx(d128, 1, D128);
983 4 50         if(d128 == NULL) croak("Failed to allocate memory in _overload_sub function");
984              
985 4           obj_ref = newSV(0);
986 4           obj = newSVrv(obj_ref, "Math::Decimal128");
987              
988 4           sv_setiv(obj, INT2PTR(IV,d128));
989 4           SvREADONLY_on(obj);
990              
991 4           *d128 = *(INT2PTR(D128 *, M_D128_SvIV(SvRV(a)))) * -1.DL;
992 4           return obj_ref;
993             }
994              
995 28           SV * _overload_div(pTHX_ SV * a, SV * b, SV * third) {
996              
997             D128 * d128;
998             SV * obj_ref, * obj;
999              
1000 28           Newx(d128, 1, D128);
1001 28 50         if(d128 == NULL) croak("Failed to allocate memory in _overload_div function");
1002              
1003 28           obj_ref = newSV(0);
1004 28           obj = newSVrv(obj_ref, "Math::Decimal128");
1005              
1006 28           sv_setiv(obj, INT2PTR(IV,d128));
1007 28           SvREADONLY_on(obj);
1008              
1009 28 50         if(SvUOK(b)) {
1010 0 0         if(third == &PL_sv_yes) *d128 = (D128)M_D128_SvUV(b) / *(INT2PTR(D128 *, M_D128_SvIV(SvRV(a))));
1011 0           else *d128 = *(INT2PTR(D128 *, M_D128_SvIV(SvRV(a)))) / (D128)M_D128_SvUV(b);
1012 0           return obj_ref;
1013             }
1014              
1015 28 100         if(SvIOK(b)) {
1016 1 50         if(third == &PL_sv_yes) *d128 = (D128)M_D128_SvIV(b) / *(INT2PTR(D128 *, M_D128_SvIV(SvRV(a))));
1017 0           else *d128 = *(INT2PTR(D128 *, M_D128_SvIV(SvRV(a)))) / (D128)M_D128_SvIV(b);
1018 1           return obj_ref;
1019             }
1020              
1021 27 100         if(SvPOK(b) && !SvNOK(b)) {
    50          
1022 1 50         if(third == &PL_sv_yes) *d128 = _atodecimal(aTHX_ SvPV_nolen(b)) / *(INT2PTR(D128 *, M_D128_SvIV(SvRV(a))));
    0          
1023 1 50         else *d128 = *(INT2PTR(D128 *, M_D128_SvIV(SvRV(a)))) / _atodecimal(aTHX_ SvPV_nolen(b));
1024 1           return obj_ref;
1025             }
1026              
1027 26 50         if(sv_isobject(b)) {
1028 26 50         const char *h = HvNAME(SvSTASH(SvRV(b)));
    50          
    50          
    0          
    50          
    50          
1029 26 50         if(strEQ(h, "Math::Decimal128")) {
1030 26           *d128 = *(INT2PTR(D128 *, M_D128_SvIV(SvRV(a)))) / *(INT2PTR(D128 *, M_D128_SvIV(SvRV(b))));
1031 26           return obj_ref;
1032             }
1033 0           croak("Invalid object supplied to Math::Decimal128::_overload_div function");
1034             }
1035 0           croak("Invalid argument supplied to Math::Decimal128::_overload_div function");
1036             }
1037              
1038 103           SV * _overload_add_eq(pTHX_ SV * a, SV * b, SV * third) {
1039              
1040 103           SvREFCNT_inc(a);
1041              
1042 103 50         if(SvUOK(b)) {
1043 0           *(INT2PTR(D128 *, M_D128_SvIV(SvRV(a)))) += (D128)M_D128_SvUV(b);
1044 0           return a;
1045             }
1046 103 100         if(SvIOK(b)) {
1047 1           *(INT2PTR(D128 *, M_D128_SvIV(SvRV(a)))) += (D128)M_D128_SvIV(b);
1048 1           return a;
1049             }
1050              
1051 102 100         if(SvPOK(b) && !SvNOK(b)) {
    50          
1052 1 50         *(INT2PTR(D128 *, M_D128_SvIV(SvRV(a)))) += _atodecimal(aTHX_ SvPV_nolen(b));
1053 1           return a;
1054             }
1055              
1056 101 50         if(sv_isobject(b)) {
1057 101 50         const char *h = HvNAME(SvSTASH(SvRV(b)));
    50          
    50          
    0          
    50          
    50          
1058 101 50         if(strEQ(h, "Math::Decimal128")) {
1059 101           *(INT2PTR(D128 *, M_D128_SvIV(SvRV(a)))) += *(INT2PTR(D128 *, M_D128_SvIV(SvRV(b))));
1060 101           return a;
1061             }
1062 0           SvREFCNT_dec(a);
1063 0           croak("Invalid object supplied to Math::Decimal128::_overload_add_eq function");
1064             }
1065 0           SvREFCNT_dec(a);
1066 0           croak("Invalid argument supplied to Math::Decimal128::_overload_add_eq function");
1067             }
1068              
1069 4878           SV * _overload_mul_eq(pTHX_ SV * a, SV * b, SV * third) {
1070              
1071 4878           SvREFCNT_inc(a);
1072              
1073 4878 50         if(SvUOK(b)) {
1074 0           *(INT2PTR(D128 *, M_D128_SvIV(SvRV(a)))) *= (D128)M_D128_SvUV(b);
1075 0           return a;
1076             }
1077 4878 100         if(SvIOK(b)) {
1078 7           *(INT2PTR(D128 *, M_D128_SvIV(SvRV(a)))) *= (D128)M_D128_SvIV(b);
1079 7           return a;
1080             }
1081              
1082 4871 100         if(SvPOK(b) && !SvNOK(b)) {
    50          
1083 1 50         *(INT2PTR(D128 *, M_D128_SvIV(SvRV(a)))) *= _atodecimal(aTHX_ SvPV_nolen(b));
1084 1           return a;
1085             }
1086              
1087 4870 50         if(sv_isobject(b)) {
1088 4870 50         const char *h = HvNAME(SvSTASH(SvRV(b)));
    50          
    50          
    0          
    50          
    50          
1089 4870 50         if(strEQ(h, "Math::Decimal128")) {
1090 4870           *(INT2PTR(D128 *, M_D128_SvIV(SvRV(a)))) *= *(INT2PTR(D128 *, M_D128_SvIV(SvRV(b))));
1091 4870           return a;
1092             }
1093 0           SvREFCNT_dec(a);
1094 0           croak("Invalid object supplied to Math::Decimal128::_overload_mul_eq function");
1095             }
1096 0           SvREFCNT_dec(a);
1097 0           croak("Invalid argument supplied to Math::Decimal128::_overload_mul_eq function");
1098             }
1099              
1100 7368192           SV * _overload_sub_eq(pTHX_ SV * a, SV * b, SV * third) {
1101              
1102 7368192           SvREFCNT_inc(a);
1103              
1104 7368192 50         if(SvUOK(b)) {
1105 0           *(INT2PTR(D128 *, M_D128_SvIV(SvRV(a)))) -= (D128)M_D128_SvUV(b);
1106 0           return a;
1107             }
1108 7368192 100         if(SvIOK(b)) {
1109 2           *(INT2PTR(D128 *, M_D128_SvIV(SvRV(a)))) -= (D128)M_D128_SvIV(b);
1110 2           return a;
1111             }
1112              
1113 7368190 100         if(SvPOK(b) && !SvNOK(b)) {
    50          
1114 1 50         *(INT2PTR(D128 *, M_D128_SvIV(SvRV(a)))) -= _atodecimal(aTHX_ SvPV_nolen(b));
1115 1           return a;
1116             }
1117              
1118 7368189 50         if(sv_isobject(b)) {
1119 7368189 50         const char *h = HvNAME(SvSTASH(SvRV(b)));
    50          
    50          
    0          
    50          
    50          
1120 7368189 50         if(strEQ(h, "Math::Decimal128")) {
1121 7368189           *(INT2PTR(D128 *, M_D128_SvIV(SvRV(a)))) -= *(INT2PTR(D128 *, M_D128_SvIV(SvRV(b))));
1122 7368189           return a;
1123             }
1124 0           SvREFCNT_dec(a);
1125 0           croak("Invalid object supplied to Math::Decimal128::_overload_sub_eq function");
1126             }
1127 0           SvREFCNT_dec(a);
1128 0           croak("Invalid argument supplied to Math::Decimal128::_overload_sub_eq function");
1129             }
1130              
1131 22           SV * _overload_div_eq(pTHX_ SV * a, SV * b, SV * third) {
1132              
1133 22           SvREFCNT_inc(a);
1134              
1135 22 50         if(SvUOK(b)) {
1136 0           *(INT2PTR(D128 *, M_D128_SvIV(SvRV(a)))) /= (D128)M_D128_SvUV(b);
1137 0           return a;
1138             }
1139 22 100         if(SvIOK(b)) {
1140 4           *(INT2PTR(D128 *, M_D128_SvIV(SvRV(a)))) /= (D128)M_D128_SvIV(b);
1141 4           return a;
1142             }
1143              
1144 18 100         if(SvPOK(b) && !SvNOK(b)) {
    50          
1145 1 50         *(INT2PTR(D128 *, M_D128_SvIV(SvRV(a)))) /= _atodecimal(aTHX_ SvPV_nolen(b));
1146 1           return a;
1147             }
1148              
1149 17 50         if(sv_isobject(b)) {
1150 17 50         const char *h = HvNAME(SvSTASH(SvRV(b)));
    50          
    50          
    0          
    50          
    50          
1151 17 50         if(strEQ(h, "Math::Decimal128")) {
1152 17           *(INT2PTR(D128 *, M_D128_SvIV(SvRV(a)))) /= *(INT2PTR(D128 *, M_D128_SvIV(SvRV(b))));
1153 17           return a;
1154             }
1155 0           SvREFCNT_dec(a);
1156 0           croak("Invalid object supplied to Math::Decimal128::_overload_div_eq function");
1157             }
1158 0           SvREFCNT_dec(a);
1159 0           croak("Invalid argument supplied to Math::Decimal128::_overload_div_eq function");
1160             }
1161              
1162 123           SV * _overload_equiv(pTHX_ SV * a, SV * b, SV * third) {
1163              
1164 123 100         if(SvUOK(b)) {
1165 1 50         if(*(INT2PTR(D128 *, M_D128_SvIV(SvRV(a)))) == (D128)M_D128_SvUV(b)) return newSViv(1);
1166 0           return newSViv(0);
1167             }
1168              
1169 122 100         if(SvIOK(b)) {
1170 4 50         if(*(INT2PTR(D128 *, M_D128_SvIV(SvRV(a)))) == (D128)M_D128_SvIV(b)) return newSViv(1);
1171 0           return newSViv(0);
1172             }
1173              
1174 118 100         if(SvPOK(b) && !SvNOK(b)) {
    50          
1175 9 50         if(*(INT2PTR(D128 *, M_D128_SvIV(SvRV(a)))) == _atodecimal(aTHX_ SvPV_nolen(b))) return newSViv(1);
    50          
1176 0           return newSViv(0);
1177             }
1178              
1179 109 100         if(sv_isobject(b)) {
1180 108 50         const char *h = HvNAME(SvSTASH(SvRV(b)));
    50          
    50          
    0          
    50          
    50          
1181 108 50         if(strEQ(h, "Math::Decimal128")) {
1182 108 100         if(*(INT2PTR(D128 *, M_D128_SvIV(SvRV(a)))) == *(INT2PTR(D128 *, M_D128_SvIV(SvRV(b))))) return newSViv(1);
1183 5           return newSViv(0);
1184             }
1185 0           croak("Invalid object supplied to Math::Decimal128::_overload_equiv function");
1186             }
1187 1           croak("Invalid argument supplied to Math::Decimal128::_overload_equiv function");
1188             }
1189              
1190 232103           SV * _overload_not_equiv(pTHX_ SV * a, SV * b, SV * third) {
1191              
1192 232103 100         if(SvUOK(b)) {
1193 1 50         if(*(INT2PTR(D128 *, M_D128_SvIV(SvRV(a)))) != (D128)M_D128_SvUV(b)) return newSViv(1);
1194 0           return newSViv(0);
1195             }
1196              
1197 232102 100         if(SvIOK(b)) {
1198 1 50         if(*(INT2PTR(D128 *, M_D128_SvIV(SvRV(a)))) != (D128)M_D128_SvIV(b)) return newSViv(1);
1199 0           return newSViv(0);
1200             }
1201              
1202 232101 100         if(SvPOK(b) && !SvNOK(b)) {
    50          
1203 3 50         if(*(INT2PTR(D128 *, M_D128_SvIV(SvRV(a)))) != _atodecimal(aTHX_ SvPV_nolen(b))) return newSViv(1);
    50          
1204 0           return newSViv(0);
1205             }
1206              
1207 232098 50         if(sv_isobject(b)) {
1208 232098 50         const char *h = HvNAME(SvSTASH(SvRV(b)));
    50          
    50          
    0          
    50          
    50          
1209 232098 50         if(strEQ(h, "Math::Decimal128")) {
1210 232098 100         if(*(INT2PTR(D128 *, M_D128_SvIV(SvRV(a)))) == *(INT2PTR(D128 *, M_D128_SvIV(SvRV(b))))) return newSViv(0);
1211 19           return newSViv(1);
1212             }
1213 0           croak("Invalid object supplied to Math::Decimal128::_overload_not_equiv function");
1214             }
1215 0           croak("Invalid argument supplied to Math::Decimal128::_overload_not_equiv function");
1216             }
1217              
1218 23875           SV * _overload_lt(pTHX_ SV * a, SV * b, SV * third) {
1219              
1220 23875 100         if(SvUOK(b)) {
1221 2 100         if(third == &PL_sv_yes) {
1222 1 50         if(*(INT2PTR(D128 *, M_D128_SvIV(SvRV(a)))) > (D128)M_D128_SvUV(b)) return newSViv(1);
1223 0           return newSViv(0);
1224             }
1225 1 50         if(*(INT2PTR(D128 *, M_D128_SvIV(SvRV(a)))) < (D128)M_D128_SvUV(b)) return newSViv(1);
1226 0           return newSViv(0);
1227             }
1228              
1229 23873 100         if(SvIOK(b)) {
1230 2 100         if(third == &PL_sv_yes) {
1231 1 50         if(*(INT2PTR(D128 *, M_D128_SvIV(SvRV(a)))) > (D128)M_D128_SvIV(b)) return newSViv(1);
1232 0           return newSViv(0);
1233             }
1234 1 50         if(*(INT2PTR(D128 *, M_D128_SvIV(SvRV(a)))) < (D128)M_D128_SvIV(b)) return newSViv(1);
1235 0           return newSViv(0);
1236             }
1237              
1238 23871 100         if(SvPOK(b) && !SvNOK(b)) {
    50          
1239 3 100         if(third == &PL_sv_yes) {
1240 1 50         if(*(INT2PTR(D128 *, M_D128_SvIV(SvRV(a)))) > _atodecimal(aTHX_ SvPV_nolen(b))) return newSViv(1);
    50          
1241 0           return newSViv(0);
1242             }
1243 2 50         if(*(INT2PTR(D128 *, M_D128_SvIV(SvRV(a)))) < _atodecimal(aTHX_ SvPV_nolen(b))) return newSViv(1);
    50          
1244 0           return newSViv(0);
1245             }
1246              
1247 23868 100         if(sv_isobject(b)) {
1248 23867 50         const char *h = HvNAME(SvSTASH(SvRV(b)));
    50          
    50          
    0          
    50          
    50          
1249 23867 50         if(strEQ(h, "Math::Decimal128")) {
1250 23867 100         if(*(INT2PTR(D128 *, M_D128_SvIV(SvRV(a)))) < *(INT2PTR(D128 *, M_D128_SvIV(SvRV(b))))) return newSViv(1);
1251 2           return newSViv(0);
1252             }
1253 0           croak("Invalid object supplied to Math::Decimal128::_overload_lt function");
1254             }
1255 1           croak("Invalid argument supplied to Math::Decimal128::_overload_lt function");
1256             }
1257              
1258 6444820           SV * _overload_gt(pTHX_ SV * a, SV * b, SV * third) {
1259              
1260 6444820 100         if(SvUOK(b)) {
1261 2 100         if(third == &PL_sv_yes) {
1262 1 50         if(*(INT2PTR(D128 *, M_D128_SvIV(SvRV(a)))) < (D128)M_D128_SvUV(b)) return newSViv(1);
1263 0           return newSViv(0);
1264             }
1265 1 50         if(*(INT2PTR(D128 *, M_D128_SvIV(SvRV(a)))) > (D128)M_D128_SvUV(b)) return newSViv(1);
1266 0           return newSViv(0);
1267             }
1268              
1269 6444818 100         if(SvIOK(b)) {
1270 6444804 100         if(third == &PL_sv_yes) {
1271 1 50         if(*(INT2PTR(D128 *, M_D128_SvIV(SvRV(a)))) < (D128)M_D128_SvIV(b)) return newSViv(1);
1272 0           return newSViv(0);
1273             }
1274 6444803 100         if(*(INT2PTR(D128 *, M_D128_SvIV(SvRV(a)))) > (D128)M_D128_SvIV(b)) return newSViv(1);
1275 2265457           return newSViv(0);
1276             }
1277              
1278 14 100         if(SvPOK(b) && !SvNOK(b)) {
    50          
1279 4 100         if(third == &PL_sv_yes) {
1280 1 50         if(*(INT2PTR(D128 *, M_D128_SvIV(SvRV(a)))) < _atodecimal(aTHX_ SvPV_nolen(b))) return newSViv(1);
    50          
1281 0           return newSViv(0);
1282             }
1283 3 50         if(*(INT2PTR(D128 *, M_D128_SvIV(SvRV(a)))) > _atodecimal(aTHX_ SvPV_nolen(b))) return newSViv(1);
    50          
1284 0           return newSViv(0);
1285             }
1286              
1287 10 100         if(sv_isobject(b)) {
1288 9 50         const char *h = HvNAME(SvSTASH(SvRV(b)));
    50          
    50          
    0          
    50          
    50          
1289 9 50         if(strEQ(h, "Math::Decimal128")) {
1290 9 100         if(*(INT2PTR(D128 *, M_D128_SvIV(SvRV(a)))) > *(INT2PTR(D128 *, M_D128_SvIV(SvRV(b))))) return newSViv(1);
1291 1           return newSViv(0);
1292             }
1293 0           croak("Invalid object supplied to Math::Decimal128::_overload_gt function");
1294             }
1295 1           croak("Invalid argument supplied to Math::Decimal128::_overload_gt function");
1296             }
1297              
1298 24           SV * _overload_lte(pTHX_ SV * a, SV * b, SV * third) {
1299              
1300 24 100         if(SvUOK(b)) {
1301 3 100         if(third == &PL_sv_yes) {
1302 2 50         if(*(INT2PTR(D128 *, M_D128_SvIV(SvRV(a)))) >= (D128)M_D128_SvUV(b)) return newSViv(1);
1303 0           return newSViv(0);
1304             }
1305 1 50         if(*(INT2PTR(D128 *, M_D128_SvIV(SvRV(a)))) <= (D128)M_D128_SvUV(b)) return newSViv(1);
1306 0           return newSViv(0);
1307             }
1308              
1309 21 100         if(SvIOK(b)) {
1310 3 100         if(third == &PL_sv_yes) {
1311 2 50         if(*(INT2PTR(D128 *, M_D128_SvIV(SvRV(a)))) >= (D128)M_D128_SvIV(b)) return newSViv(1);
1312 0           return newSViv(0);
1313             }
1314 1 50         if(*(INT2PTR(D128 *, M_D128_SvIV(SvRV(a)))) <= (D128)M_D128_SvIV(b)) return newSViv(1);
1315 0           return newSViv(0);
1316             }
1317              
1318 18 100         if(SvPOK(b) && !SvNOK(b)) {
    50          
1319 4 100         if(third == &PL_sv_yes) {
1320 2 50         if(*(INT2PTR(D128 *, M_D128_SvIV(SvRV(a)))) >= _atodecimal(aTHX_ SvPV_nolen(b))) return newSViv(1);
    50          
1321 0           return newSViv(0);
1322             }
1323 2 50         if(*(INT2PTR(D128 *, M_D128_SvIV(SvRV(a)))) <= _atodecimal(aTHX_ SvPV_nolen(b))) return newSViv(1);
    50          
1324 0           return newSViv(0);
1325             }
1326              
1327 14 100         if(sv_isobject(b)) {
1328 13 50         const char *h = HvNAME(SvSTASH(SvRV(b)));
    50          
    50          
    0          
    50          
    50          
1329 13 50         if(strEQ(h, "Math::Decimal128")) {
1330 13 100         if(*(INT2PTR(D128 *, M_D128_SvIV(SvRV(a)))) <= *(INT2PTR(D128 *, M_D128_SvIV(SvRV(b))))) return newSViv(1);
1331 1           return newSViv(0);
1332             }
1333 0           croak("Invalid object supplied to Math::Decimal128::_overload_lte function");
1334             }
1335 1           croak("Invalid argument supplied to Math::Decimal128::_overload_lte function");
1336             }
1337              
1338 11547556           SV * _overload_gte(pTHX_ SV * a, SV * b, SV * third) {
1339              
1340 11547556 100         if(SvUOK(b)) {
1341 3 100         if(third == &PL_sv_yes) {
1342 2 50         if(*(INT2PTR(D128 *, M_D128_SvIV(SvRV(a)))) <= (D128)M_D128_SvUV(b)) return newSViv(1);
1343 0           return newSViv(0);
1344             }
1345 1 50         if(*(INT2PTR(D128 *, M_D128_SvIV(SvRV(a)))) >= (D128)M_D128_SvUV(b)) return newSViv(1);
1346 0           return newSViv(0);
1347             }
1348              
1349 11547553 100         if(SvIOK(b)) {
1350 3 100         if(third == &PL_sv_yes) {
1351 2 50         if(*(INT2PTR(D128 *, M_D128_SvIV(SvRV(a)))) <= (D128)M_D128_SvIV(b)) return newSViv(1);
1352 0           return newSViv(0);
1353             }
1354 1 50         if(*(INT2PTR(D128 *, M_D128_SvIV(SvRV(a)))) >= (D128)M_D128_SvIV(b)) return newSViv(1);
1355 0           return newSViv(0);
1356             }
1357              
1358 11547550 100         if(SvPOK(b) && !SvNOK(b)) {
    50          
1359 4 100         if(third == &PL_sv_yes) {
1360 2 50         if(*(INT2PTR(D128 *, M_D128_SvIV(SvRV(a)))) <= _atodecimal(aTHX_ SvPV_nolen(b))) return newSViv(1);
    50          
1361 0           return newSViv(0);
1362             }
1363 2 50         if(*(INT2PTR(D128 *, M_D128_SvIV(SvRV(a)))) >= _atodecimal(aTHX_ SvPV_nolen(b))) return newSViv(1);
    50          
1364 0           return newSViv(0);
1365             }
1366              
1367 11547546 100         if(sv_isobject(b)) {
1368 11547545 50         const char *h = HvNAME(SvSTASH(SvRV(b)));
    50          
    50          
    0          
    50          
    50          
1369 11547545 50         if(strEQ(h, "Math::Decimal128")) {
1370 11547545 100         if(*(INT2PTR(D128 *, M_D128_SvIV(SvRV(a)))) >= *(INT2PTR(D128 *, M_D128_SvIV(SvRV(b))))) return newSViv(1);
1371 4179346           return newSViv(0);
1372             }
1373 0           croak("Invalid object supplied to Math::Decimal128::_overload_gte function");
1374             }
1375 1           croak("Invalid argument supplied to Math::Decimal128::_overload_gte function");
1376             }
1377              
1378 47           SV * _overload_spaceship(pTHX_ SV * a, SV * b, SV * third) {
1379 47           int reversal = 1;
1380 47 100         if(third == &PL_sv_yes) reversal = -1;
1381              
1382 47 100         if(SvUOK(b)) {
1383 9 100         if(*(INT2PTR(D128 *, M_D128_SvIV(SvRV(a)))) > (D128)M_D128_SvUV(b)) return newSViv( 1 * reversal);
1384 7 100         if(*(INT2PTR(D128 *, M_D128_SvIV(SvRV(a)))) < (D128)M_D128_SvUV(b)) return newSViv(-1 * reversal);
1385 5 100         if(*(INT2PTR(D128 *, M_D128_SvIV(SvRV(a)))) == (D128)M_D128_SvUV(b)) return newSViv(0);
1386 2           return &PL_sv_undef; /* Math::Decimal128 object (1st arg) is a nan */
1387             }
1388              
1389 38 100         if(SvIOK(b)) {
1390 9 100         if(*(INT2PTR(D128 *, M_D128_SvIV(SvRV(a)))) > (D128)M_D128_SvIV(b)) return newSViv( 1 * reversal);
1391 7 100         if(*(INT2PTR(D128 *, M_D128_SvIV(SvRV(a)))) < (D128)M_D128_SvIV(b)) return newSViv(-1 * reversal);
1392 5 100         if(*(INT2PTR(D128 *, M_D128_SvIV(SvRV(a)))) == (D128)M_D128_SvIV(b)) return newSViv(0);
1393 2           return &PL_sv_undef; /* Math::Decimal128 object (1st arg) is a nan */
1394             }
1395              
1396 29 100         if(SvPOK(b) && !SvNOK(b)) {
    50          
1397 9 50         if(*(INT2PTR(D128 *, M_D128_SvIV(SvRV(a)))) > _atodecimal(aTHX_ SvPV_nolen(b))) return newSViv( 1 * reversal);
    100          
1398 7 50         if(*(INT2PTR(D128 *, M_D128_SvIV(SvRV(a)))) < _atodecimal(aTHX_ SvPV_nolen(b))) return newSViv(-1 * reversal);
    100          
1399 5 50         if(*(INT2PTR(D128 *, M_D128_SvIV(SvRV(a)))) == _atodecimal(aTHX_ SvPV_nolen(b))) return newSViv(0);
    100          
1400 2           return &PL_sv_undef; /* Math::Decimal128 object (1st arg) is a nan */
1401             }
1402              
1403 20 100         if(sv_isobject(b)) {
1404 19 50         const char *h = HvNAME(SvSTASH(SvRV(b)));
    50          
    50          
    0          
    50          
    50          
1405 19 50         if(strEQ(h, "Math::Decimal128")) {
1406 19 100         if(*(INT2PTR(D128 *, M_D128_SvIV(SvRV(a)))) < *(INT2PTR(D128 *, M_D128_SvIV(SvRV(b))))) return newSViv(-1 * reversal);
1407 15 100         if(*(INT2PTR(D128 *, M_D128_SvIV(SvRV(a)))) > *(INT2PTR(D128 *, M_D128_SvIV(SvRV(b))))) return newSViv( 1 * reversal);
1408 11 100         if(*(INT2PTR(D128 *, M_D128_SvIV(SvRV(a)))) == *(INT2PTR(D128 *, M_D128_SvIV(SvRV(b))))) return newSViv(0);
1409 5           return &PL_sv_undef; /* it's a nan */
1410             }
1411 0           croak("Invalid object supplied to Math::Decimal128::_overload_spaceship function");
1412             }
1413 1           croak("Invalid argument supplied to Math::Decimal128::_overload_spaceship function");
1414             }
1415              
1416 188597           SV * _overload_copy(pTHX_ SV * a, SV * b, SV * third) {
1417              
1418             D128 * d128;
1419             SV * obj_ref, * obj;
1420              
1421 188597           Newx(d128, 1, D128);
1422 188597 50         if(d128 == NULL) croak("Failed to allocate memory in _overload_copy function");
1423              
1424 188597           *d128 = *(INT2PTR(D128 *, M_D128_SvIV(SvRV(a))));
1425              
1426 188597           obj_ref = newSV(0);
1427 188597           obj = newSVrv(obj_ref, "Math::Decimal128");
1428 188597           sv_setiv(obj, INT2PTR(IV,d128));
1429 188597           SvREADONLY_on(obj);
1430 188597           return obj_ref;
1431             }
1432              
1433 25           SV * D128toD128(pTHX_ SV * a) {
1434             D128 * d128;
1435             SV * obj_ref, * obj;
1436              
1437 25 50         if(sv_isobject(a)) {
1438 25 50         const char *h = HvNAME(SvSTASH(SvRV(a)));
    50          
    50          
    0          
    50          
    50          
1439 25 50         if(strEQ(h, "Math::Decimal128")) {
1440              
1441 25           Newx(d128, 1, D128);
1442 25 50         if(d128 == NULL) croak("Failed to allocate memory in D128toD128 function");
1443              
1444 25           *d128 = *(INT2PTR(D128 *, M_D128_SvIV(SvRV(a))));
1445              
1446 25           obj_ref = newSV(0);
1447 25           obj = newSVrv(obj_ref, "Math::Decimal128");
1448 25           sv_setiv(obj, INT2PTR(IV,d128));
1449 25           SvREADONLY_on(obj);
1450 25           return obj_ref;
1451             }
1452 0           croak("Invalid object supplied to Math::Decimal128::D128toD128 function");
1453             }
1454 0           croak("Invalid argument supplied to Math::Decimal128::D128toD128 function");
1455             }
1456              
1457 6           SV * _overload_true(pTHX_ SV * a, SV * b, SV * third) {
1458              
1459 6 100         if(_is_nan(*(INT2PTR(D128 *, M_D128_SvIV(SvRV(a)))))) return newSViv(0);
1460 4 100         if(*(INT2PTR(D128 *, M_D128_SvIV(SvRV(a)))) != 0.DL) return newSViv(1);
1461 1           return newSViv(0);
1462             }
1463              
1464 64           SV * _overload_not(pTHX_ SV * a, SV * b, SV * third) {
1465 64 100         if(_is_nan(*(INT2PTR(D128 *, M_D128_SvIV(SvRV(a)))))) return newSViv(1);
1466 63 100         if(*(INT2PTR(D128 *, M_D128_SvIV(SvRV(a)))) != 0.DL) return newSViv(0);
1467 14           return newSViv(1);
1468             }
1469              
1470 2           SV * _overload_abs(pTHX_ SV * a, SV * b, SV * third) {
1471              
1472             D128 * d128;
1473             SV * obj_ref, * obj;
1474              
1475 2           Newx(d128, 1, D128);
1476 2 50         if(d128 == NULL) croak("Failed to allocate memory in _overload_abs function");
1477              
1478 2           obj_ref = newSV(0);
1479 2           obj = newSVrv(obj_ref, "Math::Decimal128");
1480              
1481 2           sv_setiv(obj, INT2PTR(IV,d128));
1482 2           SvREADONLY_on(obj);
1483              
1484 2           *d128 = *(INT2PTR(D128 *, M_D128_SvIV(SvRV(a))));
1485 2 100         if(_is_neg_zero(*d128) || *d128 < 0 ) *d128 *= -1.DL;
    50          
1486 2           return obj_ref;
1487             }
1488              
1489 1           SV * _overload_inc(pTHX_ SV * p, SV * second, SV * third) {
1490 1           SvREFCNT_inc(p);
1491 1           *(INT2PTR(D128 *, M_D128_SvIV(SvRV(p)))) += 1.DL;
1492 1           return p;
1493             }
1494              
1495 1           SV * _overload_dec(pTHX_ SV * p, SV * second, SV * third) {
1496 1           SvREFCNT_inc(p);
1497 1           *(INT2PTR(D128 *, M_D128_SvIV(SvRV(p)))) -= 1.DL;
1498 1           return p;
1499             }
1500              
1501 149           SV * _itsa(pTHX_ SV * a) {
1502 149 100         if(SvUOK(a)) return newSVuv(1);
1503 135 100         if(SvIOK(a)) return newSVuv(2);
1504 119 100         if(SvNOK(a)) return newSVuv(3);
1505 115 100         if(SvPOK(a)) return newSVuv(4);
1506 41 50         if(sv_isobject(a)) {
1507 41 50         const char *h = HvNAME(SvSTASH(SvRV(a)));
    50          
    50          
    0          
    50          
    50          
1508 41 100         if(strEQ(h, "Math::Decimal128")) return newSVuv(34);
1509             }
1510 4           return newSVuv(0);
1511             }
1512              
1513 49495           SV * is_NaND128(pTHX_ SV * b) {
1514 49495 50         if(sv_isobject(b)) {
1515 49495 50         const char *h = HvNAME(SvSTASH(SvRV(b)));
    50          
    50          
    0          
    50          
    50          
1516 49495 50         if(strEQ(h, "Math::Decimal128"))
1517 49495           return newSViv(_is_nan(*(INT2PTR(D128 *, M_D128_SvIV(SvRV(b))))));
1518             }
1519 0           croak("Invalid argument supplied to Math::Decimal128::is_NaND128 function");
1520             }
1521              
1522 49574           SV * is_InfD128(pTHX_ SV * b) {
1523 49574 50         if(sv_isobject(b)) {
1524 49574 50         const char *h = HvNAME(SvSTASH(SvRV(b)));
    50          
    50          
    0          
    50          
    50          
1525 49574 50         if(strEQ(h, "Math::Decimal128"))
1526 49574           return newSViv(_is_inf(*(INT2PTR(D128 *, M_D128_SvIV(SvRV(b))))));
1527             }
1528 0           croak("Invalid argument supplied to Math::Decimal128::is_InfD128 function");
1529             }
1530              
1531 227634           SV * is_ZeroD128(pTHX_ SV * b) {
1532 227634 50         if(sv_isobject(b)) {
1533 227634 50         const char *h = HvNAME(SvSTASH(SvRV(b)));
    50          
    50          
    0          
    50          
    50          
1534 227634 50         if(strEQ(h, "Math::Decimal128"))
1535 227634 100         if (_is_neg_zero(*(INT2PTR(D128 *, M_D128_SvIV(SvRV(b)))))) return newSViv(-1);
1536 226915 100         if (*(INT2PTR(D128 *, M_D128_SvIV(SvRV(b)))) == 0.DL) return newSViv(1);
1537 226351           return newSViv(0);
1538             }
1539 0           croak("Invalid argument supplied to Math::Decimal128::is_ZeroD128 function");
1540             }
1541              
1542 0           SV * _wrap_count(pTHX) {
1543 0           return newSVuv(PL_sv_count);
1544             }
1545              
1546 1           SV * _get_xs_version(pTHX) {
1547 1           return newSVpv(XS_VERSION, 0);
1548             }
1549              
1550 199389           void _d128_bytes(pTHX_ SV * sv) {
1551 199389           dXSARGS;
1552 199389           D128 d128 = *(INT2PTR(D128 *, M_D128_SvIV(SvRV(sv))));
1553 199389           int i, n = sizeof(D128);
1554             char buff[4];
1555 199389           void * p = &d128;
1556              
1557 199389           sp = mark;
1558              
1559             #ifdef WE_HAVE_BENDIAN /* Big Endian architecture */
1560             for (i = 0; i < n; i++) {
1561             #else
1562 3389613 100         for (i = n - 1; i >= 0; i--) {
1563             #endif
1564              
1565 3190224           sprintf(buff, "%02X", ((unsigned char*)p)[i]);
1566 3190224 50         XPUSHs(sv_2mortal(newSVpv(buff, 0)));
1567             }
1568 199389           PUTBACK;
1569 199389           XSRETURN(n);
1570             }
1571              
1572 184691           SV * _bid_mant(pTHX_ SV * bin) {
1573              
1574             D128 * d128;
1575             SV * obj_ref, * obj;
1576 184691           int i, imax = av_len((AV*)SvRV(bin));
1577 184691           D128 val = 0.DL;
1578             extern D128 add_on[];
1579              
1580 184691           Newx(d128, 1, D128);
1581 184691 50         if(d128 == NULL) croak("Failed to allocate memory in _bid_mant function");
1582              
1583 21239465 100         for(i = 0; i <= imax; i++)
1584 21054774 50         if(SvIV(*(av_fetch((AV*)SvRV(bin), i, 0)))) val += add_on[i];
    100          
1585              
1586             /* If val is inf or nan this function would not have been called.
1587             Therefore, if val > DEC128_MAX it must be one of those illegal
1588             values that should be set to zero */
1589              
1590 184691 50         if(val > 9999999999999999999999999999999999e0DL) val = 0.DL;
1591              
1592 184691           obj_ref = newSV(0);
1593 184691           obj = newSVrv(obj_ref, "Math::Decimal128");
1594              
1595 184691           *d128 = val;
1596 184691           sv_setiv(obj, INT2PTR(IV,d128));
1597 184691           SvREADONLY_on(obj);
1598 184691           return obj_ref;
1599              
1600             }
1601              
1602 1           SV * _endianness(pTHX) {
1603             #if defined(WE_HAVE_BENDIAN)
1604             return newSVpv("Big Endian", 0);
1605             #elif defined(WE_HAVE_LENDIAN)
1606 1           return newSVpv("Little Endian", 0);
1607             #else
1608             return &PL_sv_undef;
1609             #endif
1610             }
1611              
1612 6           SV * _DPDtoD128(pTHX_ char * in) {
1613             D128 * d128;
1614             SV * obj_ref, * obj;
1615 6           int i, n = sizeof(D128);
1616 6           D128 out = 0.;
1617 6           void *p = &out;
1618              
1619 6           Newx(d128, 1, D128);
1620 6 50         if(d128 == NULL) croak("Failed to allocate memory in DPDtoD128 function");
1621              
1622 6           obj_ref = newSV(0);
1623 6           obj = newSVrv(obj_ref, "Math::Decimal128");
1624              
1625 102 100         for (i = n - 1; i >= 0; i--)
1626             #ifdef WE_HAVE_BENDIAN
1627             ((unsigned char*)p)[i] = in[i];
1628             #else
1629 96           ((unsigned char*)p)[i] = in[n - 1 - i];
1630             #endif
1631              
1632 6           *d128 = out;
1633              
1634 6           sv_setiv(obj, INT2PTR(IV,d128));
1635 6           SvREADONLY_on(obj);
1636 6           return obj_ref;
1637             }
1638              
1639             /*
1640             _assignDPD takes 2 args: a Math::Decimal128 object, and a
1641             string that encodes the value to be assigned to that object
1642             */
1643 6           void _assignDPD(pTHX_ SV * a, char * in) {
1644 6           int i, n = sizeof(D128);
1645 6           D128 out = 0.;
1646 6           void *p = &out;
1647              
1648 102 100         for (i = n - 1; i >= 0; i--)
1649             #ifdef WE_HAVE_BENDIAN
1650             ((unsigned char*)p)[i] = in[i];
1651             #else
1652 96           ((unsigned char*)p)[i] = in[n - 1 - i];
1653             #endif
1654              
1655 6 50         *(INT2PTR(D128 *, SvIV(SvRV(a)))) = out;
1656 6           }
1657              
1658 18           int nnumflag(void) {
1659 18           return nnum;
1660             }
1661              
1662 1           void clear_nnum(void) {
1663 1           nnum = 0;
1664 1           }
1665              
1666 1           void set_nnum(int x) {
1667 1           nnum = x;
1668 1           }
1669              
1670              
1671 0           int _lln(pTHX_ SV * x) {
1672 0 0         if(looks_like_number(x)) return 1;
1673 0           return 0;
1674             }
1675             MODULE = Math::Decimal128 PACKAGE = Math::Decimal128
1676              
1677             PROTOTYPES: DISABLE
1678              
1679              
1680             SV *
1681             _is_nan_NV (x)
1682             SV * x
1683             CODE:
1684 0           RETVAL = _is_nan_NV (aTHX_ x);
1685             OUTPUT: RETVAL
1686              
1687             SV *
1688             _is_inf_NV (x)
1689             SV * x
1690             CODE:
1691 0           RETVAL = _is_inf_NV (aTHX_ x);
1692             OUTPUT: RETVAL
1693              
1694             SV *
1695             _is_neg_zero_NV (x)
1696             SV * x
1697             CODE:
1698 0           RETVAL = _is_neg_zero_NV (aTHX_ x);
1699             OUTPUT: RETVAL
1700              
1701             SV *
1702             _DEC128_MAX ()
1703             CODE:
1704 8           RETVAL = _DEC128_MAX (aTHX);
1705             OUTPUT: RETVAL
1706              
1707              
1708             SV *
1709             _DEC128_MIN ()
1710             CODE:
1711 9           RETVAL = _DEC128_MIN (aTHX);
1712             OUTPUT: RETVAL
1713              
1714              
1715             SV *
1716             NaND128 ()
1717             CODE:
1718 30           RETVAL = NaND128 (aTHX);
1719             OUTPUT: RETVAL
1720              
1721              
1722             SV *
1723             InfD128 (sign)
1724             int sign
1725             CODE:
1726 18           RETVAL = InfD128 (aTHX_ sign);
1727             OUTPUT: RETVAL
1728              
1729             SV *
1730             ZeroD128 (sign)
1731             int sign
1732             CODE:
1733 47722           RETVAL = ZeroD128 (aTHX_ sign);
1734             OUTPUT: RETVAL
1735              
1736             SV *
1737             UnityD128 (sign)
1738             int sign
1739             CODE:
1740 2429           RETVAL = UnityD128 (aTHX_ sign);
1741             OUTPUT: RETVAL
1742              
1743             SV *
1744             Exp10l (power)
1745             int power
1746             CODE:
1747 4868           RETVAL = Exp10l (aTHX_ power);
1748             OUTPUT: RETVAL
1749              
1750             SV *
1751             _testvalD128_1 (sign)
1752             int sign
1753             CODE:
1754 0           RETVAL = _testvalD128_1 (aTHX_ sign);
1755             OUTPUT: RETVAL
1756              
1757             SV *
1758             _testvalD128_2 (sign)
1759             int sign
1760             CODE:
1761 2           RETVAL = _testvalD128_2 (aTHX_ sign);
1762             OUTPUT: RETVAL
1763              
1764             SV *
1765             _testvalD128_3 (sign)
1766             int sign
1767             CODE:
1768 0           RETVAL = _testvalD128_3 (aTHX_ sign);
1769             OUTPUT: RETVAL
1770              
1771             SV *
1772             _testvalD128_4 (sign)
1773             int sign
1774             CODE:
1775 0           RETVAL = _testvalD128_4 (aTHX_ sign);
1776             OUTPUT: RETVAL
1777              
1778             SV *
1779             _MEtoD128 (msd, nsd, lsd, exponent)
1780             char * msd
1781             char * nsd
1782             char * lsd
1783             SV * exponent
1784             CODE:
1785 373638           RETVAL = _MEtoD128 (aTHX_ msd, nsd, lsd, exponent);
1786             OUTPUT: RETVAL
1787              
1788             void
1789             _assignME (a, msd, nsd, lsd, c)
1790             SV * a
1791             char * msd
1792             char * nsd
1793             char * lsd
1794             SV * c
1795             PREINIT:
1796             I32* temp;
1797             PPCODE:
1798 11           temp = PL_markstack_ptr++;
1799 11           _assignME(aTHX_ a, msd, nsd, lsd, c);
1800 11 50         if (PL_markstack_ptr != temp) {
1801             /* truly void, because dXSARGS not invoked */
1802 11           PL_markstack_ptr = temp;
1803 11           XSRETURN_EMPTY; /* return empty stack */
1804             }
1805             /* must have used dXSARGS; list context implied */
1806 0           return; /* assume stack size is correct */
1807              
1808             SV *
1809             NVtoD128 (x)
1810             SV * x
1811             CODE:
1812 65           RETVAL = NVtoD128 (aTHX_ x);
1813             OUTPUT: RETVAL
1814              
1815             SV *
1816             UVtoD128 (x)
1817             SV * x
1818             CODE:
1819 17           RETVAL = UVtoD128 (aTHX_ x);
1820             OUTPUT: RETVAL
1821              
1822             SV *
1823             IVtoD128 (x)
1824             SV * x
1825             CODE:
1826 18           RETVAL = IVtoD128 (aTHX_ x);
1827             OUTPUT: RETVAL
1828              
1829             SV *
1830             PVtoD128 (x)
1831             char * x
1832             CODE:
1833 23800           RETVAL = PVtoD128 (aTHX_ x);
1834             OUTPUT: RETVAL
1835              
1836             SV *
1837             STRtoD128 (x)
1838             char * x
1839             CODE:
1840 0           RETVAL = STRtoD128 (aTHX_ x);
1841             OUTPUT: RETVAL
1842              
1843             int
1844             have_strtod128 ()
1845              
1846              
1847             SV *
1848             D128toNV (d128)
1849             SV * d128
1850             CODE:
1851 3           RETVAL = D128toNV (aTHX_ d128);
1852             OUTPUT: RETVAL
1853              
1854             void
1855             DESTROY (rop)
1856             SV * rop
1857             PREINIT:
1858             I32* temp;
1859             PPCODE:
1860 828554           temp = PL_markstack_ptr++;
1861 828554           DESTROY(aTHX_ rop);
1862 828554 50         if (PL_markstack_ptr != temp) {
1863             /* truly void, because dXSARGS not invoked */
1864 828554           PL_markstack_ptr = temp;
1865 828554           XSRETURN_EMPTY; /* return empty stack */
1866             }
1867             /* must have used dXSARGS; list context implied */
1868 0           return; /* assume stack size is correct */
1869              
1870             void
1871             assignIVl (a, val)
1872             SV * a
1873             SV * val
1874             PREINIT:
1875             I32* temp;
1876             PPCODE:
1877 2           temp = PL_markstack_ptr++;
1878 2           assignIVl(aTHX_ a, val);
1879 2 50         if (PL_markstack_ptr != temp) {
1880             /* truly void, because dXSARGS not invoked */
1881 2           PL_markstack_ptr = temp;
1882 2           XSRETURN_EMPTY; /* return empty stack */
1883             }
1884             /* must have used dXSARGS; list context implied */
1885 0           return; /* assume stack size is correct */
1886              
1887             void
1888             assignUVl (a, val)
1889             SV * a
1890             SV * val
1891             PREINIT:
1892             I32* temp;
1893             PPCODE:
1894 1           temp = PL_markstack_ptr++;
1895 1           assignUVl(aTHX_ a, val);
1896 1 50         if (PL_markstack_ptr != temp) {
1897             /* truly void, because dXSARGS not invoked */
1898 1           PL_markstack_ptr = temp;
1899 1           XSRETURN_EMPTY; /* return empty stack */
1900             }
1901             /* must have used dXSARGS; list context implied */
1902 0           return; /* assume stack size is correct */
1903              
1904             void
1905             assignNVl (a, val)
1906             SV * a
1907             SV * val
1908             PREINIT:
1909             I32* temp;
1910             PPCODE:
1911 2           temp = PL_markstack_ptr++;
1912 2           assignNVl(aTHX_ a, val);
1913 2 50         if (PL_markstack_ptr != temp) {
1914             /* truly void, because dXSARGS not invoked */
1915 2           PL_markstack_ptr = temp;
1916 2           XSRETURN_EMPTY; /* return empty stack */
1917             }
1918             /* must have used dXSARGS; list context implied */
1919 0           return; /* assume stack size is correct */
1920              
1921             void
1922             assignPVl (a, s)
1923             SV * a
1924             char * s
1925             PREINIT:
1926             I32* temp;
1927             PPCODE:
1928 25101           temp = PL_markstack_ptr++;
1929 25101           assignPVl(aTHX_ a, s);
1930 25101 50         if (PL_markstack_ptr != temp) {
1931             /* truly void, because dXSARGS not invoked */
1932 25101           PL_markstack_ptr = temp;
1933 25101           XSRETURN_EMPTY; /* return empty stack */
1934             }
1935             /* must have used dXSARGS; list context implied */
1936 0           return; /* assume stack size is correct */
1937              
1938             void
1939             assignD128 (a, val)
1940             SV * a
1941             SV * val
1942             PREINIT:
1943             I32* temp;
1944             PPCODE:
1945 1           temp = PL_markstack_ptr++;
1946 1           assignD128(aTHX_ a, val);
1947 1 50         if (PL_markstack_ptr != temp) {
1948             /* truly void, because dXSARGS not invoked */
1949 1           PL_markstack_ptr = temp;
1950 1           XSRETURN_EMPTY; /* return empty stack */
1951             }
1952             /* must have used dXSARGS; list context implied */
1953 0           return; /* assume stack size is correct */
1954              
1955             void
1956             assignNaNl (a)
1957             SV * a
1958             PREINIT:
1959             I32* temp;
1960             PPCODE:
1961 2           temp = PL_markstack_ptr++;
1962 2           assignNaNl(aTHX_ a);
1963 2 50         if (PL_markstack_ptr != temp) {
1964             /* truly void, because dXSARGS not invoked */
1965 2           PL_markstack_ptr = temp;
1966 2           XSRETURN_EMPTY; /* return empty stack */
1967             }
1968             /* must have used dXSARGS; list context implied */
1969 0           return; /* assume stack size is correct */
1970              
1971             void
1972             assignInfl (a, sign)
1973             SV * a
1974             int sign
1975             PREINIT:
1976             I32* temp;
1977             PPCODE:
1978 4           temp = PL_markstack_ptr++;
1979 4           assignInfl(aTHX_ a, sign);
1980 4 50         if (PL_markstack_ptr != temp) {
1981             /* truly void, because dXSARGS not invoked */
1982 4           PL_markstack_ptr = temp;
1983 4           XSRETURN_EMPTY; /* return empty stack */
1984             }
1985             /* must have used dXSARGS; list context implied */
1986 0           return; /* assume stack size is correct */
1987              
1988             SV *
1989             _overload_add (a, b, third)
1990             SV * a
1991             SV * b
1992             SV * third
1993             CODE:
1994 41           RETVAL = _overload_add (aTHX_ a, b, third);
1995             OUTPUT: RETVAL
1996              
1997             SV *
1998             _overload_mul (a, b, third)
1999             SV * a
2000             SV * b
2001             SV * third
2002             CODE:
2003 2502           RETVAL = _overload_mul (aTHX_ a, b, third);
2004             OUTPUT: RETVAL
2005              
2006             SV *
2007             _overload_sub (a, b, third)
2008             SV * a
2009             SV * b
2010             SV * third
2011             CODE:
2012 34           RETVAL = _overload_sub (aTHX_ a, b, third);
2013             OUTPUT: RETVAL
2014              
2015             SV *
2016             _overload_neg (a, b, third)
2017             SV * a
2018             SV * b
2019             SV * third
2020             CODE:
2021 4           RETVAL = _overload_neg (aTHX_ a, b, third);
2022             OUTPUT: RETVAL
2023              
2024             SV *
2025             _overload_div (a, b, third)
2026             SV * a
2027             SV * b
2028             SV * third
2029             CODE:
2030 28           RETVAL = _overload_div (aTHX_ a, b, third);
2031             OUTPUT: RETVAL
2032              
2033             SV *
2034             _overload_add_eq (a, b, third)
2035             SV * a
2036             SV * b
2037             SV * third
2038             CODE:
2039 103           RETVAL = _overload_add_eq (aTHX_ a, b, third);
2040             OUTPUT: RETVAL
2041              
2042             SV *
2043             _overload_mul_eq (a, b, third)
2044             SV * a
2045             SV * b
2046             SV * third
2047             CODE:
2048 4878           RETVAL = _overload_mul_eq (aTHX_ a, b, third);
2049             OUTPUT: RETVAL
2050              
2051             SV *
2052             _overload_sub_eq (a, b, third)
2053             SV * a
2054             SV * b
2055             SV * third
2056             CODE:
2057 7368192           RETVAL = _overload_sub_eq (aTHX_ a, b, third);
2058             OUTPUT: RETVAL
2059              
2060             SV *
2061             _overload_div_eq (a, b, third)
2062             SV * a
2063             SV * b
2064             SV * third
2065             CODE:
2066 22           RETVAL = _overload_div_eq (aTHX_ a, b, third);
2067             OUTPUT: RETVAL
2068              
2069             SV *
2070             _overload_equiv (a, b, third)
2071             SV * a
2072             SV * b
2073             SV * third
2074             CODE:
2075 123           RETVAL = _overload_equiv (aTHX_ a, b, third);
2076             OUTPUT: RETVAL
2077              
2078             SV *
2079             _overload_not_equiv (a, b, third)
2080             SV * a
2081             SV * b
2082             SV * third
2083             CODE:
2084 232103           RETVAL = _overload_not_equiv (aTHX_ a, b, third);
2085             OUTPUT: RETVAL
2086              
2087             SV *
2088             _overload_lt (a, b, third)
2089             SV * a
2090             SV * b
2091             SV * third
2092             CODE:
2093 23875           RETVAL = _overload_lt (aTHX_ a, b, third);
2094             OUTPUT: RETVAL
2095              
2096             SV *
2097             _overload_gt (a, b, third)
2098             SV * a
2099             SV * b
2100             SV * third
2101             CODE:
2102 6444820           RETVAL = _overload_gt (aTHX_ a, b, third);
2103             OUTPUT: RETVAL
2104              
2105             SV *
2106             _overload_lte (a, b, third)
2107             SV * a
2108             SV * b
2109             SV * third
2110             CODE:
2111 24           RETVAL = _overload_lte (aTHX_ a, b, third);
2112             OUTPUT: RETVAL
2113              
2114             SV *
2115             _overload_gte (a, b, third)
2116             SV * a
2117             SV * b
2118             SV * third
2119             CODE:
2120 11547556           RETVAL = _overload_gte (aTHX_ a, b, third);
2121             OUTPUT: RETVAL
2122              
2123             SV *
2124             _overload_spaceship (a, b, third)
2125             SV * a
2126             SV * b
2127             SV * third
2128             CODE:
2129 47           RETVAL = _overload_spaceship (aTHX_ a, b, third);
2130             OUTPUT: RETVAL
2131              
2132             SV *
2133             _overload_copy (a, b, third)
2134             SV * a
2135             SV * b
2136             SV * third
2137             CODE:
2138 188597           RETVAL = _overload_copy (aTHX_ a, b, third);
2139             OUTPUT: RETVAL
2140              
2141             SV *
2142             D128toD128 (a)
2143             SV * a
2144             CODE:
2145 25           RETVAL = D128toD128 (aTHX_ a);
2146             OUTPUT: RETVAL
2147              
2148             SV *
2149             _overload_true (a, b, third)
2150             SV * a
2151             SV * b
2152             SV * third
2153             CODE:
2154 6           RETVAL = _overload_true (aTHX_ a, b, third);
2155             OUTPUT: RETVAL
2156              
2157             SV *
2158             _overload_not (a, b, third)
2159             SV * a
2160             SV * b
2161             SV * third
2162             CODE:
2163 64           RETVAL = _overload_not (aTHX_ a, b, third);
2164             OUTPUT: RETVAL
2165              
2166             SV *
2167             _overload_abs (a, b, third)
2168             SV * a
2169             SV * b
2170             SV * third
2171             CODE:
2172 2           RETVAL = _overload_abs (aTHX_ a, b, third);
2173             OUTPUT: RETVAL
2174              
2175             SV *
2176             _overload_inc (p, second, third)
2177             SV * p
2178             SV * second
2179             SV * third
2180             CODE:
2181 1           RETVAL = _overload_inc (aTHX_ p, second, third);
2182             OUTPUT: RETVAL
2183              
2184             SV *
2185             _overload_dec (p, second, third)
2186             SV * p
2187             SV * second
2188             SV * third
2189             CODE:
2190 1           RETVAL = _overload_dec (aTHX_ p, second, third);
2191             OUTPUT: RETVAL
2192              
2193             SV *
2194             _itsa (a)
2195             SV * a
2196             CODE:
2197 149           RETVAL = _itsa (aTHX_ a);
2198             OUTPUT: RETVAL
2199              
2200             SV *
2201             is_NaND128 (b)
2202             SV * b
2203             CODE:
2204 49495           RETVAL = is_NaND128 (aTHX_ b);
2205             OUTPUT: RETVAL
2206              
2207             SV *
2208             is_InfD128 (b)
2209             SV * b
2210             CODE:
2211 49574           RETVAL = is_InfD128 (aTHX_ b);
2212             OUTPUT: RETVAL
2213              
2214             SV *
2215             is_ZeroD128 (b)
2216             SV * b
2217             CODE:
2218 227634           RETVAL = is_ZeroD128 (aTHX_ b);
2219             OUTPUT: RETVAL
2220              
2221             SV *
2222             _wrap_count ()
2223             CODE:
2224 0           RETVAL = _wrap_count (aTHX);
2225             OUTPUT: RETVAL
2226              
2227              
2228             SV *
2229             _get_xs_version ()
2230             CODE:
2231 1           RETVAL = _get_xs_version (aTHX);
2232             OUTPUT: RETVAL
2233              
2234              
2235             void
2236             _d128_bytes (sv)
2237             SV * sv
2238             PREINIT:
2239             I32* temp;
2240             PPCODE:
2241 199389           temp = PL_markstack_ptr++;
2242 199389           _d128_bytes(aTHX_ sv);
2243 199389 50         if (PL_markstack_ptr != temp) {
2244             /* truly void, because dXSARGS not invoked */
2245 0           PL_markstack_ptr = temp;
2246 0           XSRETURN_EMPTY; /* return empty stack */
2247             }
2248             /* must have used dXSARGS; list context implied */
2249 199389           return; /* assume stack size is correct */
2250              
2251             SV *
2252             _bid_mant (bin)
2253             SV * bin
2254             CODE:
2255 184691           RETVAL = _bid_mant (aTHX_ bin);
2256             OUTPUT: RETVAL
2257              
2258             SV *
2259             _endianness ()
2260             CODE:
2261 1           RETVAL = _endianness (aTHX);
2262             OUTPUT: RETVAL
2263              
2264              
2265             SV *
2266             _DPDtoD128 (in)
2267             char * in
2268             CODE:
2269 6           RETVAL = _DPDtoD128 (aTHX_ in);
2270             OUTPUT: RETVAL
2271              
2272             void
2273             _assignDPD (a, in)
2274             SV * a
2275             char * in
2276             PREINIT:
2277             I32* temp;
2278             PPCODE:
2279 6           temp = PL_markstack_ptr++;
2280 6           _assignDPD(aTHX_ a, in);
2281 6 50         if (PL_markstack_ptr != temp) {
2282             /* truly void, because dXSARGS not invoked */
2283 6           PL_markstack_ptr = temp;
2284 6           XSRETURN_EMPTY; /* return empty stack */
2285             }
2286             /* must have used dXSARGS; list context implied */
2287 0           return; /* assume stack size is correct */
2288              
2289             int
2290             nnumflag ()
2291              
2292              
2293             void
2294             clear_nnum ()
2295              
2296             PREINIT:
2297             I32* temp;
2298             PPCODE:
2299 1           temp = PL_markstack_ptr++;
2300 1           clear_nnum();
2301 1 50         if (PL_markstack_ptr != temp) {
2302             /* truly void, because dXSARGS not invoked */
2303 1           PL_markstack_ptr = temp;
2304 1           XSRETURN_EMPTY; /* return empty stack */
2305             }
2306             /* must have used dXSARGS; list context implied */
2307 0           return; /* assume stack size is correct */
2308              
2309             void
2310             set_nnum (x)
2311             int x
2312             PREINIT:
2313             I32* temp;
2314             PPCODE:
2315 1           temp = PL_markstack_ptr++;
2316 1           set_nnum(x);
2317 1 50         if (PL_markstack_ptr != temp) {
2318             /* truly void, because dXSARGS not invoked */
2319 1           PL_markstack_ptr = temp;
2320 1           XSRETURN_EMPTY; /* return empty stack */
2321             }
2322             /* must have used dXSARGS; list context implied */
2323 0           return; /* assume stack size is correct */
2324              
2325             int
2326             _lln (x)
2327             SV * x
2328             CODE:
2329 0           RETVAL = _lln (aTHX_ x);
2330             OUTPUT: RETVAL
2331