File Coverage

Int64.xs
Criterion Covered Total %
statement 570 760 75.0
branch 330 612 53.9
condition n/a
subroutine n/a
pod n/a
total 900 1372 65.6


line stmt bran cond sub pod time code
1             /* -*- Mode: C -*- */
2              
3             #define PERL_NO_GET_CONTEXT 1
4              
5             #include "EXTERN.h"
6             #include "perl.h"
7             #include "XSUB.h"
8              
9             #define NEED_sv_2pvbyte
10             #define NEED_sv_2pv_flags
11             #include "ppport.h"
12              
13             static int may_die_on_overflow;
14             static int may_use_native;
15              
16             #ifdef HAS_STDINT_H
17             #include
18             #endif
19              
20             #define NV_0x1p15 ((NV)32768)
21             #define NV_0x1p16 ((NV)65536)
22             #define NV_0x1p31 (NV_0x1p16 * NV_0x1p15)
23             #define NV_0x1p32 (NV_0x1p16 * NV_0x1p16)
24             #define NV_0x1p63 (NV_0x1p32 * NV_0x1p31)
25             #define NV_0x1p64 (NV_0x1p32 * NV_0x1p32)
26              
27             #ifdef _MSC_VER
28             #include
29              
30             #ifndef INT64_MAX
31             #define INT64_MAX _I64_MAX
32             #endif
33             #ifndef INT64_MIN
34             #define INT64_MIN _I64_MIN
35             #endif
36             #ifndef UINT64_MAX
37             #define UINT64_MAX _UI64_MAX
38             #endif
39             #ifndef UINT32_MAX
40             #define UINT32_MAX _UI32_MAX
41             #endif
42              
43             #endif
44              
45             #ifdef USE_INT64_T
46             /* do nothing */
47              
48             #elif defined(USE___INT64)
49             typedef __int64 int64_t;
50             typedef unsigned __int64 uint64_t;
51              
52             #elif defined(USE_INT64_DI)
53             typedef int int64_t __attribute__ ((__mode__ (DI)));
54             typedef unsigned int uint64_t __attribute__ ((__mode__ (DTI)));
55              
56             #else
57             #error "No int64 type define was passed to the compiler!"
58             #endif
59              
60             #if ((defined _MSC_VER) || (defined INT64_MY_NV2U64))
61              
62             /* Old MS compilers do not implement the double->uint64 conversion and
63             * silently do a double->int64 conversion instead. See
64             * http://connect.microsoft.com/VisualStudio/feedback/details/270762/error-in-converting-double-to-unsigned-long-long */
65              
66             /* I don't trust atof, so I generate 2**-32 from simpler constants and
67             * hope the optimizer will do its work properly */
68              
69             #define NV_0x1p_4 ((NV)0.0625)
70             #define NV_0x1p_16 (NV_0x1p_4 * NV_0x1p_4 * NV_0x1p_4 * NV_0x1p_4)
71             #define NV_0x1p_32 (NV_0x1p_16 * NV_0x1p_16)
72              
73             static uint64_t
74             nv2u64(NV nv) {
75             if ((nv > 0.0) && (nv < NV_0x1p64)) {
76             uint64_t h = nv * NV_0x1p_32;
77             uint64_t l = nv - (NV)(int64_t)h * NV_0x1p32;
78             return ((h << 32) + l);
79             }
80             return 0;
81             }
82             #define NV2U64(nv) nv2u64(nv)
83              
84             # if defined(_MSC_VER) && _MSC_VER >= 1300
85             # define U642NV(u64) ((NV)(u64))
86             # else
87             static NV
88             u642nv(uint64_t u64) {
89             unsigned long h = u64 >> 32;
90             unsigned long l = u64 & 0xffffffff;
91             return (NV_0x1p32 * h) + (NV)l;
92             }
93             # define U642NV(nv) u642nv(nv)
94             # endif
95             #else
96             #define NV2U64(nv) ((uint64_t)(nv))
97             #define U642NV(u64) ((NV)(u64))
98             #endif
99              
100             #if (PERL_VERSION >= 10)
101              
102             #ifndef cop_hints_fetch_pvs
103             #define cop_hints_fetch_pvs(cop, key, flags) \
104             Perl_refcounted_he_fetch(aTHX_ (cop)->cop_hints_hash, NULL, STR_WITH_LEN(key), (flags), 0)
105             #endif
106              
107             static int
108 58           check_die_on_overflow_hint(pTHX) {
109 58           SV *hint = cop_hints_fetch_pvs(PL_curcop, "Math::Int64::die_on_overflow", 0);
110 58 50         return (hint && SvTRUE(hint));
    100          
111             }
112              
113             static int
114 16           check_use_native_hint(pTHX) {
115 16           SV *hint = cop_hints_fetch_pvs(PL_curcop, "Math::Int64::native_if_available", 0);
116 16 50         return (hint && SvTRUE(hint));
    50          
117             }
118              
119             #define use_native (may_use_native && check_use_native_hint(aTHX))
120              
121             #else
122              
123             static int
124             check_die_on_overflow_hint(pTHX) {
125             return 1;
126             }
127              
128             static int
129             check_use_native_hint(pTHX) {
130             return 1;
131             }
132              
133             #define use_native may_use_native
134              
135             #endif
136              
137             static void
138 58           overflow(pTHX_ const char *msg) {
139 58 100         if (check_die_on_overflow_hint(aTHX))
140 30           Perl_croak(aTHX_ "Math::Int64 overflow: %s", msg);
141 28           }
142              
143             static const char *out_of_bounds_error_s = "Number is out of bounds for int64_t conversion";
144             static const char *out_of_bounds_error_u = "Number is out of bounds for uint64_t conversion";
145             static const char *mul_error = "Multiplication overflows";
146             static const char *add_error = "Addition overflows";
147             static const char *sub_error = "Subtraction overflows";
148             static const char *inc_error = "Increment operation wraps";
149             static const char *dec_error = "Decrement operation wraps";
150             static const char *div_by_0_error = "Illegal division by zero";
151             static const char *pow_error = "Exponentiation overflows";
152             static const char *invalid_length_error_s = "Invalid length for int64";
153             static const char *invalid_length_error_u = "Invalid length for uint64";
154             static const char *invalid_BER_error = "Invalid BER encoding";
155              
156 1           static void croak_string(pTHX_ const char *str) {
157 1           Perl_croak(aTHX_ "%s", str);
158             }
159              
160             #include "strtoint64.h"
161             #include "isaac64.h"
162              
163             #define MY_CXT_KEY "Math::Int64::isaac64_state" XS_VERSION
164             typedef struct {
165             isaac64_state_t is;
166             } my_cxt_t;
167             START_MY_CXT
168              
169             #if defined(INT64_BACKEND_NV)
170             # define BACKEND "NV"
171             # define SvI64Y SvNVX
172             # define SvI64_onY SvNOK_on
173             # define SVt_I64 SVt_NV
174             #elif defined(INT64_BACKEND_IV)
175             # define BACKEND "IV"
176             # define SvI64Y SvIVX
177             # define SvI64_onY SvIOK_on
178             # define SVt_I64 SVt_IV
179             #else
180             # error "unsupported backend"
181             #endif
182              
183             static int
184 0           SvI64OK(pTHX_ SV *sv) {
185 0 0         if (SvROK(sv)) {
186 0           SV *si64 = SvRV(sv);
187 0 0         return (si64 && (SvTYPE(si64) >= SVt_I64) && sv_isa(sv, "Math::Int64"));
    0          
    0          
188             }
189 0           return 0;
190             }
191              
192             static int
193 0           SvU64OK(pTHX_ SV *sv) {
194 0 0         if (SvROK(sv)) {
195 0           SV *su64 = SvRV(sv);
196 0 0         return (su64 && (SvTYPE(su64) >= SVt_I64) && sv_isa(sv, "Math::UInt64"));
    0          
    0          
197             }
198 0           return 0;
199             }
200              
201             static SV *
202 1674           newSVi64(pTHX_ int64_t i64) {
203             SV *sv;
204 1674           SV *si64 = newSV(0);
205 1674 50         SvUPGRADE(si64, SVt_I64);
206 1674           SvI64_onY(si64);
207 1674           sv = newRV_noinc(si64);
208 1674           sv_bless(sv, gv_stashpvs("Math::Int64", TRUE));
209 1674           *(int64_t*)(&(SvI64Y(si64))) = i64;
210 1674           SvREADONLY_on(si64);
211 1674           return sv;
212             }
213              
214             static SV *
215 2046           newSVu64(pTHX_ uint64_t u64) {
216             SV *sv;
217 2046           SV *su64 = newSV(0);
218 2046 50         SvUPGRADE(su64, SVt_I64);
219 2046           SvI64_onY(su64);
220 2046           sv = newRV_noinc(su64);
221 2046           sv_bless(sv, gv_stashpvs("Math::UInt64", TRUE));
222 2046           *(int64_t*)(&(SvI64Y(su64))) = u64;
223 2046           SvREADONLY_on(su64);
224 2046           return sv;
225             }
226              
227             #define SvI64X(sv) (*(int64_t*)(&(SvI64Y(SvRV(sv)))))
228             #define SvU64X(sv) (*(uint64_t*)(&(SvI64Y(SvRV(sv)))))
229              
230             static SV *
231 3179           SvSI64(pTHX_ SV *sv) {
232 3179 50         if (SvROK(sv)) {
233 3179           SV *si64 = SvRV(sv);
234 3179 50         if (si64 && (SvTYPE(si64) >= SVt_I64))
    50          
235 3179           return si64;
236             }
237 0           croak_string(aTHX_ "internal error: reference to NV expected");
238 0           return NULL; /* this dead code is a workaround for OpenWatcom */
239             }
240              
241             static SV *
242 3213           SvSU64(pTHX_ SV *sv) {
243 3213 50         if (SvROK(sv)) {
244 3213           SV *su64 = SvRV(sv);
245 3213 50         if (su64 && (SvTYPE(su64) >= SVt_I64))
    50          
246 3213           return su64;
247             }
248 0           croak_string(aTHX_ "internal error: reference to NV expected");
249 0           return NULL; /* this dead code is a workaround for OpenWatcom */
250             }
251              
252             #define SvI64x(sv) (*(int64_t*)(&(SvI64Y(SvSI64(aTHX_ sv)))))
253             #define SvU64x(sv) (*(uint64_t*)(&(SvI64Y(SvSU64(aTHX_ sv)))))
254              
255             static int64_t
256 1794           SvI64(pTHX_ SV *sv) {
257 1794 100         if (SvROK(sv)) {
258 1119           SV *si64 = SvRV(sv);
259 1119 50         if (si64 && SvOBJECT(si64)) {
    50          
260             GV *method;
261 1119           HV *stash = SvSTASH(si64);
262 1119 50         char const * classname = HvNAME_get(stash);
    50          
    50          
    0          
    50          
    50          
263 1119 100         if (memcmp(classname, "Math::", 6) == 0) {
264             int u;
265 1117 100         if (classname[6] == 'U') {
266 4           u = 1;
267 4           classname += 7;
268             }
269             else {
270 1113           u = 0;
271 1113           classname += 6;
272             }
273 1117 50         if (memcmp(classname, "Int64", 6) == 0) {
274 1117 50         if (SvTYPE(si64) < SVt_I64)
275 0 0         Perl_croak(aTHX_ "Wrong internal representation for %s object", HvNAME_get(stash));
    0          
    0          
    0          
    0          
    0          
276 1117 100         if (u) {
277 4           uint64_t u = *(uint64_t*)(&(SvI64Y(si64)));
278 4 100         if (may_die_on_overflow && (u > INT64_MAX)) overflow(aTHX_ out_of_bounds_error_s);
    100          
279 3           return u;
280             }
281             else {
282 1113           return *(int64_t*)(&(SvI64Y(si64)));
283             }
284             }
285             }
286 2           method = gv_fetchmethod(stash, "as_int64");
287 2 50         if (method) {
288             SV *result;
289             int count;
290 2           dSP;
291 2           ENTER;
292 2           SAVETMPS;
293 2           PUSHSTACKi(PERLSI_MAGIC);
294 2 50         PUSHMARK(SP);
295 2 50         XPUSHs(sv);
296 2           PUTBACK;
297 2           count = perl_call_sv( (SV*)method, G_SCALAR );
298 2           SPAGAIN;
299 2 50         if (count != 1)
300 0           Perl_croak(aTHX_ "internal error: method call returned %d values, 1 expected", count);
301 2           result = newSVsv(POPs);
302 2           PUTBACK;
303 2           POPSTACK;
304 2           SPAGAIN;
305 2 50         FREETMPS;
306 2           LEAVE;
307 2           return SvI64(aTHX_ sv_2mortal(result));
308             }
309             }
310             }
311             else {
312 675           SvGETMAGIC(sv);
313 675 100         if (SvIOK(sv)) {
314 587 50         if (SvIOK_UV(sv)) {
315 0           UV uv = SvUV(sv);
316 0 0         if (may_die_on_overflow &&
317 0 0         (uv > INT64_MAX)) overflow(aTHX_ out_of_bounds_error_s);
318 0           return uv;
319             }
320 587           return SvIV(sv);
321             }
322 88 100         if (SvNOK(sv)) {
323 16           NV nv = SvNV(sv);
324 16 100         if ( may_die_on_overflow &&
    100          
325 13 100         ((nv >= NV_0x1p63) || (nv < -NV_0x1p63)) ) overflow(aTHX_ out_of_bounds_error_s);
326 11           return nv;
327             }
328             }
329 72           return strtoint64(aTHX_ SvPV_nolen(sv), 10, 1);
330             }
331              
332             static uint64_t
333 2654           SvU64(pTHX_ SV *sv) {
334 2654 100         if (SvROK(sv)) {
335 1028           SV *su64 = SvRV(sv);
336 1028 50         if (su64 && SvOBJECT(su64)) {
    50          
337             GV *method;
338 1028           HV *stash = SvSTASH(su64);
339 1028 50         char const * classname = HvNAME_get(stash);
    50          
    50          
    0          
    50          
    50          
340 1028 100         if (memcmp(classname, "Math::", 6) == 0) {
341             int u;
342 1026 100         if (classname[6] == 'U') {
343 1025           u = 1;
344 1025           classname += 7;
345             }
346             else {
347 1           u = 0;
348 1           classname += 6;
349             }
350 1026 50         if (memcmp(classname, "Int64", 6) == 0) {
351 1026 50         if (SvTYPE(su64) < SVt_I64)
352 0 0         Perl_croak(aTHX_ "Wrong internal representation for %s object", HvNAME_get(stash));
    0          
    0          
    0          
    0          
    0          
353 1026 100         if (u) {
354 1025           return *(uint64_t*)(&(SvI64Y(su64)));
355             }
356             else {
357 1           int64_t i = *(int64_t*)(&(SvI64Y(su64)));
358 1 50         if (may_die_on_overflow && (i < 0)) overflow(aTHX_ out_of_bounds_error_u);
    0          
359 1           return i;
360             }
361             }
362             }
363 2           method = gv_fetchmethod(SvSTASH(su64), "as_uint64");
364 2 50         if (method) {
365             SV *result;
366             int count;
367 2           dSP;
368 2           ENTER;
369 2           SAVETMPS;
370 2           PUSHSTACKi(PERLSI_MAGIC);
371 2 50         PUSHMARK(SP);
372 2 50         XPUSHs(sv);
373 2           PUTBACK;
374 2           count = perl_call_sv( (SV*)method, G_SCALAR );
375 2           SPAGAIN;
376 2 50         if (count != 1)
377 0           Perl_croak(aTHX_ "internal error: method call returned %d values, 1 expected", count);
378 2           result = newSVsv(POPs);
379 2           PUTBACK;
380 2           POPSTACK;
381 2           SPAGAIN;
382 2 50         FREETMPS;
383 2           LEAVE;
384 2           return SvU64(aTHX_ sv_2mortal(result));
385             }
386             }
387             }
388             else {
389 1626           SvGETMAGIC(sv);
390 1626 100         if (SvIOK(sv)) {
391 1558 100         if (SvIOK_UV(sv)) {
392 3           return SvUV(sv);
393             }
394             else {
395 1555           IV iv = SvIV(sv);
396 1555 100         if (may_die_on_overflow &&
    100          
397 2           (iv < 0) ) overflow(aTHX_ out_of_bounds_error_u);
398 1554           return SvIV(sv);
399             }
400             }
401 68 100         if (SvNOK(sv)) {
402 5           NV nv = SvNV(sv);
403 5 50         if (may_die_on_overflow &&
    50          
404 5 100         ( (nv < 0) || (nv >= NV_0x1p64)) ) overflow(aTHX_ out_of_bounds_error_u);
405 3           return NV2U64(nv);
406             }
407             }
408 63           return strtoint64(aTHX_ SvPV_nolen(sv), 10, 0);
409             }
410              
411             static SV *
412 1           si64_to_number(pTHX_ SV *sv) {
413 1           int64_t i64 = SvI64(aTHX_ sv);
414 1 50         if (i64 < 0) {
415 0           IV iv = i64;
416 0 0         if (iv == i64)
417 0           return newSViv(iv);
418             }
419             else {
420 1           UV uv = i64;
421 1 50         if (uv == i64)
422 1           return newSVuv(uv);
423             }
424 0           return newSVnv(i64);
425             }
426              
427             static SV *
428 2           su64_to_number(pTHX_ SV *sv) {
429 2           uint64_t u64 = SvU64(aTHX_ sv);
430 2           UV uv = u64;
431 2 50         if (uv == u64)
432 2           return newSVuv(uv);
433 0           return newSVnv(U642NV(u64));
434             }
435              
436             #define I64STRLEN 65
437              
438             static SV *
439 4437           u64_to_string_with_sign(pTHX_ uint64_t u64, int base, int sign) {
440             char str[I64STRLEN];
441 4437           int len = 0;
442 4437 50         if ((base > 36) || (base < 2))
    50          
443 0           Perl_croak(aTHX_ "base %d out of range [2,36]", base);
444 74455 100         while (u64) {
445 70018           char c = u64 % base;
446 70018           u64 /= base;
447 70018 100         str[len++] = c + (c > 9 ? 'A' - 10 : '0');
448             }
449 4437 100         if (len) {
450             int i;
451 4432           int svlen = len + (sign ? 1 : 0);
452 4432           SV *sv = newSV(svlen);
453 4432           char *pv = SvPVX(sv);
454 4432           SvPOK_on(sv);
455 4432           SvCUR_set(sv, svlen);
456 4432 100         if (sign) *(pv++) = '-';
457 74450 100         for (i = len; i--;) *(pv++) = str[i];
458 4432           *pv = '\0';
459 4432           return sv;
460             }
461             else {
462 5           return newSVpvs("0");
463             }
464             }
465              
466             static SV *
467 2306           i64_to_string(pTHX_ int64_t i64, int base) {
468 2306 100         if (i64 < 0) {
469 645           return u64_to_string_with_sign(aTHX_ -i64, base, 1);
470             }
471 1661           return u64_to_string_with_sign(aTHX_ i64, base, 0);
472             }
473              
474             static uint64_t
475 0           randU64(pTHX) {
476             dMY_CXT;
477 0           return rand64(&(MY_CXT.is));
478             }
479              
480             static void
481 8           mul_check_overflow(pTHX_ uint64_t a, uint64_t b, const char *error_str) {
482 8 100         if (a < b) {
483 3           uint64_t tmp = a;
484 3           a = b; b = tmp;
485             }
486 8 100         if (b > UINT32_MAX) overflow(aTHX_ error_str);
487             else {
488             uint64_t rl, rh;
489 6           rl = (a & UINT32_MAX) * b;
490 6           rh = (a >> 32) * b + (rl >> 32);
491 6 100         if (rh > UINT32_MAX) overflow(aTHX_ error_str);
492             }
493 5           }
494              
495             static uint64_t
496 558           powU64(pTHX_ uint64_t a, uint64_t b) {
497             uint64_t r;
498 558           int mdoo = may_die_on_overflow;
499 558 100         if (b == 0) return 1;
500 542 100         if (b == 1) return a;
501 529 100         if (b == 2) {
502 14 50         if (mdoo && (a > UINT32_MAX)) overflow(aTHX_ pow_error);
    0          
503 14           return a*a;
504             }
505 515 100         if (a == 0) return 0;
506 513 100         if (a == 1) return 1;
507 509 100         if (a == 2) {
508 442 100         if (b > 63) {
509 2 100         if (mdoo) overflow(aTHX_ pow_error);
510 1           return 0;
511             }
512 440           return (((uint64_t)1) << b);
513             }
514 67 100         if (mdoo) {
515 2 50         r = ((b & 1) ? a : 1);
516 3 100         while ((b >>= 1)) {
517 2 50         if (a > UINT32_MAX) overflow(aTHX_ pow_error);
518 2           a *= a;
519 2 50         if (b & 1) {
520 2           mul_check_overflow(aTHX_ r, a, pow_error);
521 1           r *= a;
522             }
523             }
524             }
525             else {
526 65           r = 1;
527 396 100         while (b) {
528 331 100         if (b & 1) r *= a;
529 331           a *= a;
530 331           b >>= 1;
531             }
532             }
533 66           return r;
534             }
535              
536             static SV *
537 359           uint64_to_BER(pTHX_ uint64_t a) {
538             char buffer[10];
539 359           char *top = buffer + sizeof(buffer);
540 359           char *p = top;
541 359           *(--p) = (a & 0x7f);
542 3396 100         while ((a >>= 7)) {
543 3037           *(--p) = (a & 0x7f) | 0x80;
544              
545             }
546 359           return newSVpvn(p, top - p);
547             }
548              
549             static SV *
550 208           int64_to_BER(pTHX_ int64_t a) {
551 416 100         return uint64_to_BER(aTHX_
552             a < 0
553 93           ? ( ( ( ~(uint64_t)a) << 1 ) | 1 )
554 115           : ( ( ( (uint64_t)a) << 1 ) | 0 ) );
555             }
556              
557             static uint64_t
558 357           BER_to_uint64(pTHX_ SV *sv) {
559             STRLEN len;
560 357           char *pv = SvPVbyte(sv, len);
561             uint64_t a;
562             IV i;
563 3378 50         for (i = 0, a = 0; i < len; i++) {
564 3378 50         if (may_die_on_overflow && (a > (((uint64_t)1) << (63 - 7))))
    0          
565 0           overflow(aTHX_ out_of_bounds_error_u);
566 3378           a = (a << 7) | (pv[i] & 0x7f);
567 3378 100         if ((pv[i] & 0x80) == 0) {
568 357 50         if (i + 1 != len) croak_string(aTHX_ invalid_BER_error);
569 357           return a;
570             }
571             }
572 0           croak_string(aTHX_ invalid_BER_error);
573 0           return 0; /* this dead code is a workaround for OpenWatcom */
574             }
575              
576             static int64_t
577 207           BER_to_int64(pTHX_ SV *sv) {
578 207           uint64_t a = BER_to_uint64(aTHX_ sv);
579 207           int64_t b = (int64_t)(a >> 1);
580 207 100         return (a & 1 ? ~b : b);
581             }
582              
583             static IV
584 106           BER_length(pTHX_ SV *sv) {
585             STRLEN len;
586 106           char *pv = SvPVbyte(sv, len);
587             IV i;
588 998 50         for (i = 0; i < len; i++) {
589 998 100         if ((pv[i] & 0x80) == 0) return i + 1;
590             }
591 0           return -1;
592             }
593              
594             #include "c_api.h"
595              
596             MODULE = Math::Int64 PACKAGE = Math::Int64 PREFIX=miu64_
597             PROTOTYPES: DISABLE
598              
599             BOOT:
600             {
601             MY_CXT_INIT;
602 9           randinit(&(MY_CXT.is), 0);
603 9           may_die_on_overflow = 0;
604 9           may_use_native = 0;
605 9           INIT_C_API;
606             }
607              
608             char *
609             miu64__backend()
610             CODE:
611 5           RETVAL = BACKEND;
612             OUTPUT:
613             RETVAL
614              
615             void
616             miu64__set_may_die_on_overflow(v)
617             int v
618             CODE:
619 1           may_die_on_overflow = v;
620              
621             void
622             miu64__set_may_use_native(v)
623             int v;
624             CODE:
625 2           may_use_native = v;
626              
627             SV *
628             miu64_int64(value=&PL_sv_undef)
629             SV *value;
630             CODE:
631 243 50         RETVAL = (use_native
632 4           ? newSViv(SvIV(value))
633 249 100         : newSVi64(aTHX_ SvI64(aTHX_ value)));
634             OUTPUT:
635             RETVAL
636              
637             SV *
638             miu64_uint64(value=&PL_sv_undef)
639             SV *value;
640             CODE:
641 276 50         RETVAL = (use_native
642 3           ? newSVuv(SvUV(value))
643 280 100         : newSVu64(aTHX_ SvU64(aTHX_ value)));
644             OUTPUT:
645             RETVAL
646              
647             SV *
648             miu64_int64_to_number(self)
649             SV *self
650             CODE:
651 0           RETVAL = si64_to_number(aTHX_ self);
652             OUTPUT:
653             RETVAL
654              
655             SV *
656             miu64_uint64_to_number(self)
657             SV *self
658             CODE:
659 1           RETVAL = su64_to_number(aTHX_ self);
660             OUTPUT:
661             RETVAL
662              
663             SV *
664             miu64_net_to_int64(net)
665             SV *net;
666             PREINIT:
667             STRLEN len;
668 58           unsigned char *pv = (unsigned char *)SvPVbyte(net, len);
669             int64_t i64;
670             CODE:
671 58 50         if (len != 8) croak_string(aTHX_ invalid_length_error_s);
672 58           i64 = (((((((((((((((int64_t)pv[0]) << 8)
673 58           + (int64_t)pv[1]) << 8)
674 58           + (int64_t)pv[2]) << 8)
675 58           + (int64_t)pv[3]) << 8)
676 58           + (int64_t)pv[4]) << 8)
677 58           + (int64_t)pv[5]) << 8)
678 58           + (int64_t)pv[6]) <<8)
679 58           + (int64_t)pv[7];
680 61 50         RETVAL = ( use_native
681 3           ? newSViv(i64)
682 58 100         : newSVi64(aTHX_ i64) );
683             OUTPUT:
684             RETVAL
685              
686             SV *
687             miu64_net_to_uint64(net)
688             SV *net;
689             PREINIT:
690             STRLEN len;
691 56           unsigned char *pv = (unsigned char *)SvPVbyte(net, len);
692             uint64_t u64;
693             CODE:
694 56 50         if (len != 8)
695 0           croak_string(aTHX_ invalid_length_error_u);
696 56           u64 = (((((((((((((((uint64_t)pv[0]) << 8)
697 56           + (uint64_t)pv[1]) << 8)
698 56           + (uint64_t)pv[2]) << 8)
699 56           + (uint64_t)pv[3]) << 8)
700 56           + (uint64_t)pv[4]) << 8)
701 56           + (uint64_t)pv[5]) << 8)
702 56           + (uint64_t)pv[6]) <<8)
703 56           + (uint64_t)pv[7];
704 56 0         RETVAL = ( use_native
705 0           ? newSVuv(u64)
706 56 50         : newSVu64(aTHX_ u64) );
707             OUTPUT:
708             RETVAL
709              
710             SV *
711             miu64_le_to_int64(net)
712             SV *net;
713             PREINIT:
714             STRLEN len;
715 1           unsigned char *pv = (unsigned char *)SvPVbyte(net, len);
716             int64_t i64;
717             CODE:
718 1 50         if (len != 8) croak_string(aTHX_ invalid_length_error_s);
719 1           i64 = (((((((((((((((int64_t)pv[7]) << 8)
720 1           + (int64_t)pv[6]) << 8)
721 1           + (int64_t)pv[5]) << 8)
722 1           + (int64_t)pv[4]) << 8)
723 1           + (int64_t)pv[3]) << 8)
724 1           + (int64_t)pv[2]) << 8)
725 1           + (int64_t)pv[1]) <<8)
726 1           + (int64_t)pv[0];
727 1 0         RETVAL = ( use_native
728 0           ? newSViv(i64)
729 1 50         : newSVi64(aTHX_ i64) );
730             OUTPUT:
731             RETVAL
732              
733             SV *
734             miu64_le_to_uint64(net)
735             SV *net;
736             PREINIT:
737             STRLEN len;
738 0           unsigned char *pv = (unsigned char *)SvPVbyte(net, len);
739             uint64_t u64;
740             CODE:
741 0 0         if (len != 8)
742 0           croak_string(aTHX_ invalid_length_error_u);
743 0           u64 = (((((((((((((((uint64_t)pv[7]) << 8)
744 0           + (uint64_t)pv[6]) << 8)
745 0           + (uint64_t)pv[5]) << 8)
746 0           + (uint64_t)pv[4]) << 8)
747 0           + (uint64_t)pv[3]) << 8)
748 0           + (uint64_t)pv[2]) << 8)
749 0           + (uint64_t)pv[1]) <<8)
750 0           + (uint64_t)pv[0];
751 0 0         RETVAL = ( use_native
752 0           ? newSVuv(u64)
753 0 0         : newSVu64(aTHX_ u64) );
754             OUTPUT:
755             RETVAL
756              
757             SV *
758             miu64_int64_to_net(self)
759             SV *self
760             PREINIT:
761             char *pv;
762 57           int64_t i64 = SvI64(aTHX_ self);
763             int i;
764             CODE:
765 57           RETVAL = newSV(8);
766 57           SvPOK_on(RETVAL);
767 57           SvCUR_set(RETVAL, 8);
768 57           pv = SvPVX(RETVAL);
769 57           pv[8] = '\0';
770 513 100         for (i = 7; i >= 0; i--, i64 >>= 8)
771 456           pv[i] = i64;
772             OUTPUT:
773             RETVAL
774              
775             SV *
776             miu64_uint64_to_net(self)
777             SV *self
778             PREINIT:
779             char *pv;
780 56           uint64_t u64 = SvU64(aTHX_ self);
781             int i;
782             CODE:
783 56           RETVAL = newSV(8);
784 56           SvPOK_on(RETVAL);
785 56           SvCUR_set(RETVAL, 8);
786 56           pv = SvPVX(RETVAL);
787 56           pv[8] = '\0';
788 504 100         for (i = 7; i >= 0; i--, u64 >>= 8)
789 448           pv[i] = u64;
790             OUTPUT:
791             RETVAL
792              
793             SV *
794             miu64_int64_to_le(self)
795             SV *self
796             PREINIT:
797             char *pv;
798 2           int64_t i64 = SvI64(aTHX_ self);
799             int i;
800             CODE:
801 2           RETVAL = newSV(8);
802 2           SvPOK_on(RETVAL);
803 2           SvCUR_set(RETVAL, 8);
804 2           pv = SvPVX(RETVAL);
805 2           pv[8] = '\0';
806 18 100         for (i = 0; i <= 7; i++, i64 >>= 8)
807 16           pv[i] = i64;
808             OUTPUT:
809             RETVAL
810              
811             SV *
812             miu64_uint64_to_le(self)
813             SV *self
814             PREINIT:
815             char *pv;
816 0           uint64_t u64 = SvU64(aTHX_ self);
817             int i;
818             CODE:
819 0           RETVAL = newSV(8);
820 0           SvPOK_on(RETVAL);
821 0           SvCUR_set(RETVAL, 8);
822 0           pv = SvPVX(RETVAL);
823 0           pv[8] = '\0';
824 0 0         for (i = 0; i <= 7; i++, u64 >>= 8)
825 0           pv[i] = u64;
826             OUTPUT:
827             RETVAL
828              
829             SV *
830             miu64_BER_to_int64(ber)
831             SV *ber
832             CODE:
833 107           RETVAL = newSVi64(aTHX_ BER_to_int64(aTHX_ ber));
834             OUTPUT:
835             RETVAL
836              
837             SV *
838             miu64_BER_to_uint64(ber)
839             SV *ber
840             CODE:
841 50           RETVAL = newSVu64(aTHX_ BER_to_uint64(aTHX_ ber));
842             OUTPUT:
843             RETVAL
844              
845             SV *
846             miu64_int64_to_BER(self)
847             SV *self
848             CODE:
849 108           RETVAL = int64_to_BER(aTHX_ SvI64(aTHX_ self));
850             OUTPUT:
851             RETVAL
852              
853             SV *
854             miu64_uint64_to_BER(self)
855             SV *self
856             CODE:
857 51           RETVAL = uint64_to_BER(aTHX_ SvU64(aTHX_ self));
858             OUTPUT:
859             RETVAL
860              
861             SV *
862             miu64_native_to_int64(native)
863             SV *native
864             PREINIT:
865             STRLEN len;
866 62           char *pv = SvPVbyte(native, len);
867             CODE:
868 62 50         if (len != 8)
869 0           croak_string(aTHX_ invalid_length_error_s);
870 62 100         if (use_native) {
    50          
871 6           RETVAL = newSViv(0);
872 6           Copy(pv, &(SvIVX(RETVAL)), 8, char);
873             }
874             else {
875 56           RETVAL = newSVi64(aTHX_ 0);
876 56           Copy(pv, &(SvI64X(RETVAL)), 8, char);
877             }
878             OUTPUT:
879             RETVAL
880              
881             SV *
882             BER_length(sv)
883             SV *sv
884             PREINIT:
885             IV len;
886             CODE:
887 106           len = BER_length(aTHX_ sv);
888 106 50         RETVAL = (len < 0 ? &PL_sv_undef : newSViv(len));
889             OUTPUT:
890             RETVAL
891              
892             SV *
893             miu64_native_to_uint64(native)
894             SV *native
895             PREINIT:
896             STRLEN len;
897 56           char *pv = SvPVbyte(native, len);
898             CODE:
899 56 50         if (len != 8)
900 0           croak_string(aTHX_ invalid_length_error_u);
901 56 50         if (use_native) {
    0          
902             uint64_t tmp;
903 0           Copy(pv, &tmp, 8, char);
904 0           RETVAL = newSVuv(tmp);
905             }
906             else {
907 56           RETVAL = newSVu64(aTHX_ 0);
908 56           Copy(pv, &(SvU64X(RETVAL)), 8, char);
909             }
910             OUTPUT:
911             RETVAL
912              
913             SV *
914             miu64_int64_to_native(self)
915             SV *self
916             PREINIT:
917             char *pv;
918 62           int64_t i64 = SvI64(aTHX_ self);
919             CODE:
920 62           RETVAL = newSV(9);
921 62           SvPOK_on(RETVAL);
922 62           SvCUR_set(RETVAL, 8);
923 62           pv = SvPVX(RETVAL);
924 62           Copy(&i64, pv, 8, char);
925 62           pv[8] = '\0';
926             OUTPUT:
927             RETVAL
928              
929             SV *
930             miu64_uint64_to_native(self)
931             SV *self
932             PREINIT:
933             char *pv;
934 56           uint64_t u64 = SvU64(aTHX_ self);
935             CODE:
936 56           RETVAL = newSV(9);
937 56           SvPOK_on(RETVAL);
938 56           SvCUR_set(RETVAL, 8);
939 56           pv = SvPVX(RETVAL);
940 56           Copy(&u64, pv, 8, char);
941 56           pv[8] = '\0';
942             OUTPUT:
943             RETVAL
944              
945             SV *
946             miu64_int64_to_string(self, base = 10)
947             SV *self
948             int base
949             CODE:
950 318           RETVAL = i64_to_string(aTHX_ SvI64(aTHX_ self), base);
951             OUTPUT:
952             RETVAL
953              
954             SV *
955             miu64_uint64_to_string(self, base = 10)
956             SV *self
957             int base
958             CODE:
959 300           RETVAL = u64_to_string_with_sign(aTHX_ SvU64(aTHX_ self), base, 0);
960             OUTPUT:
961             RETVAL
962              
963             SV *
964             miu64_int64_to_hex(self)
965             SV *self
966             CODE:
967 212           RETVAL = i64_to_string(aTHX_ SvI64(aTHX_ self), 16);
968             OUTPUT:
969             RETVAL
970              
971             SV *
972             miu64_uint64_to_hex(self)
973             SV *self
974             CODE:
975 200           RETVAL = u64_to_string_with_sign(aTHX_ SvU64(aTHX_ self), 16, 0);
976             OUTPUT:
977             RETVAL
978              
979             SV *
980             miu64_string_to_int64(str, base = 0)
981             const char *str;
982             int base;
983             CODE:
984 344 0         RETVAL = ( use_native
985 0           ? newSViv(strtoint64(aTHX_ str, base, 1))
986 344 50         : newSVi64(aTHX_ strtoint64(aTHX_ str, base, 1)) );
987             OUTPUT:
988             RETVAL
989              
990             SV *
991             miu64_string_to_uint64(str, base = 0)
992             const char *str;
993             int base;
994             CODE:
995 315 0         RETVAL = ( use_native
996 0           ? newSVuv(strtoint64(aTHX_ str, base, 0))
997 315 50         : newSVu64(aTHX_ strtoint64(aTHX_ str, base, 0)) );
998             OUTPUT:
999             RETVAL
1000              
1001             SV *
1002             miu64_hex_to_int64(str)
1003             const char *str;
1004             CODE:
1005 53 0         RETVAL = ( use_native
1006 0           ? newSViv(strtoint64(aTHX_ str, 16, 1))
1007 53 50         : newSVi64(aTHX_ strtoint64(aTHX_ str, 16, 1)) );
1008             OUTPUT:
1009             RETVAL
1010              
1011             SV *
1012             miu64_hex_to_uint64(str)
1013             const char *str;
1014             CODE:
1015 50 0         RETVAL = ( use_native
1016 0           ? newSVuv(strtoint64(aTHX_ str, 16, 0))
1017 50 50         : newSVu64(aTHX_ strtoint64(aTHX_ str, 16, 0)) );
1018             OUTPUT:
1019             RETVAL
1020              
1021              
1022             SV *
1023             miu64_int64_rand()
1024             PREINIT:
1025             dMY_CXT;
1026 150           int64_t i64 = rand64(&(MY_CXT.is));
1027             CODE:
1028 150 0         RETVAL = ( use_native
1029 0           ? newSViv(i64)
1030 150 50         : newSVi64(aTHX_ i64) );
1031             OUTPUT:
1032             RETVAL
1033              
1034             SV *
1035             miu64_uint64_rand()
1036             PREINIT:
1037             dMY_CXT;
1038 150           uint64_t u64 = rand64(&(MY_CXT.is));
1039             CODE:
1040 150 0         RETVAL = ( use_native
1041 0           ? newSViv(u64)
1042 150 50         : newSVu64(aTHX_ u64) );
1043             OUTPUT:
1044             RETVAL
1045              
1046             void
1047             miu64_int64_srand(seed=&PL_sv_undef)
1048             SV *seed
1049             PREINIT:
1050             dMY_CXT;
1051             isaac64_state_t *is;
1052             CODE:
1053 0           is = &(MY_CXT.is);
1054 0 0         if (SvOK(seed) && SvCUR(seed)) {
    0          
1055             STRLEN len;
1056 0           const char *pv = SvPV_const(seed, len);
1057 0           char *shadow = (char*)is->randrsl;
1058             int i;
1059 0 0         if (len > sizeof(is->randrsl)) len = sizeof(is->randrsl);
1060 0           Zero(shadow, sizeof(is->randrsl), char);
1061 0           Copy(pv, shadow, len, char);
1062              
1063             /* make the seed endianness agnostic */
1064 0 0         for (i = 0; i < RANDSIZ; i++) {
1065 0           char *p = shadow + i * sizeof(uint64_t);
1066 0           is->randrsl[i] = (((((((((((((((uint64_t)p[0]) << 8) + p[1]) << 8) + p[2]) << 8) + p[3]) << 8) +
1067 0           p[4]) << 8) + p[5]) << 8) + p[6]) << 8) + p[7];
1068             }
1069 0           randinit(is, 1);
1070             }
1071             else
1072 0           randinit(is, 0);
1073              
1074             MODULE = Math::Int64 PACKAGE = Math::Int64 PREFIX=mi64
1075             PROTOTYPES: DISABLE
1076              
1077             SV *
1078             mi64_inc(self, other = NULL, rev = NULL)
1079             SV *self
1080             SV *other = NO_INIT
1081             SV *rev = NO_INIT
1082             CODE:
1083 2 50         if (may_die_on_overflow && (SvI64x(self) == INT64_MAX)) overflow(aTHX_ inc_error);
    50          
1084 1           SvI64x(self)++;
1085 1           RETVAL = self;
1086 1           SvREFCNT_inc(RETVAL);
1087             OUTPUT:
1088             RETVAL
1089              
1090             SV *
1091             mi64_dec(self, other = NULL, rev = NULL)
1092             SV *self
1093             SV *other = NO_INIT
1094             SV *rev = NO_INIT
1095             CODE:
1096 2 50         if (may_die_on_overflow && (SvI64x(self) == INT64_MIN)) overflow(aTHX_ dec_error);
    50          
1097 1           SvI64x(self)--;
1098 1           RETVAL = self;
1099 1           SvREFCNT_inc(RETVAL);
1100             OUTPUT:
1101             RETVAL
1102              
1103             SV *
1104             mi64_add(self, other, rev = &PL_sv_no)
1105             SV *self
1106             SV *other
1107             SV *rev
1108             PREINIT:
1109 13           int64_t a = SvI64x(self);
1110 13           int64_t b = SvI64(aTHX_ other);
1111             CODE:
1112 15 100         if ( may_die_on_overflow &&
    50          
    50          
1113             ( a > 0
1114 2 50         ? ( (b > 0) && (INT64_MAX - a < b) )
    50          
1115 2 0         : ( (b < 0) && (INT64_MIN - a > b) ) ) ) overflow(aTHX_ add_error);
    0          
1116 12 100         if (SvOK(rev))
1117 11           RETVAL = newSVi64(aTHX_ a + b);
1118             else {
1119 1           RETVAL = self;
1120 1           SvREFCNT_inc(RETVAL);
1121 1           SvI64x(self) = a + b;
1122             }
1123             OUTPUT:
1124             RETVAL
1125              
1126             SV *
1127             mi64_sub(self, other, rev = &PL_sv_no)
1128             SV *self
1129             SV *other
1130             SV *rev
1131             PREINIT:
1132 10           int64_t a = SvI64x(self);
1133 10           int64_t b = SvI64(aTHX_ other);
1134             CODE:
1135 10 50         if (SvTRUE(rev)) {
1136 0           int64_t tmp = a;
1137 0           a = b; b = tmp;
1138             }
1139 12 100         if ( may_die_on_overflow &&
    50          
    50          
1140             ( a > 0
1141 0 0         ? ( ( b < 0) && (a - INT64_MAX > b) )
    0          
1142 4 50         : ( ( b > 0) && (a - INT64_MIN < b) ) ) ) overflow(aTHX_ sub_error);
    50          
1143 9 100         if (SvOK(rev))
1144 8           RETVAL = newSVi64(aTHX_ a - b);
1145             else {
1146 1           RETVAL = self;
1147 1           SvREFCNT_inc(RETVAL);
1148 1           SvI64x(self) = a - b;
1149             }
1150             OUTPUT:
1151             RETVAL
1152              
1153             SV *
1154             mi64_mul(self, other, rev = &PL_sv_no)
1155             SV *self
1156             SV *other
1157             SV *rev
1158             PREINIT:
1159 13           int64_t a1 = SvI64x(self);
1160 13           int64_t b1 = SvI64(aTHX_ other);
1161             CODE:
1162 13 50         if (may_die_on_overflow) {
1163 0           int neg = 0;
1164             uint64_t a, b;
1165 0 0         if (a1 < 0) {
1166 0           a = -a1;
1167 0           neg ^= 1;
1168             }
1169 0           else a = a1;
1170 0 0         if (b1 < 0) {
1171 0           b = -b1;
1172 0           neg ^= 1;
1173             }
1174 0           else b = b1;
1175 0           mul_check_overflow(aTHX_ a, b, mul_error);
1176 0 0         if (a * b > (neg ? (~(uint64_t)INT64_MIN + 1) : INT64_MAX)) overflow(aTHX_ mul_error);
    0          
1177             }
1178 13 100         if (SvOK(rev))
1179 12           RETVAL = newSVi64(aTHX_ a1 * b1);
1180             else {
1181 1           RETVAL = self;
1182 1           SvREFCNT_inc(RETVAL);
1183 1           SvI64x(self) = a1 * b1;
1184             }
1185             OUTPUT:
1186             RETVAL
1187              
1188             SV *
1189             mi64_div(self, other, rev = &PL_sv_no)
1190             SV *self
1191             SV *other
1192             SV *rev
1193             PREINIT:
1194             int64_t up;
1195             int64_t down;
1196             CODE:
1197 127 50         if (SvOK(rev)) {
1198 127 50         if (SvTRUE(rev)) {
1199 0           up = SvI64(aTHX_ other);
1200 0           down = SvI64x(self);
1201             }
1202             else {
1203 127           up = SvI64x(self);
1204 127           down = SvI64(aTHX_ other);
1205             }
1206 127 50         if (!down)
1207 0           croak_string(aTHX_ div_by_0_error);
1208 127           RETVAL = newSVi64(aTHX_ up/down);
1209             }
1210             else {
1211 0           down = SvI64(aTHX_ other);
1212 0 0         if (!down)
1213 0           croak_string(aTHX_ div_by_0_error);
1214 0           RETVAL = self;
1215 0           SvREFCNT_inc(RETVAL);
1216 0           SvI64x(self) /= down;
1217             }
1218             OUTPUT:
1219             RETVAL
1220              
1221             SV *
1222             mi64_rest(self, other, rev = &PL_sv_no)
1223             SV *self
1224             SV *other
1225             SV *rev
1226             PREINIT:
1227             int64_t up;
1228             int64_t down;
1229             CODE:
1230 3 100         if (SvOK(rev)) {
1231 2 50         if (SvTRUE(rev)) {
1232 0           up = SvI64(aTHX_ other);
1233 0           down = SvI64x(self);
1234             }
1235             else {
1236 2           up = SvI64x(self);
1237 2           down = SvI64(aTHX_ other);
1238             }
1239 2 50         if (!down)
1240 0           croak_string(aTHX_ div_by_0_error);
1241 2           RETVAL = newSVi64(aTHX_ up % down);
1242             }
1243             else {
1244 1           down = SvI64(aTHX_ other);
1245 1 50         if (!down)
1246 0           croak_string(aTHX_ div_by_0_error);
1247 1           RETVAL = self;
1248 1           SvREFCNT_inc(RETVAL);
1249 1           SvI64x(self) %= down;
1250             }
1251             OUTPUT:
1252             RETVAL
1253              
1254             SV *
1255             mi64_left(self, other, rev = &PL_sv_no)
1256             SV *self
1257             SV *other
1258             SV *rev
1259             PREINIT:
1260             int64_t a, r;
1261             uint64_t b;
1262             CODE:
1263 235 50         if (SvTRUE(rev)) {
1264 0           a = SvI64(aTHX_ other);
1265 0           b = SvU64x(self);
1266             }
1267             else {
1268 235           a = SvI64x(self);
1269 235           b = SvU64(aTHX_ other);
1270             }
1271 235 100         r = (b > 63 ? 0 : a << b);
1272 235 100         if (SvOK(rev))
1273 170           RETVAL = newSVi64(aTHX_ r);
1274             else {
1275 65           RETVAL = SvREFCNT_inc(self);
1276 65           SvI64x(self) = r;
1277             }
1278             OUTPUT:
1279             RETVAL
1280              
1281             SV *mi64_right(self, other, rev = &PL_sv_no)
1282             SV *self
1283             SV *other
1284             SV *rev
1285             PREINIT:
1286             int64_t a, r;
1287             uint64_t b;
1288             CODE:
1289 134 50         if (SvTRUE(rev)) {
1290 0           a = SvI64(aTHX_ other);
1291 0           b = SvU64x(self);
1292             }
1293             else {
1294 134           a = SvI64x(self);
1295 134           b = SvU64(aTHX_ other);
1296             }
1297 134 100         r = (b > 63 ? (a < 0 ? -1 : 0) : a >> b);
    100          
1298 134 100         if (SvOK(rev))
1299 68           RETVAL = newSVi64(aTHX_ r);
1300             else {
1301 66           RETVAL = SvREFCNT_inc(self);
1302 66           SvI64x(self) = r;
1303             }
1304             OUTPUT:
1305             RETVAL
1306              
1307             SV *
1308             mi64_pow(self, other, rev = &PL_sv_no)
1309             SV *self
1310             SV *other
1311             SV *rev
1312             PREINIT:
1313             int sign;
1314             uint64_t r;
1315             int64_t a, b;
1316             CODE:
1317 264 50         if (SvTRUE(rev)) {
1318 0           a = SvI64(aTHX_ other);
1319 0           b = SvI64x(self);
1320             }
1321             else {
1322 264           a = SvI64x(self);
1323 264           b = SvI64(aTHX_ other);
1324             }
1325 264 100         if (a < 0) {
1326 18 100         sign = ((b & 1) ? -1 : 1);
1327 18           a = -a;
1328             }
1329 246           else sign = 1;
1330 264 100         if (b < 0) {
1331 10 100         if (a == 0) croak_string(aTHX_ div_by_0_error);
1332 9 100         else if (a == 1) r = sign;
1333 5           else r = 0;
1334             }
1335             else {
1336 254           uint64_t u = powU64(aTHX_ a, b);
1337 254 100         if (may_die_on_overflow && (u > ((sign < 0) ? (~(uint64_t)INT64_MIN + 1) : INT64_MAX))) overflow(aTHX_ pow_error);
    50          
    50          
1338 253 100         r = ((sign > 0) ? u : -u);
1339             }
1340 262 50         if (SvOK(rev))
1341 262           RETVAL = newSVi64(aTHX_ r);
1342             else {
1343 0           RETVAL = self;
1344 0           SvREFCNT_inc(RETVAL);
1345 0           SvI64x(self) = r;
1346             }
1347             OUTPUT:
1348             RETVAL
1349              
1350             int
1351             mi64_spaceship(self, other, rev = &PL_sv_no)
1352             SV *self
1353             SV *other
1354             SV *rev
1355             PREINIT:
1356             int64_t left;
1357             int64_t right;
1358             CODE:
1359 4 50         if (SvTRUE(rev)) {
1360 0           left = SvI64(aTHX_ other);
1361 0           right = SvI64x(self);
1362             }
1363             else {
1364 4           left = SvI64x(self);
1365 4           right = SvI64(aTHX_ other);
1366             }
1367 4 100         RETVAL = (left < right ? -1 : left > right ? 1 : 0);
    50          
1368             OUTPUT:
1369             RETVAL
1370              
1371             SV *
1372             mi64_eqn(self, other, rev = NULL)
1373             SV *self
1374             SV *other
1375             SV *rev = NO_INIT
1376             CODE:
1377 672           RETVAL = ( SvI64x(self) == SvI64(aTHX_ other)
1378             ? &PL_sv_yes
1379 336 50         : &PL_sv_no );
1380             OUTPUT:
1381             RETVAL
1382              
1383             SV *
1384             mi64_nen(self, other, rev = NULL)
1385             SV *self
1386             SV *other
1387             SV *rev = NO_INIT
1388             CODE:
1389 2           RETVAL = ( SvI64x(self) != SvI64(aTHX_ other)
1390             ? &PL_sv_yes
1391 1 50         : &PL_sv_no );
1392             OUTPUT:
1393             RETVAL
1394              
1395             SV *
1396             mi64_gtn(self, other, rev = &PL_sv_no)
1397             SV *self
1398             SV *other
1399             SV *rev
1400             CODE:
1401 2 50         if (SvTRUE(rev))
1402 0 0         RETVAL = SvI64x(self) < SvI64(aTHX_ other) ? &PL_sv_yes : &PL_sv_no;
1403             else
1404 2 100         RETVAL = SvI64x(self) > SvI64(aTHX_ other) ? &PL_sv_yes : &PL_sv_no;
1405             OUTPUT:
1406             RETVAL
1407              
1408             SV *
1409             mi64_ltn(self, other, rev = &PL_sv_no)
1410             SV *self
1411             SV *other
1412             SV *rev
1413             CODE:
1414 2 50         if (SvTRUE(rev))
1415 0 0         RETVAL = SvI64x(self) > SvI64(aTHX_ other) ? &PL_sv_yes : &PL_sv_no;
1416             else
1417 2 100         RETVAL = SvI64x(self) < SvI64(aTHX_ other) ? &PL_sv_yes : &PL_sv_no;
1418             OUTPUT:
1419             RETVAL
1420              
1421             SV *
1422             mi64_gen(self, other, rev = &PL_sv_no)
1423             SV *self
1424             SV *other
1425             SV *rev
1426             CODE:
1427 3 50         if (SvTRUE(rev))
1428 0 0         RETVAL = SvI64x(self) <= SvI64(aTHX_ other) ? &PL_sv_yes : &PL_sv_no;
1429             else
1430 3 100         RETVAL = SvI64x(self) >= SvI64(aTHX_ other) ? &PL_sv_yes : &PL_sv_no;
1431             OUTPUT:
1432             RETVAL
1433              
1434             SV *
1435             mi64_len(self, other, rev = &PL_sv_no)
1436             SV *self
1437             SV *other
1438             SV *rev
1439             CODE:
1440 3 50         if (SvTRUE(rev))
1441 0 0         RETVAL = SvI64x(self) >= SvI64(aTHX_ other) ? &PL_sv_yes : &PL_sv_no;
1442             else
1443 3 100         RETVAL = SvI64x(self) <= SvI64(aTHX_ other) ? &PL_sv_yes : &PL_sv_no;
1444             OUTPUT:
1445             RETVAL
1446              
1447             SV *
1448             mi64_and(self, other, rev = &PL_sv_no)
1449             SV *self
1450             SV *other
1451             SV *rev
1452             CODE:
1453 5 50         if (SvOK(rev))
1454 5           RETVAL = newSVi64(aTHX_ SvI64x(self) & SvI64(aTHX_ other));
1455             else {
1456 0           RETVAL = self;
1457 0           SvREFCNT_inc(RETVAL);
1458 0           SvI64x(self) &= SvI64(aTHX_ other);
1459             }
1460             OUTPUT:
1461             RETVAL
1462              
1463             SV *
1464             mi64_or(self, other, rev = &PL_sv_no)
1465             SV *self
1466             SV *other
1467             SV *rev
1468             CODE:
1469 1 50         if (SvOK(rev))
1470 1           RETVAL = newSVi64(aTHX_ SvI64x(self) | SvI64(aTHX_ other));
1471             else {
1472 0           RETVAL = self;
1473 0           SvREFCNT_inc(RETVAL);
1474 0           SvI64x(self) |= SvI64(aTHX_ other);
1475             }
1476             OUTPUT:
1477             RETVAL
1478              
1479             SV *
1480             mi64_xor(self, other, rev = &PL_sv_no)
1481             SV *self
1482             SV *other
1483             SV *rev
1484             CODE:
1485 0 0         if (SvOK(rev))
1486 0           RETVAL = newSVi64(aTHX_ SvI64x(self) ^ SvI64(aTHX_ other));
1487             else {
1488 0           RETVAL = self;
1489 0           SvREFCNT_inc(RETVAL);
1490 0           SvI64x(self) ^= SvI64(aTHX_ other);
1491             }
1492             OUTPUT:
1493             RETVAL
1494              
1495             SV *
1496             mi64_not(self, other = NULL, rev = NULL)
1497             SV *self
1498             SV *other = NO_INIT
1499             SV *rev = NO_INIT
1500             CODE:
1501 0 0         RETVAL = SvI64x(self) ? &PL_sv_no : &PL_sv_yes;
1502             OUTPUT:
1503             RETVAL
1504              
1505             SV *
1506             mi64_bnot(self, other = NULL, rev = NULL)
1507             SV *self
1508             SV *other = NO_INIT
1509             SV *rev = NO_INIT
1510             CODE:
1511 0           RETVAL = newSVi64(aTHX_ ~SvI64x(self));
1512             OUTPUT:
1513             RETVAL
1514              
1515             SV *
1516             mi64_neg(self, other = NULL, rev = NULL)
1517             SV *self
1518             SV *other = NO_INIT
1519             SV *rev = NO_INIT
1520             CODE:
1521 2           RETVAL = newSVi64(aTHX_ -SvI64x(self));
1522             OUTPUT:
1523             RETVAL
1524              
1525             SV *
1526             mi64_bool(self, other = NULL, rev = NULL)
1527             SV *self
1528             SV *other = NO_INIT
1529             SV *rev = NO_INIT
1530             CODE:
1531 0 0         RETVAL = SvI64x(self) ? &PL_sv_yes : &PL_sv_no;
1532             OUTPUT:
1533             RETVAL
1534              
1535             SV *
1536             mi64_number(self, other = NULL, rev = NULL)
1537             SV *self
1538             SV *other = NO_INIT
1539             SV *rev = NO_INIT
1540             CODE:
1541 1           RETVAL = si64_to_number(aTHX_ self);
1542             OUTPUT:
1543             RETVAL
1544              
1545             SV *
1546             mi64_clone(self, other = NULL, rev = NULL)
1547             SV *self
1548             SV *other = NO_INIT
1549             SV *rev = NO_INIT
1550             CODE:
1551 5           RETVAL = newSVi64(aTHX_ SvI64x(self));
1552             OUTPUT:
1553             RETVAL
1554              
1555             SV *
1556             mi64_string(self, other = NULL, rev = NULL)
1557             SV *self
1558             SV *other = NO_INIT
1559             SV *rev = NO_INIT
1560             CODE:
1561 1776           RETVAL = i64_to_string(aTHX_ SvI64x(self), 10);
1562             OUTPUT:
1563             RETVAL
1564              
1565             void
1566             mi64STORABLE_thaw(self, cloning, serialized, ...)
1567             SV *self
1568             SV *cloning = NO_INIT
1569             SV *serialized
1570             CODE:
1571 100 50         if (SvROK(self) && sv_isa(self, "Math::Int64")) {
    50          
1572 100           SV *target = SvRV(self);
1573 100           SV *tmp = sv_2mortal(newSVu64(aTHX_ BER_to_int64(aTHX_ serialized)));
1574 100           sv_setsv(target, SvRV(tmp));
1575 100           SvREADONLY_on(target);
1576             }
1577             else
1578 0           croak_string(aTHX_ "Bad object for Math::Int64::STORABLE_thaw call");
1579              
1580             SV *
1581             mi64STORABLE_freeze(self, cloning = NULL)
1582             SV *self
1583             SV *cloning = NO_INIT
1584             CODE:
1585 100           RETVAL = int64_to_BER(aTHX_ SvI64x(self));
1586             OUTPUT:
1587             RETVAL
1588              
1589             MODULE = Math::Int64 PACKAGE = Math::UInt64 PREFIX=mu64
1590             PROTOTYPES: DISABLE
1591              
1592             SV *
1593             mu64_inc(self, other = NULL, rev = NULL)
1594             SV *self
1595             SV *other = NO_INIT
1596             SV *rev = NO_INIT
1597             CODE:
1598 2 50         if (may_die_on_overflow && (SvU64x(self) == UINT64_MAX)) overflow(aTHX_ inc_error);
    50          
1599 1           SvU64x(self)++;
1600 1           RETVAL = SvREFCNT_inc(self);
1601             OUTPUT:
1602             RETVAL
1603              
1604             SV *
1605             mu64_dec(self, other = NULL, rev = NULL)
1606             SV *self
1607             SV *other = NO_INIT
1608             SV *rev = NO_INIT
1609             CODE:
1610 2 50         if (may_die_on_overflow && (SvU64x(self) == 0)) overflow(aTHX_ dec_error);
    50          
1611 1           SvU64x(self)--;
1612 1           RETVAL = SvREFCNT_inc(self);
1613             OUTPUT:
1614             RETVAL
1615              
1616             SV *
1617             mu64_add(self, other, rev = &PL_sv_no)
1618             SV *self
1619             SV *other
1620             SV *rev
1621             PREINIT:
1622             uint64_t a, b;
1623             CODE:
1624 74           a = SvU64x(self);
1625 74           b = SvU64(aTHX_ other);
1626 74 100         if (may_die_on_overflow && (UINT64_MAX - a < b)) overflow(aTHX_ add_error);
    50          
1627 73 100         if (SvOK(rev))
1628 72           RETVAL = newSVu64(aTHX_ a + b);
1629             else {
1630 1           RETVAL = self;
1631 1           SvREFCNT_inc(RETVAL);
1632 1           SvU64x(self) = a + b;
1633             }
1634             OUTPUT:
1635             RETVAL
1636              
1637             SV *
1638             mu64_sub(self, other, rev = &PL_sv_no)
1639             SV *self
1640             SV *other
1641             SV *rev
1642             PREINIT:
1643             uint64_t a, b;
1644             CODE:
1645 73 50         if (SvTRUE(rev)) {
1646 0           a = SvU64(aTHX_ other);
1647 0           b = SvU64x(self);
1648             }
1649             else {
1650 73           a = SvU64x(self);
1651 73           b = SvU64(aTHX_ other);
1652             }
1653 73 100         if (may_die_on_overflow && (b > a)) overflow(aTHX_ sub_error);
    100          
1654 72 100         if (SvOK(rev))
1655 71           RETVAL = newSVu64(aTHX_ a - b);
1656             else {
1657 1           RETVAL = SvREFCNT_inc(self);
1658 1           SvU64x(self) = a - b;
1659             }
1660             OUTPUT:
1661             RETVAL
1662              
1663             SV *
1664             mu64_mul(self, other, rev = &PL_sv_no)
1665             SV *self
1666             SV *other
1667             SV *rev
1668             PREINIT:
1669             uint64_t a, b;
1670             CODE:
1671 83           a = SvU64x(self);
1672 83           b = SvU64(aTHX_ other);
1673 83 100         if (may_die_on_overflow) mul_check_overflow(aTHX_ a, b, mul_error);
1674 81 100         if (SvOK(rev))
1675 80           RETVAL = newSVu64(aTHX_ a * b);
1676             else {
1677 1           RETVAL = SvREFCNT_inc(self);
1678 1           SvU64x(self) = a * b;
1679             }
1680             OUTPUT:
1681             RETVAL
1682              
1683             SV *
1684             mu64_div(self, other, rev = &PL_sv_no)
1685             SV *self
1686             SV *other
1687             SV *rev
1688             PREINIT:
1689             uint64_t up, down;
1690             CODE:
1691 129 50         if (SvOK(rev)) {
1692 129 50         if (SvTRUE(rev)) {
1693 0           up = SvU64(aTHX_ other);
1694 0           down = SvU64x(self);
1695             }
1696             else {
1697 129           up = SvU64x(self);
1698 129           down = SvU64(aTHX_ other);
1699             }
1700 129 50         if (!down)
1701 0           croak_string(aTHX_ div_by_0_error);
1702 129           RETVAL = newSVu64(aTHX_ up/down);
1703             }
1704             else {
1705 0           down = SvU64(aTHX_ other);
1706 0 0         if (!down)
1707 0           croak_string(aTHX_ div_by_0_error);
1708 0           RETVAL = self;
1709 0           SvREFCNT_inc(RETVAL);
1710 0           SvU64x(self) /= down;
1711             }
1712             OUTPUT:
1713             RETVAL
1714              
1715             SV *
1716             mu64_rest(self, other, rev = &PL_sv_no)
1717             SV *self
1718             SV *other
1719             SV *rev
1720             PREINIT:
1721             uint64_t up;
1722             uint64_t down;
1723             CODE:
1724 3 100         if (SvOK(rev)) {
1725 2 50         if (SvTRUE(rev)) {
1726 0           up = SvU64(aTHX_ other);
1727 0           down = SvU64x(self);
1728             }
1729             else {
1730 2           up = SvU64x(self);
1731 2           down = SvU64(aTHX_ other);
1732             }
1733 2 50         if (!down)
1734 0           croak_string(aTHX_ div_by_0_error);
1735 2           RETVAL = newSVu64(aTHX_ up % down);
1736             }
1737             else {
1738 1           down = SvU64(aTHX_ other);
1739 1 50         if (!down)
1740 0           croak_string(aTHX_ div_by_0_error);
1741 1           RETVAL = self;
1742 1           SvREFCNT_inc(RETVAL);
1743 1           SvU64x(self) %= down;
1744             }
1745             OUTPUT:
1746             RETVAL
1747              
1748             SV *mu64_left(self, other, rev = &PL_sv_no)
1749             SV *self
1750             SV *other
1751             SV *rev
1752             PREINIT:
1753             uint64_t a, b, r;
1754             CODE:
1755 236 50         if (SvTRUE(rev)) {
1756 0           a = SvU64(aTHX_ other);
1757 0           b = SvU64x(self);
1758             }
1759             else {
1760 236           a = SvU64x(self);
1761 236           b = SvU64(aTHX_ other);
1762             }
1763 236 100         r = (b > 63 ? 0 : a << b);
1764 236 100         if (SvOK(rev))
1765 172           RETVAL = newSVu64(aTHX_ r);
1766             else {
1767 64           RETVAL = SvREFCNT_inc(self);
1768 64           SvU64x(self) = r;
1769             }
1770             OUTPUT:
1771             RETVAL
1772              
1773             SV *mu64_right(self, other, rev = &PL_sv_no)
1774             SV *self
1775             SV *other
1776             SV *rev
1777             PREINIT:
1778             uint64_t a, b, r;
1779             CODE:
1780 127 50         if (SvTRUE(rev)) {
1781 0           a = SvU64(aTHX_ other);
1782 0           b = SvU64x(self);
1783             }
1784             else {
1785 127           a = SvU64x(self);
1786 127           b = SvU64(aTHX_ other);
1787             }
1788 127 50         r = (b > 63 ? 0 : a >> b);
1789 127 100         if (SvOK(rev))
1790 64           RETVAL = newSVu64(aTHX_ r);
1791             else {
1792 63           RETVAL = SvREFCNT_inc(self);
1793 63           SvU64x(self) = r;
1794             }
1795             OUTPUT:
1796             RETVAL
1797              
1798             SV *
1799             mu64_pow(self, other, rev = &PL_sv_no)
1800             SV *self
1801             SV *other
1802             SV *rev
1803             PREINIT:
1804             uint64_t r;
1805             int64_t a, b;
1806             CODE:
1807 304 50         if (SvTRUE(rev)) {
1808 0           a = SvU64(aTHX_ other);
1809 0           b = SvU64x(self);
1810             }
1811             else {
1812 304           a = SvU64x(self);
1813 304           b = SvU64(aTHX_ other);
1814             }
1815 304           r = powU64(aTHX_ a, b);
1816 302 50         if (SvOK(rev))
1817 302           RETVAL = newSVu64(aTHX_ r);
1818             else {
1819 0           RETVAL = self;
1820 0           SvREFCNT_inc(RETVAL);
1821 0           SvU64x(self) = r;
1822             }
1823             OUTPUT:
1824             RETVAL
1825              
1826             int
1827             mu64_spaceship(self, other, rev = &PL_sv_no)
1828             SV *self
1829             SV *other
1830             SV *rev
1831             PREINIT:
1832             uint64_t left;
1833             uint64_t right;
1834             CODE:
1835 4 50         if (SvTRUE(rev)) {
1836 0           left = SvU64(aTHX_ other);
1837 0           right = SvU64x(self);
1838             }
1839             else {
1840 4           left = SvU64x(self);
1841 4           right = SvU64(aTHX_ other);
1842             }
1843 4 100         RETVAL = (left < right ? -1 : left > right ? 1 : 0);
    50          
1844             OUTPUT:
1845             RETVAL
1846              
1847             SV *
1848             mu64_eqn(self, other, rev = NULL)
1849             SV *self
1850             SV *other
1851             SV *rev = NO_INIT
1852             CODE:
1853 592           RETVAL = ( SvU64x(self) == SvU64(aTHX_ other)
1854             ? &PL_sv_yes
1855 296 50         : &PL_sv_no );
1856             OUTPUT:
1857             RETVAL
1858              
1859             SV *
1860             mu64_nen(self, other, rev = NULL)
1861             SV *self
1862             SV *other
1863             SV *rev = NO_INIT
1864             CODE:
1865 0           RETVAL = ( SvU64x(self) != SvU64(aTHX_ other)
1866             ? &PL_sv_yes
1867 0 0         : &PL_sv_no );
1868             OUTPUT:
1869             RETVAL
1870              
1871             SV *
1872             mu64_gtn(self, other, rev = &PL_sv_no)
1873             SV *self
1874             SV *other
1875             SV *rev
1876             CODE:
1877 2 50         if (SvTRUE(rev))
1878 0 0         RETVAL = SvU64x(self) < SvU64(aTHX_ other) ? &PL_sv_yes : &PL_sv_no;
1879             else
1880 2 100         RETVAL = SvU64x(self) > SvU64(aTHX_ other) ? &PL_sv_yes : &PL_sv_no;
1881             OUTPUT:
1882             RETVAL
1883              
1884             SV *
1885             mu64_ltn(self, other, rev = &PL_sv_no)
1886             SV *self
1887             SV *other
1888             SV *rev
1889             CODE:
1890 2 50         if (SvTRUE(rev))
1891 0 0         RETVAL = SvU64x(self) > SvU64(aTHX_ other) ? &PL_sv_yes : &PL_sv_no;
1892             else
1893 2 100         RETVAL = SvU64x(self) < SvU64(aTHX_ other) ? &PL_sv_yes : &PL_sv_no;
1894             OUTPUT:
1895             RETVAL
1896              
1897             SV *
1898             mu64_gen(self, other, rev = &PL_sv_no)
1899             SV *self
1900             SV *other
1901             SV *rev
1902             CODE:
1903 3 50         if (SvTRUE(rev))
1904 0 0         RETVAL = SvU64x(self) <= SvU64(aTHX_ other) ? &PL_sv_yes : &PL_sv_no;
1905             else
1906 3 100         RETVAL = SvU64x(self) >= SvU64(aTHX_ other) ? &PL_sv_yes : &PL_sv_no;
1907             OUTPUT:
1908             RETVAL
1909              
1910             SV *
1911             mu64_len(self, other, rev = &PL_sv_no)
1912             SV *self
1913             SV *other
1914             SV *rev
1915             CODE:
1916 3 50         if (SvTRUE(rev))
1917 0 0         RETVAL = SvU64x(self) >= SvU64(aTHX_ other) ? &PL_sv_yes : &PL_sv_no;
1918             else
1919 3 100         RETVAL = SvU64x(self) <= SvU64(aTHX_ other) ? &PL_sv_yes : &PL_sv_no;
1920             OUTPUT:
1921             RETVAL
1922              
1923             SV *
1924             mu64_and(self, other, rev = &PL_sv_no)
1925             SV *self
1926             SV *other
1927             SV *rev
1928             CODE:
1929 2 50         if (SvOK(rev))
1930 2           RETVAL = newSVu64(aTHX_ SvU64x(self) & SvU64(aTHX_ other));
1931             else {
1932 0           RETVAL = self;
1933 0           SvREFCNT_inc(RETVAL);
1934 0           SvU64x(self) &= SvU64(aTHX_ other);
1935             }
1936             OUTPUT:
1937             RETVAL
1938              
1939             SV *
1940             mu64_or(self, other, rev = &PL_sv_no)
1941             SV *self
1942             SV *other
1943             SV *rev
1944             CODE:
1945 0 0         if (SvOK(rev))
1946 0           RETVAL = newSVu64(aTHX_ SvU64x(self) | SvU64(aTHX_ other));
1947             else {
1948 0           RETVAL = self;
1949 0           SvREFCNT_inc(RETVAL);
1950 0           SvU64x(self) |= SvU64(aTHX_ other);
1951             }
1952             OUTPUT:
1953             RETVAL
1954              
1955             SV *
1956             mu64_xor(self, other, rev = &PL_sv_no)
1957             SV *self
1958             SV *other
1959             SV *rev
1960             CODE:
1961 0 0         if (SvOK(rev))
1962 0           RETVAL = newSVu64(aTHX_ SvU64x(self) ^ SvU64(aTHX_ other));
1963             else {
1964 0           RETVAL = self;
1965 0           SvREFCNT_inc(RETVAL);
1966 0           SvU64x(self) ^= SvU64(aTHX_ other);
1967             }
1968             OUTPUT:
1969             RETVAL
1970              
1971             SV *
1972             mu64_not(self, other = NULL, rev = NULL)
1973             SV *self
1974             SV *other = NO_INIT
1975             SV *rev = NO_INIT
1976             CODE:
1977 0 0         RETVAL = SvU64x(self) ? &PL_sv_no : &PL_sv_yes;
1978             OUTPUT:
1979             RETVAL
1980              
1981             SV *
1982             mu64_bnot(self, other = NULL, rev = NULL)
1983             SV *self
1984             SV *other = NO_INIT
1985             SV *rev = NO_INIT
1986             CODE:
1987 0           RETVAL = newSVu64(aTHX_ ~SvU64x(self));
1988             OUTPUT:
1989             RETVAL
1990              
1991             SV *
1992             mu64_neg(self, other = NULL, rev = NULL)
1993             SV *self
1994             SV *other = NO_INIT
1995             SV *rev = NO_INIT
1996             CODE:
1997 0           RETVAL = newSVu64(aTHX_ ~(SvU64x(self)-1));
1998             OUTPUT:
1999             RETVAL
2000              
2001             SV *
2002             mu64_bool(self, other = NULL, rev = NULL)
2003             SV *self
2004             SV *other = NO_INIT
2005             SV *rev = NO_INIT
2006             CODE:
2007 0 0         RETVAL = SvU64x(self) ? &PL_sv_yes : &PL_sv_no;
2008             OUTPUT:
2009             RETVAL
2010              
2011             SV *
2012             mu64_number(self, other = NULL, rev = NULL)
2013             SV *self
2014             SV *other = NO_INIT
2015             SV *rev = NO_INIT
2016             CODE:
2017 1           RETVAL = su64_to_number(aTHX_ self);
2018             OUTPUT:
2019             RETVAL
2020              
2021             SV *
2022             mu64_clone(self, other = NULL, rev = NULL)
2023             SV *self
2024             SV *other = NO_INIT
2025             SV *rev = NO_INIT
2026             CODE:
2027 5           RETVAL = newSVu64(aTHX_ SvU64x(self));
2028             OUTPUT:
2029             RETVAL
2030              
2031             SV *
2032             mu64_string(self, other = NULL, rev = NULL)
2033             SV *self
2034             SV *other = NO_INIT
2035             SV *rev = NO_INIT
2036             CODE:
2037 1631           RETVAL = u64_to_string_with_sign(aTHX_ SvU64x(self), 10, 0);
2038             OUTPUT:
2039             RETVAL
2040              
2041             void
2042             mu64STORABLE_thaw(self, cloning, serialized, ...)
2043             SV *self
2044             SV *cloning = NO_INIT
2045             SV *serialized
2046             CODE:
2047 100 50         if (SvROK(self) && sv_isa(self, "Math::UInt64")) {
    50          
2048 100           SV *target = SvRV(self);
2049 100           SV *tmp = sv_2mortal(newSVu64(aTHX_ BER_to_uint64(aTHX_ serialized)));
2050 100           sv_setsv(target, SvRV(tmp));
2051 100           SvREADONLY_on(target);
2052             }
2053             else
2054 0           croak_string(aTHX_ "Bad object for Math::UInt64::STORABLE_thaw call");
2055              
2056             SV *
2057             mu64STORABLE_freeze(self, cloning = NULL)
2058             SV *self
2059             SV *cloning = NO_INIT
2060             CODE:
2061 100           RETVAL = uint64_to_BER(aTHX_ SvU64x(self));
2062             OUTPUT:
2063             RETVAL
2064