File Coverage

Decimal64.xs
Criterion Covered Total %
statement 835 1013 82.4
branch 766 1700 45.0
condition n/a
subroutine n/a
pod n/a
total 1601 2713 59.0


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