#ifdef __MINGW32__ #ifndef __USE_MINGW_ANSI_STDIO #define __USE_MINGW_ANSI_STDIO 1 #endif #endif #define PERL_NO_GET_CONTEXT 1 #include "EXTERN.h" #include "perl.h" #include "XSUB.h" #include <stdlib.h> #ifdef OLDPERL #define SvUOK SvIsUV #endif #ifndef Newx # define Newx(v,n,t) New(0,v,n,t) #endif typedef _Decimal64 D64; long long add_on[54] = {1ll,2ll, 4ll, 8ll, 16ll, 32ll, 64ll, 128ll, 256ll, 512ll, 1024ll, 2048ll, 4096ll, 8192ll, 16384ll, 32768ll, 65536ll, 131072ll, 262144ll, 524288ll, 1048576ll, 2097152ll, 4194304ll, 8388608ll, 16777216ll, 33554432ll, 67108864ll, 134217728ll, 268435456ll, 536870912ll, 1073741824ll, 2147483648ll, 4294967296ll, 8589934592ll, 17179869184ll, 34359738368ll, 68719476736ll, 137438953472ll, 274877906944ll, 549755813888ll, 1099511627776ll, 2199023255552ll, 4398046511104ll, 8796093022208ll, 17592186044416ll, 35184372088832ll, 70368744177664ll, 140737488355328ll, 281474976710656ll, 562949953421312ll, 1125899906842624ll, 2251799813685248ll, 4503599627370496ll, 9007199254740992ll}; int _is_nan(_Decimal64 x) { if(x == x) return 0; return 1; } int _is_inf(_Decimal64 x) { if(x != x) return 0; /* NaN */ if(x == 0.0DD) return 0; /* Zero */ if(x/x != x/x) { if(x < 0.0DD) return -1; else return 1; } return 0; /* Finite Real */ } int _is_neg_zero(_Decimal64 x) { char * buffer; if(x != 0.0DD) return 0; Newx(buffer, 2, char); sprintf(buffer, "%.0f", (double)x); if(strcmp(buffer, "-0")) { Safefree(buffer); return 0; } Safefree(buffer); return 1; } SV * _is_nan_NV(pTHX_ SV * x) { if(SvNV(x) == SvNV(x)) return newSViv(0); return newSViv(1); } SV * _is_inf_NV(pTHX_ SV * x) { if(SvNV(x) != SvNV(x)) return 0; /* NaN */ if(SvNV(x) == 0.0) return newSViv(0); /* Zero */ if(SvNV(x)/SvNV(x) != SvNV(x)/SvNV(x)) { if(SvNV(x) < 0.0) return newSViv(-1); else return newSViv(1); } return newSVnv(0); /* Finite Real */ } SV * _is_neg_zero_NV(pTHX_ SV * x) { char * buffer; if(SvNV(x) != 0.0) return newSViv(0); Newx(buffer, 2, char); sprintf(buffer, "%.0f", (double)SvNV(x)); if(strcmp(buffer, "-0")) { Safefree(buffer); return newSViv(0); } Safefree(buffer); return newSViv(1); } _Decimal64 _get_inf(int sign) { if(sign < 0) return -1.0DD/0.0DD; return 1.0DD/0.0DD; } _Decimal64 _get_nan(void) { _Decimal64 inf = _get_inf(1); return inf/inf; } SV * _DEC64_MAX(pTHX) { _Decimal64 * d64; SV * obj_ref, * obj; Newx(d64, 1, _Decimal64); if(d64 == NULL) croak("Failed to allocate memory in DEC64_MAX function"); obj_ref = newSV(0); obj = newSVrv(obj_ref, "Math::Decimal64"); *d64 = 9999999999999999e369DD; sv_setiv(obj, INT2PTR(IV,d64)); SvREADONLY_on(obj); return obj_ref; } SV * _DEC64_MIN(pTHX) { _Decimal64 * d64; SV * obj_ref, * obj; Newx(d64, 1, _Decimal64); if(d64 == NULL) croak("Failed to allocate memory in DEC64_MIN function"); obj_ref = newSV(0); obj = newSVrv(obj_ref, "Math::Decimal64"); *d64 = 1e-398DD; sv_setiv(obj, INT2PTR(IV,d64)); SvREADONLY_on(obj); return obj_ref; } SV * NaND64(pTHX) { _Decimal64 * d64; SV * obj_ref, * obj; Newx(d64, 1, _Decimal64); if(d64 == NULL) croak("Failed to allocate memory in NaND64 function"); obj_ref = newSV(0); obj = newSVrv(obj_ref, "Math::Decimal64"); *d64 = _get_nan(); sv_setiv(obj, INT2PTR(IV,d64)); SvREADONLY_on(obj); return obj_ref; } SV * InfD64(pTHX_ int sign) { _Decimal64 * d64; SV * obj_ref, * obj; Newx(d64, 1, _Decimal64); if(d64 == NULL) croak("Failed to allocate memory in InfD64 function"); obj_ref = newSV(0); obj = newSVrv(obj_ref, "Math::Decimal64"); *d64 = _get_inf(sign); sv_setiv(obj, INT2PTR(IV,d64)); SvREADONLY_on(obj); return obj_ref; } SV * ZeroD64(pTHX_ int sign) { _Decimal64 * d64; SV * obj_ref, * obj; Newx(d64, 1, _Decimal64); if(d64 == NULL) croak("Failed to allocate memory in ZeroD64 function"); obj_ref = newSV(0); obj = newSVrv(obj_ref, "Math::Decimal64"); *d64 = 0.0DD; if(sign < 0) *d64 *= -1; sv_setiv(obj, INT2PTR(IV,d64)); SvREADONLY_on(obj); return obj_ref; } SV * UnityD64(pTHX_ int sign) { _Decimal64 * d64; SV * obj_ref, * obj; Newx(d64, 1, _Decimal64); if(d64 == NULL) croak("Failed to allocate memory in UnityD64 function"); obj_ref = newSV(0); obj = newSVrv(obj_ref, "Math::Decimal64"); *d64 = 1.0DD; if(sign < 0) *d64 *= -1; sv_setiv(obj, INT2PTR(IV,d64)); SvREADONLY_on(obj); return obj_ref; } SV * Exp10(pTHX_ int power) { _Decimal64 * d64; SV * obj_ref, * obj; /* Remove this condition - and let the value be set to 0 or Inf if(power < -398 || power > 384) croak("Argument supplied to Exp10 function (%d) is out of allowable range", power); */ Newx(d64, 1, _Decimal64); if(d64 == NULL) croak("Failed to allocate memory in Exp10 function"); obj_ref = newSV(0); obj = newSVrv(obj_ref, "Math::Decimal64"); *d64 = 1.0DD; if(power < 0) { while(power < -100) { *d64 *= 1e-100DL; power += 100; } while(power < -10) { *d64 *= 1e-10DL; power += 10; } while(power) { *d64 *= 1e-1DL; power++; } } else { while(power > 100) { *d64 *= 1e100DL; power -= 100; } while(power > 10) { *d64 *= 1e10DL; power -= 10; } while(power) { *d64 *= 1e1DL; power--; } } sv_setiv(obj, INT2PTR(IV,d64)); SvREADONLY_on(obj); return obj_ref; } SV * _testvalD64(pTHX_ int sign) { _Decimal64 * d64; SV * obj_ref, * obj; Newx(d64, 1, _Decimal64); if(d64 == NULL) croak("Failed to allocate memory in _testvalD64 function"); obj_ref = newSV(0); obj = newSVrv(obj_ref, "Math::Decimal64"); *d64 = 9307199254740993e-15DD; if(sign < 0) *d64 *= -1; sv_setiv(obj, INT2PTR(IV,d64)); SvREADONLY_on(obj); return obj_ref; } SV * _MEtoD64(pTHX_ char * mantissa, SV * exponent) { _Decimal64 * d64; SV * obj_ref, * obj; int exp = (int)SvIV(exponent), i; char * ptr; long double man; man = strtold(mantissa, &ptr); Newx(d64, 1, _Decimal64); if(d64 == NULL) croak("Failed to allocate memory in MEtoD64 function"); obj_ref = newSV(0); obj = newSVrv(obj_ref, "Math::Decimal64"); *d64 = (_Decimal64)man; if(exp < 0) { for(i = 0; i > exp; --i) *d64 *= 0.1DD; } else { for(i = 0; i < exp; ++i) *d64 *= 10.0DD; } sv_setiv(obj, INT2PTR(IV,d64)); SvREADONLY_on(obj); return obj_ref; } SV * NVtoD64(pTHX_ SV * x) { _Decimal64 * d64; SV * obj_ref, * obj; Newx(d64, 1, _Decimal64); if(d64 == NULL) croak("Failed to allocate memory in NVtoD64 function"); obj_ref = newSV(0); obj = newSVrv(obj_ref, "Math::Decimal64"); *d64 = (_Decimal64)SvNV(x); sv_setiv(obj, INT2PTR(IV,d64)); SvREADONLY_on(obj); return obj_ref; } SV * UVtoD64(pTHX_ SV * x) { _Decimal64 * d64; SV * obj_ref, * obj; Newx(d64, 1, _Decimal64); if(d64 == NULL) croak("Failed to allocate memory in UVtoD64 function"); obj_ref = newSV(0); obj = newSVrv(obj_ref, "Math::Decimal64"); *d64 = (_Decimal64)SvUV(x); sv_setiv(obj, INT2PTR(IV,d64)); SvREADONLY_on(obj); return obj_ref; } SV * IVtoD64(pTHX_ SV * x) { _Decimal64 * d64; SV * obj_ref, * obj; Newx(d64, 1, _Decimal64); if(d64 == NULL) croak("Failed to allocate memory in IVtoD64 function"); obj_ref = newSV(0); obj = newSVrv(obj_ref, "Math::Decimal64"); *d64 = (_Decimal64)SvIV(x); sv_setiv(obj, INT2PTR(IV,d64)); SvREADONLY_on(obj); return obj_ref; } /* Currently using perl sub of the same name. SV * PVtoD64(pTHX_ char * x) { _Decimal64 * d64; long double temp; char * ptr; SV * obj_ref, * obj; temp = strtold(x, &ptr); Newx(d64, 1, _Decimal64); if(d64 == NULL) croak("Failed to allocate memory in PVtoD64 function"); obj_ref = newSV(0); obj = newSVrv(obj_ref, "Math::Decimal64"); *d64 = (_Decimal64)temp; sv_setiv(obj, INT2PTR(IV,d64)); SvREADONLY_on(obj); return obj_ref; } */ SV * STRtoD64(pTHX_ char * x) { #ifdef STRTOD64_AVAILABLE _Decimal64 * d64; char * ptr; SV * obj_ref, * obj; Newx(d64, 1, _Decimal64); if(d64 == NULL) croak("Failed to allocate memory in STRtoD64 function"); *d64 = strtod64(x, &ptr); obj_ref = newSV(0); obj = newSVrv(obj_ref, "Math::Decimal64"); sv_setiv(obj, INT2PTR(IV,d64)); SvREADONLY_on(obj); return obj_ref; #else croak("The strtod64 function has not been made available"); #endif } int have_strtod64(void) { #ifdef STRTOD64_AVAILABLE return 1; #else return 0; #endif } SV * D64toNV(pTHX_ SV * d64) { return newSVnv((NV)(*(INT2PTR(_Decimal64*, SvIV(SvRV(d64)))))); } void LDtoD64(pTHX_ SV * d64, SV * ld) { if(sv_isobject(d64) && sv_isobject(ld)) { const char *h1 = HvNAME(SvSTASH(SvRV(d64))); const char *h2 = HvNAME(SvSTASH(SvRV(ld))); if(strEQ(h1, "Math::Decimal64") && strEQ(h2, "Math::LongDouble")) { *(INT2PTR(_Decimal64 *, SvIV(SvRV(d64)))) = (_Decimal64)*(INT2PTR(long double *, SvIV(SvRV(ld)))); } else croak("Invalid object supplied to Math::Decimal64::LDtoD64"); } else croak("Invalid argument supplied to Math::Decimal64::LDtoD64"); } void D64toLD(pTHX_ SV * ld, SV * d64) { if(sv_isobject(d64) && sv_isobject(ld)) { const char *h1 = HvNAME(SvSTASH(SvRV(d64))); const char *h2 = HvNAME(SvSTASH(SvRV(ld))); if(strEQ(h1, "Math::Decimal64") && strEQ(h2, "Math::LongDouble")) { *(INT2PTR(long double *, SvIV(SvRV(ld)))) = (long double)*(INT2PTR(_Decimal64 *, SvIV(SvRV(d64)))); } else croak("Invalid object supplied to Math::Decimal64::D64toLD"); } else croak("Invalid argument supplied to Math::Decimal64::D64toLD"); } void DESTROY(pTHX_ SV * rop) { Safefree(INT2PTR(_Decimal64 *, SvIV(SvRV(rop)))); } void _assignME(pTHX_ SV * a, char * mantissa, SV * c) { char * ptr; long double man; int exp = (int)SvIV(c), i; man = strtold(mantissa, &ptr); *(INT2PTR(_Decimal64 *, SvIV(SvRV(a)))) = (_Decimal64)man; if(exp < 0) { for(i = 0; i > exp; --i) *(INT2PTR(_Decimal64 *, SvIV(SvRV(a)))) *= 0.1DD; } else { for(i = 0; i < exp; ++i) *(INT2PTR(_Decimal64 *, SvIV(SvRV(a)))) *= 10.0DD; } } /* Currently using perl sub of the same name void assignPV(pTHX_ SV * a, char * str) { char * ptr; long double man = strtold(str, &ptr); *(INT2PTR(_Decimal64 *, SvIV(SvRV(a)))) = (_Decimal64)man; } */ void assignNaN(pTHX_ SV * a) { if(sv_isobject(a)) { const char * h = HvNAME(SvSTASH(SvRV(a))); if(strEQ(h, "Math::Decimal64")) { *(INT2PTR(_Decimal64 *, SvIV(SvRV(a)))) = _get_nan(); } else croak("Invalid object supplied to Math::Decimal64::assignNaN function"); } else croak("Invalid argument supplied to Math::Decimal64::assignNaN function"); } void assignInf(pTHX_ SV * a, int sign) { if(sv_isobject(a)) { const char * h = HvNAME(SvSTASH(SvRV(a))); if(strEQ(h, "Math::Decimal64")) { *(INT2PTR(_Decimal64 *, SvIV(SvRV(a)))) = _get_inf(sign); } else croak("Invalid object supplied to Math::Decimal64::assignInf function"); } else croak("Invalid argument supplied to Math::Decimal64::assignInf function"); } SV * _overload_add(pTHX_ SV * a, SV * b, SV * third) { _Decimal64 * d64; SV * obj_ref, * obj; Newx(d64, 1, _Decimal64); if(d64 == NULL) croak("Failed to allocate memory in _overload_add function"); obj_ref = newSV(0); obj = newSVrv(obj_ref, "Math::Decimal64"); sv_setiv(obj, INT2PTR(IV,d64)); SvREADONLY_on(obj); if(SvUOK(b)) { *d64 = *(INT2PTR(_Decimal64 *, SvIV(SvRV(a)))) + SvUV(b); return obj_ref; } if(SvIOK(b)) { *d64 = *(INT2PTR(_Decimal64 *, SvIV(SvRV(a)))) + SvIV(b); return obj_ref; } if(sv_isobject(b)) { const char *h = HvNAME(SvSTASH(SvRV(b))); if(strEQ(h, "Math::Decimal64")) { *d64 = *(INT2PTR(_Decimal64 *, SvIV(SvRV(a)))) + *(INT2PTR(_Decimal64 *, SvIV(SvRV(b)))); return obj_ref; } croak("Invalid object supplied to Math::Decimal64::_overload_add function"); } croak("Invalid argument supplied to Math::Decimal64::_overload_add function"); } SV * _overload_mul(pTHX_ SV * a, SV * b, SV * third) { _Decimal64 * d64; SV * obj_ref, * obj; Newx(d64, 1, _Decimal64); if(d64 == NULL) croak("Failed to allocate memory in _overload_mul function"); obj_ref = newSV(0); obj = newSVrv(obj_ref, "Math::Decimal64"); sv_setiv(obj, INT2PTR(IV,d64)); SvREADONLY_on(obj); if(SvUOK(b)) { *d64 = *(INT2PTR(_Decimal64 *, SvIV(SvRV(a)))) * SvUV(b); return obj_ref; } if(SvIOK(b)) { *d64 = *(INT2PTR(_Decimal64 *, SvIV(SvRV(a)))) * SvIV(b); return obj_ref; } if(sv_isobject(b)) { const char *h = HvNAME(SvSTASH(SvRV(b))); if(strEQ(h, "Math::Decimal64")) { *d64 = *(INT2PTR(_Decimal64 *, SvIV(SvRV(a)))) * *(INT2PTR(_Decimal64 *, SvIV(SvRV(b)))); return obj_ref; } croak("Invalid object supplied to Math::Decimal64::_overload_mul function"); } croak("Invalid argument supplied to Math::Decimal64::_overload_mul function"); } SV * _overload_sub(pTHX_ SV * a, SV * b, SV * third) { _Decimal64 * d64; SV * obj_ref, * obj; Newx(d64, 1, _Decimal64); if(d64 == NULL) croak("Failed to allocate memory in _overload_sub function"); obj_ref = newSV(0); obj = newSVrv(obj_ref, "Math::Decimal64"); sv_setiv(obj, INT2PTR(IV,d64)); SvREADONLY_on(obj); if(SvUOK(b)) { if(third == &PL_sv_yes) *d64 = SvUV(b) - *(INT2PTR(_Decimal64 *, SvIV(SvRV(a)))); else *d64 = *(INT2PTR(_Decimal64 *, SvIV(SvRV(a)))) - SvUV(b); return obj_ref; } if(SvIOK(b)) { if(third == &PL_sv_yes) *d64 = SvIV(b) - *(INT2PTR(_Decimal64 *, SvIV(SvRV(a)))); else *d64 = *(INT2PTR(_Decimal64 *, SvIV(SvRV(a)))) - SvIV(b); return obj_ref; } if(sv_isobject(b)) { const char *h = HvNAME(SvSTASH(SvRV(b))); if(strEQ(h, "Math::Decimal64")) { *d64 = *(INT2PTR(_Decimal64 *, SvIV(SvRV(a)))) - *(INT2PTR(_Decimal64 *, SvIV(SvRV(b)))); return obj_ref; } croak("Invalid object supplied to Math::Decimal64::_overload_sub function"); } if(third == &PL_sv_yes) { *d64 = *(INT2PTR(_Decimal64 *, SvIV(SvRV(a)))) * -1.0DD; return obj_ref; } croak("Invalid argument supplied to Math::Decimal64::_overload_sub function"); } SV * _overload_div(pTHX_ SV * a, SV * b, SV * third) { _Decimal64 * d64; SV * obj_ref, * obj; Newx(d64, 1, _Decimal64); if(d64 == NULL) croak("Failed to allocate memory in _overload_div function"); obj_ref = newSV(0); obj = newSVrv(obj_ref, "Math::Decimal64"); sv_setiv(obj, INT2PTR(IV,d64)); SvREADONLY_on(obj); if(SvUOK(b)) { if(third == &PL_sv_yes) *d64 = SvUV(b) / *(INT2PTR(_Decimal64 *, SvIV(SvRV(a)))); else *d64 = *(INT2PTR(_Decimal64 *, SvIV(SvRV(a)))) / SvUV(b); return obj_ref; } if(SvIOK(b)) { if(third == &PL_sv_yes) *d64 = SvIV(b) / *(INT2PTR(_Decimal64 *, SvIV(SvRV(a)))); else *d64 = *(INT2PTR(_Decimal64 *, SvIV(SvRV(a)))) / SvIV(b); return obj_ref; } if(sv_isobject(b)) { const char *h = HvNAME(SvSTASH(SvRV(b))); if(strEQ(h, "Math::Decimal64")) { *d64 = *(INT2PTR(_Decimal64 *, SvIV(SvRV(a)))) / *(INT2PTR(_Decimal64 *, SvIV(SvRV(b)))); return obj_ref; } croak("Invalid object supplied to Math::Decimal64::_overload_div function"); } croak("Invalid argument supplied to Math::Decimal64::_overload_div function"); } SV * _overload_add_eq(pTHX_ SV * a, SV * b, SV * third) { SvREFCNT_inc(a); if(SvUOK(b)) { *(INT2PTR(_Decimal64 *, SvIV(SvRV(a)))) += SvUV(b); return a; } if(SvIOK(b)) { *(INT2PTR(_Decimal64 *, SvIV(SvRV(a)))) += SvIV(b); return a; } if(sv_isobject(b)) { const char *h = HvNAME(SvSTASH(SvRV(b))); if(strEQ(h, "Math::Decimal64")) { *(INT2PTR(_Decimal64 *, SvIV(SvRV(a)))) += *(INT2PTR(_Decimal64 *, SvIV(SvRV(b)))); return a; } SvREFCNT_dec(a); croak("Invalid object supplied to Math::Decimal64::_overload_add_eq function"); } SvREFCNT_dec(a); croak("Invalid argument supplied to Math::Decimal64::_overload_add_eq function"); } SV * _overload_mul_eq(pTHX_ SV * a, SV * b, SV * third) { SvREFCNT_inc(a); if(SvUOK(b)) { *(INT2PTR(_Decimal64 *, SvIV(SvRV(a)))) *= SvUV(b); return a; } if(SvIOK(b)) { *(INT2PTR(_Decimal64 *, SvIV(SvRV(a)))) *= SvIV(b); return a; } if(sv_isobject(b)) { const char *h = HvNAME(SvSTASH(SvRV(b))); if(strEQ(h, "Math::Decimal64")) { *(INT2PTR(_Decimal64 *, SvIV(SvRV(a)))) *= *(INT2PTR(_Decimal64 *, SvIV(SvRV(b)))); return a; } SvREFCNT_dec(a); croak("Invalid object supplied to Math::Decimal64::_overload_mul_eq function"); } SvREFCNT_dec(a); croak("Invalid argument supplied to Math::Decimal64::_overload_mul_eq function"); } SV * _overload_sub_eq(pTHX_ SV * a, SV * b, SV * third) { SvREFCNT_inc(a); if(SvUOK(b)) { *(INT2PTR(_Decimal64 *, SvIV(SvRV(a)))) -= SvUV(b); return a; } if(SvIOK(b)) { *(INT2PTR(_Decimal64 *, SvIV(SvRV(a)))) -= SvIV(b); return a; } if(sv_isobject(b)) { const char *h = HvNAME(SvSTASH(SvRV(b))); if(strEQ(h, "Math::Decimal64")) { *(INT2PTR(_Decimal64 *, SvIV(SvRV(a)))) -= *(INT2PTR(_Decimal64 *, SvIV(SvRV(b)))); return a; } SvREFCNT_dec(a); croak("Invalid object supplied to Math::Decimal64::_overload_sub_eq function"); } SvREFCNT_dec(a); croak("Invalid argument supplied to Math::Decimal64::_overload_sub_eq function"); } SV * _overload_div_eq(pTHX_ SV * a, SV * b, SV * third) { SvREFCNT_inc(a); if(SvUOK(b)) { *(INT2PTR(_Decimal64 *, SvIV(SvRV(a)))) /= SvUV(b); return a; } if(SvIOK(b)) { *(INT2PTR(_Decimal64 *, SvIV(SvRV(a)))) /= SvIV(b); return a; } if(sv_isobject(b)) { const char *h = HvNAME(SvSTASH(SvRV(b))); if(strEQ(h, "Math::Decimal64")) { *(INT2PTR(_Decimal64 *, SvIV(SvRV(a)))) /= *(INT2PTR(_Decimal64 *, SvIV(SvRV(b)))); return a; } SvREFCNT_dec(a); croak("Invalid object supplied to Math::Decimal64::_overload_div_eq function"); } SvREFCNT_dec(a); croak("Invalid argument supplied to Math::Decimal64::_overload_div_eq function"); } SV * _overload_equiv(pTHX_ SV * a, SV * b, SV * third) { if(SvUOK(b)) { if(*(INT2PTR(_Decimal64 *, SvIV(SvRV(a)))) == SvUV(b)) return newSViv(1); return newSViv(0); } if(SvIOK(b)) { if(*(INT2PTR(_Decimal64 *, SvIV(SvRV(a)))) == SvIV(b)) return newSViv(1); return newSViv(0); } if(sv_isobject(b)) { const char *h = HvNAME(SvSTASH(SvRV(b))); if(strEQ(h, "Math::Decimal64")) { if(*(INT2PTR(_Decimal64 *, SvIV(SvRV(a)))) == *(INT2PTR(_Decimal64 *, SvIV(SvRV(b))))) return newSViv(1); return newSViv(0); } croak("Invalid object supplied to Math::Decimal64::_overload_equiv function"); } croak("Invalid argument supplied to Math::Decimal64::_overload_equiv function"); } SV * _overload_not_equiv(pTHX_ SV * a, SV * b, SV * third) { if(SvUOK(b)) { if(*(INT2PTR(_Decimal64 *, SvIV(SvRV(a)))) != SvUV(b)) return newSViv(1); return newSViv(0); } if(SvIOK(b)) { if(*(INT2PTR(_Decimal64 *, SvIV(SvRV(a)))) != SvIV(b)) return newSViv(1); return newSViv(0); } if(sv_isobject(b)) { const char *h = HvNAME(SvSTASH(SvRV(b))); if(strEQ(h, "Math::Decimal64")) { if(*(INT2PTR(_Decimal64 *, SvIV(SvRV(a)))) == *(INT2PTR(_Decimal64 *, SvIV(SvRV(b))))) return newSViv(0); return newSViv(1); } croak("Invalid object supplied to Math::Decimal64::_overload_not_equiv function"); } croak("Invalid argument supplied to Math::Decimal64::_overload_not_equiv function"); } SV * _overload_lt(pTHX_ SV * a, SV * b, SV * third) { if(SvUOK(b)) { if(*(INT2PTR(_Decimal64 *, SvIV(SvRV(a)))) < SvUV(b)) return newSViv(1); return newSViv(0); } if(SvIOK(b)) { if(*(INT2PTR(_Decimal64 *, SvIV(SvRV(a)))) < SvIV(b)) return newSViv(1); return newSViv(0); } if(sv_isobject(b)) { const char *h = HvNAME(SvSTASH(SvRV(b))); if(strEQ(h, "Math::Decimal64")) { if(*(INT2PTR(_Decimal64 *, SvIV(SvRV(a)))) < *(INT2PTR(_Decimal64 *, SvIV(SvRV(b))))) return newSViv(1); return newSViv(0); } croak("Invalid object supplied to Math::Decimal64::_overload_lt function"); } croak("Invalid argument supplied to Math::Decimal64::_overload_lt function"); } SV * _overload_gt(pTHX_ SV * a, SV * b, SV * third) { if(SvUOK(b)) { if(*(INT2PTR(_Decimal64 *, SvIV(SvRV(a)))) > SvUV(b)) return newSViv(1); return newSViv(0); } if(SvIOK(b)) { if(*(INT2PTR(_Decimal64 *, SvIV(SvRV(a)))) > SvIV(b)) return newSViv(1); return newSViv(0); } if(sv_isobject(b)) { const char *h = HvNAME(SvSTASH(SvRV(b))); if(strEQ(h, "Math::Decimal64")) { if(*(INT2PTR(_Decimal64 *, SvIV(SvRV(a)))) > *(INT2PTR(_Decimal64 *, SvIV(SvRV(b))))) return newSViv(1); return newSViv(0); } croak("Invalid object supplied to Math::Decimal64::_overload_gt function"); } croak("Invalid argument supplied to Math::Decimal64::_overload_gt function"); } SV * _overload_lte(pTHX_ SV * a, SV * b, SV * third) { if(SvUOK(b)) { if(*(INT2PTR(_Decimal64 *, SvIV(SvRV(a)))) <= SvUV(b)) return newSViv(1); return newSViv(0); } if(SvIOK(b)) { if(*(INT2PTR(_Decimal64 *, SvIV(SvRV(a)))) <= SvIV(b)) return newSViv(1); return newSViv(0); } if(sv_isobject(b)) { const char *h = HvNAME(SvSTASH(SvRV(b))); if(strEQ(h, "Math::Decimal64")) { if(*(INT2PTR(_Decimal64 *, SvIV(SvRV(a)))) <= *(INT2PTR(_Decimal64 *, SvIV(SvRV(b))))) return newSViv(1); return newSViv(0); } croak("Invalid object supplied to Math::Decimal64::_overload_lte function"); } croak("Invalid argument supplied to Math::Decimal64::_overload_lte function"); } SV * _overload_gte(pTHX_ SV * a, SV * b, SV * third) { if(SvUOK(b)) { if(*(INT2PTR(_Decimal64 *, SvIV(SvRV(a)))) >= SvUV(b)) return newSViv(1); return newSViv(0); } if(SvIOK(b)) { if(*(INT2PTR(_Decimal64 *, SvIV(SvRV(a)))) >= SvIV(b)) return newSViv(1); return newSViv(0); } if(sv_isobject(b)) { const char *h = HvNAME(SvSTASH(SvRV(b))); if(strEQ(h, "Math::Decimal64")) { if(*(INT2PTR(_Decimal64 *, SvIV(SvRV(a)))) >= *(INT2PTR(_Decimal64 *, SvIV(SvRV(b))))) return newSViv(1); return newSViv(0); } croak("Invalid object supplied to Math::Decimal64::_overload_gte function"); } croak("Invalid argument supplied to Math::Decimal64::_overload_gte function"); } SV * _overload_spaceship(pTHX_ SV * a, SV * b, SV * third) { if(SvUOK(b)) { if(*(INT2PTR(_Decimal64 *, SvIV(SvRV(a)))) > SvUV(b)) return newSViv(1); if(*(INT2PTR(_Decimal64 *, SvIV(SvRV(a)))) < SvUV(b)) return newSViv(-1); if(*(INT2PTR(_Decimal64 *, SvIV(SvRV(a)))) == SvUV(b)) return newSViv(0); return &PL_sv_undef; /* Math::Decimal64 object (1st arg) is a nan */ } if(SvIOK(b)) { if(*(INT2PTR(_Decimal64 *, SvIV(SvRV(a)))) > SvIV(b)) return newSViv(1); if(*(INT2PTR(_Decimal64 *, SvIV(SvRV(a)))) < SvIV(b)) return newSViv(-1); if(*(INT2PTR(_Decimal64 *, SvIV(SvRV(a)))) == SvIV(b)) return newSViv(0); return &PL_sv_undef; /* Math::Decimal64 object (1st arg) is a nan */ } if(sv_isobject(b)) { const char *h = HvNAME(SvSTASH(SvRV(b))); if(strEQ(h, "Math::Decimal64")) { if(*(INT2PTR(_Decimal64 *, SvIV(SvRV(a)))) < *(INT2PTR(_Decimal64 *, SvIV(SvRV(b))))) return newSViv(-1); if(*(INT2PTR(_Decimal64 *, SvIV(SvRV(a)))) > *(INT2PTR(_Decimal64 *, SvIV(SvRV(b))))) return newSViv(1); if(*(INT2PTR(_Decimal64 *, SvIV(SvRV(a)))) == *(INT2PTR(_Decimal64 *, SvIV(SvRV(b))))) return newSViv(0); return &PL_sv_undef; /* it's a nan */ } croak("Invalid object supplied to Math::Decimal64::_overload_spaceship function"); } croak("Invalid argument supplied to Math::Decimal64::_overload_spaceship function"); } SV * _overload_copy(pTHX_ SV * a, SV * b, SV * third) { _Decimal64 * d64; SV * obj_ref, * obj; Newx(d64, 1, _Decimal64); if(d64 == NULL) croak("Failed to allocate memory in _overload_copy function"); *d64 = *(INT2PTR(_Decimal64 *, SvIV(SvRV(a)))); obj_ref = newSV(0); obj = newSVrv(obj_ref, "Math::Decimal64"); sv_setiv(obj, INT2PTR(IV,d64)); SvREADONLY_on(obj); return obj_ref; } SV * D64toD64(pTHX_ SV * a) { _Decimal64 * d64; SV * obj_ref, * obj; if(sv_isobject(a)) { const char *h = HvNAME(SvSTASH(SvRV(a))); if(strEQ(h, "Math::Decimal64")) { Newx(d64, 1, _Decimal64); if(d64 == NULL) croak("Failed to allocate memory in D64toD64 function"); *d64 = *(INT2PTR(_Decimal64 *, SvIV(SvRV(a)))); obj_ref = newSV(0); obj = newSVrv(obj_ref, "Math::Decimal64"); sv_setiv(obj, INT2PTR(IV,d64)); SvREADONLY_on(obj); return obj_ref; } croak("Invalid object supplied to Math::Decimal64::D64toD64 function"); } croak("Invalid argument supplied to Math::Decimal64::D64toD64 function"); } SV * _overload_true(pTHX_ SV * a, SV * b, SV * third) { if(_is_nan(*(INT2PTR(_Decimal64 *, SvIV(SvRV(a)))))) return newSViv(0); if(*(INT2PTR(_Decimal64 *, SvIV(SvRV(a)))) != 0.0DD) return newSViv(1); return newSViv(0); } SV * _overload_not(pTHX_ SV * a, SV * b, SV * third) { if(_is_nan(*(INT2PTR(_Decimal64 *, SvIV(SvRV(a)))))) return newSViv(1); if(*(INT2PTR(_Decimal64 *, SvIV(SvRV(a)))) != 0.0DD) return newSViv(0); return newSViv(1); } SV * _overload_abs(pTHX_ SV * a, SV * b, SV * third) { _Decimal64 * d64; SV * obj_ref, * obj; Newx(d64, 1, _Decimal64); if(d64 == NULL) croak("Failed to allocate memory in _overload_abs function"); obj_ref = newSV(0); obj = newSVrv(obj_ref, "Math::Decimal64"); sv_setiv(obj, INT2PTR(IV,d64)); SvREADONLY_on(obj); *d64 = *(INT2PTR(_Decimal64 *, SvIV(SvRV(a)))); if(_is_neg_zero(*d64) || *d64 < 0 ) *d64 *= -1.0DD; return obj_ref; } SV * _overload_inc(pTHX_ SV * p, SV * second, SV * third) { SvREFCNT_inc(p); *(INT2PTR(_Decimal64 *, SvIV(SvRV(p)))) += 1.0DD; return p; } SV * _overload_dec(pTHX_ SV * p, SV * second, SV * third) { SvREFCNT_inc(p); *(INT2PTR(_Decimal64 *, SvIV(SvRV(p)))) -= 1.0DD; return p; } SV * _itsa(pTHX_ SV * a) { if(SvUOK(a)) return newSVuv(1); if(SvIOK(a)) return newSVuv(2); if(SvNOK(a)) return newSVuv(3); if(SvPOK(a)) return newSVuv(4); if(sv_isobject(a)) { const char *h = HvNAME(SvSTASH(SvRV(a))); if(strEQ(h, "Math::Decimal64")) return newSVuv(64); } return newSVuv(0); } SV * is_NaND64(pTHX_ SV * b) { if(sv_isobject(b)) { const char *h = HvNAME(SvSTASH(SvRV(b))); if(strEQ(h, "Math::Decimal64")) return newSViv(_is_nan(*(INT2PTR(_Decimal64 *, SvIV(SvRV(b)))))); } croak("Invalid argument supplied to Math::Decimal64::is_NaND64 function"); } SV * is_InfD64(pTHX_ SV * b) { if(sv_isobject(b)) { const char *h = HvNAME(SvSTASH(SvRV(b))); if(strEQ(h, "Math::Decimal64")) return newSViv(_is_inf(*(INT2PTR(_Decimal64 *, SvIV(SvRV(b)))))); } croak("Invalid argument supplied to Math::Decimal64::is_InfD64 function"); } SV * is_ZeroD64(pTHX_ SV * b) { if(sv_isobject(b)) { const char *h = HvNAME(SvSTASH(SvRV(b))); if(strEQ(h, "Math::Decimal64")) if (_is_neg_zero(*(INT2PTR(_Decimal64 *, SvIV(SvRV(b)))))) return newSViv(-1); if (*(INT2PTR(_Decimal64 *, SvIV(SvRV(b)))) == 0.0DD) return newSViv(1); return newSViv(0); } croak("Invalid argument supplied to Math::Decimal64::is_ZeroD64 function"); } void _D64toME(pTHX_ SV * a) { dXSARGS; _Decimal64 t; char * buffer; int count = 0; char * fmt = "%.15Le"; if(sv_isobject(a)) { const char *h = HvNAME(SvSTASH(SvRV(a))); if(strEQ(h, "Math::Decimal64")) { t = *(INT2PTR(_Decimal64 *, SvIV(SvRV(a)))); if(_is_nan(t) || _is_inf(t) || t == 0.0DD) { EXTEND(SP, 2); ST(0) = sv_2mortal(newSVnv(t)); ST(1) = sv_2mortal(newSViv(0)); XSRETURN(2); } /* At this stage we know the arg is not a _Decimal64 infinity/0, but on powerpc it might be a long double that's outside the allowable range */ #if defined(__powerpc__) || defined(_ARCH_PPC) || defined(_M_PPC) || defined(__PPCGECKO__) || defined(__PPCBROADWAY__) if((long double)t > LDBL_MAX || (long double)t < -LDBL_MAX) { count = 150; t *= 1e-150DD; /* (long double)t should now be in range */ } if((long double)t < LDBL_MIN * 128.0L && (long double)t > -LDBL_MIN * 128.0L) { count = -150; t *= 1e150DD; /* (long double)t should now be in range */ } #endif Newx(buffer, 32, char); if(buffer == NULL)croak("Couldn't allocate memory in _D64toME"); #if defined(__powerpc__) || defined(_ARCH_PPC) || defined(_M_PPC) || defined(__PPCGECKO__) || defined(__PPCBROADWAY__) /* Formatting bug (in C compiler/libc) wrt (+-)897e-292 */ if(t == 897e-292DD || t == -897e-292DD) fmt = "%.14Le"; #endif sprintf(buffer, fmt, (long double)t); EXTEND(SP, 3); ST(0) = sv_2mortal(newSVpv(buffer, 0)); ST(1) = &PL_sv_undef; ST(2) = sv_2mortal(newSViv(count)); /* count will be added to the exponent in D64toME() perl sub. */ Safefree(buffer); XSRETURN(3); } else croak("Invalid object supplied to Math::Decimal64::D64toME function"); } else croak("Invalid argument supplied to Math::Decimal64::D64toME function"); } /* Replaced by newer rendition (above) that caters for the case that the long double has the same exponent range as the double - eg. powerpc "double-double arithmetic". void _D64toME_deprecated(SV * a) { dXSARGS; _Decimal64 t; char * buffer; if(sv_isobject(a)) { const char *h = HvNAME(SvSTASH(SvRV(a))); if(strEQ(h, "Math::Decimal64")) { EXTEND(SP, 2); t = *(INT2PTR(_Decimal64 *, SvIV(SvRV(a)))); if(_is_nan(t) || _is_inf(t) || t == 0.0DD) { ST(0) = sv_2mortal(newSVnv(t)); ST(1) = sv_2mortal(newSViv(0)); XSRETURN(2); } Newx(buffer, 32, char); sprintf(buffer, "%.15Le", (long double)t); ST(0) = sv_2mortal(newSVpv(buffer, 0)); ST(1) = &PL_sv_undef; Safefree(buffer); XSRETURN(2); } else croak("Invalid object supplied to Math::Decimal64::D64toME function"); } else croak("Invalid argument supplied to Math::Decimal64::D64toME function"); } */ void _c2ld(pTHX_ char * mantissa) { /* convert using %.15Le */ dXSARGS; long double man; char *ptr, *buffer; man = strtold(mantissa, &ptr); Newx(buffer, 32, char); sprintf(buffer, "%.15Le", man); ST(0) = sv_2mortal(newSVpv(buffer, 0)); Safefree(buffer); XSRETURN(1); } void _c2d(pTHX_ char * mantissa) { /* convert using %.15e */ dXSARGS; double man; char *ptr, *buffer; man = strtod(mantissa, &ptr); Newx(buffer, 32, char); sprintf(buffer, "%.15e", man); ST(0) = sv_2mortal(newSVpv(buffer, 0)); Safefree(buffer); XSRETURN(1); } SV * _wrap_count(pTHX) { return newSVuv(PL_sv_count); } SV * _get_xs_version(pTHX) { return newSVpv(XS_VERSION, 0); } void _d64_bytes(pTHX_ SV * sv) { dXSARGS; _Decimal64 d64 = *(INT2PTR(_Decimal64 *, SvIV(SvRV(sv)))); int i, n = sizeof(_Decimal64); char * buff; void * p = &d64; Newx(buff, 4, char); if(buff == NULL) croak("Failed to allocate memory in _d64_bytes function"); sp = mark; #ifdef WE_HAVE_BENDIAN for (i = 0; i < n; i++) { #else for (i = n - 1; i >= 0; i--) { #endif sprintf(buff, "%02X", ((unsigned char*)p)[i]); XPUSHs(sv_2mortal(newSVpv(buff, 0))); } PUTBACK; Safefree(buff); XSRETURN(n); } void _bid_mant(pTHX_ SV * bin) { dXSARGS; int i, imax = av_len((AV*)SvRV(bin)); char * buf; long long val = 0ll; extern long long add_on[54]; Newx(buf, 20, char); if(buf == NULL) croak("Failed to allocate memory in bir_mant function"); for(i = 0; i <= imax; i++) if(SvIV(*(av_fetch((AV*)SvRV(bin), i, 0)))) val += add_on[i]; if(val > 9999999999999999ll) sprintf(buf, "%lld", 0ll); else sprintf(buf, "%lld", val); ST(0) = sv_2mortal(newSVpv(buf, 0)); Safefree(buf); XSRETURN(1); } SV * _endianness(pTHX) { #if defined(WE_HAVE_BENDIAN) return newSVpv("Big Endian", 0); #elif defined(WE_HAVE_LENDIAN) return newSVpv("Little Endian", 0); #else return &PL_sv_undef; #endif } SV * _DPDtoD64(pTHX_ char * in) { D64 * d64; SV * obj_ref, * obj; int i, n = sizeof(D64); D64 out = 0.; void *p = &out; Newx(d64, 1, D64); if(d64 == NULL) croak("Failed to allocate memory in DPDtoD64 function"); obj_ref = newSV(0); obj = newSVrv(obj_ref, "Math::Decimal64"); for (i = n - 1; i >= 0; i--) #ifdef WE_HAVE_BENDIAN ((unsigned char*)p)[i] = in[i]; #else ((unsigned char*)p)[i] = in[n - 1 - i]; #endif *d64 = out; sv_setiv(obj, INT2PTR(IV,d64)); SvREADONLY_on(obj); return obj_ref; } /* _assignDPD takes 2 args: a Math::Decimal64 object, and a string that encodes the value to be assigned to that object */ void _assignDPD(pTHX_ SV * a, char * in) { int i, n = sizeof(D64); D64 out = 0.; void *p = &out; for (i = n - 1; i >= 0; i--) #ifdef WE_HAVE_BENDIAN ((unsigned char*)p)[i] = in[i]; #else ((unsigned char*)p)[i] = in[n - 1 - i]; #endif *(INT2PTR(D64 *, SvIV(SvRV(a)))) = out; } MODULE = Math::Decimal64 PACKAGE = Math::Decimal64 PROTOTYPES: DISABLE SV * _is_nan_NV (x) SV * x CODE: RETVAL = _is_nan_NV (aTHX_ x); OUTPUT: RETVAL SV * _is_inf_NV (x) SV * x CODE: RETVAL = _is_inf_NV (aTHX_ x); OUTPUT: RETVAL SV * _is_neg_zero_NV (x) SV * x CODE: RETVAL = _is_neg_zero_NV (aTHX_ x); OUTPUT: RETVAL SV * _DEC64_MAX () CODE: RETVAL = _DEC64_MAX (aTHX); OUTPUT: RETVAL SV * _DEC64_MIN () CODE: RETVAL = _DEC64_MIN (aTHX); OUTPUT: RETVAL SV * NaND64 () CODE: RETVAL = NaND64 (aTHX); OUTPUT: RETVAL SV * InfD64 (sign) int sign CODE: RETVAL = InfD64 (aTHX_ sign); OUTPUT: RETVAL SV * ZeroD64 (sign) int sign CODE: RETVAL = ZeroD64 (aTHX_ sign); OUTPUT: RETVAL SV * UnityD64 (sign) int sign CODE: RETVAL = UnityD64 (aTHX_ sign); OUTPUT: RETVAL SV * Exp10 (power) int power CODE: RETVAL = Exp10 (aTHX_ power); OUTPUT: RETVAL SV * _testvalD64 (sign) int sign CODE: RETVAL = _testvalD64 (aTHX_ sign); OUTPUT: RETVAL SV * _MEtoD64 (mantissa, exponent) char * mantissa SV * exponent CODE: RETVAL = _MEtoD64 (aTHX_ mantissa, exponent); OUTPUT: RETVAL SV * NVtoD64 (x) SV * x CODE: RETVAL = NVtoD64 (aTHX_ x); OUTPUT: RETVAL SV * UVtoD64 (x) SV * x CODE: RETVAL = UVtoD64 (aTHX_ x); OUTPUT: RETVAL SV * IVtoD64 (x) SV * x CODE: RETVAL = IVtoD64 (aTHX_ x); OUTPUT: RETVAL SV * STRtoD64 (x) char * x CODE: RETVAL = STRtoD64 (aTHX_ x); OUTPUT: RETVAL int have_strtod64 () SV * D64toNV (d64) SV * d64 CODE: RETVAL = D64toNV (aTHX_ d64); OUTPUT: RETVAL void LDtoD64 (d64, ld) SV * d64 SV * ld PREINIT: I32* temp; PPCODE: temp = PL_markstack_ptr++; LDtoD64(aTHX_ d64, ld); if (PL_markstack_ptr != temp) { /* truly void, because dXSARGS not invoked */ PL_markstack_ptr = temp; XSRETURN_EMPTY; /* return empty stack */ } /* must have used dXSARGS; list context implied */ return; /* assume stack size is correct */ void D64toLD (ld, d64) SV * ld SV * d64 PREINIT: I32* temp; PPCODE: temp = PL_markstack_ptr++; D64toLD(aTHX_ ld, d64); if (PL_markstack_ptr != temp) { /* truly void, because dXSARGS not invoked */ PL_markstack_ptr = temp; XSRETURN_EMPTY; /* return empty stack */ } /* must have used dXSARGS; list context implied */ return; /* assume stack size is correct */ void DESTROY (rop) SV * rop PREINIT: I32* temp; PPCODE: temp = PL_markstack_ptr++; DESTROY(aTHX_ rop); if (PL_markstack_ptr != temp) { /* truly void, because dXSARGS not invoked */ PL_markstack_ptr = temp; XSRETURN_EMPTY; /* return empty stack */ } /* must have used dXSARGS; list context implied */ return; /* assume stack size is correct */ void _assignME (a, mantissa, c) SV * a char * mantissa SV * c PREINIT: I32* temp; PPCODE: temp = PL_markstack_ptr++; _assignME(aTHX_ a, mantissa, c); if (PL_markstack_ptr != temp) { /* truly void, because dXSARGS not invoked */ PL_markstack_ptr = temp; XSRETURN_EMPTY; /* return empty stack */ } /* must have used dXSARGS; list context implied */ return; /* assume stack size is correct */ void assignNaN (a) SV * a PREINIT: I32* temp; PPCODE: temp = PL_markstack_ptr++; assignNaN(aTHX_ a); if (PL_markstack_ptr != temp) { /* truly void, because dXSARGS not invoked */ PL_markstack_ptr = temp; XSRETURN_EMPTY; /* return empty stack */ } /* must have used dXSARGS; list context implied */ return; /* assume stack size is correct */ void assignInf (a, sign) SV * a int sign PREINIT: I32* temp; PPCODE: temp = PL_markstack_ptr++; assignInf(aTHX_ a, sign); if (PL_markstack_ptr != temp) { /* truly void, because dXSARGS not invoked */ PL_markstack_ptr = temp; XSRETURN_EMPTY; /* return empty stack */ } /* must have used dXSARGS; list context implied */ return; /* assume stack size is correct */ SV * _overload_add (a, b, third) SV * a SV * b SV * third CODE: RETVAL = _overload_add (aTHX_ a, b, third); OUTPUT: RETVAL SV * _overload_mul (a, b, third) SV * a SV * b SV * third CODE: RETVAL = _overload_mul (aTHX_ a, b, third); OUTPUT: RETVAL SV * _overload_sub (a, b, third) SV * a SV * b SV * third CODE: RETVAL = _overload_sub (aTHX_ a, b, third); OUTPUT: RETVAL SV * _overload_div (a, b, third) SV * a SV * b SV * third CODE: RETVAL = _overload_div (aTHX_ a, b, third); OUTPUT: RETVAL SV * _overload_add_eq (a, b, third) SV * a SV * b SV * third CODE: RETVAL = _overload_add_eq (aTHX_ a, b, third); OUTPUT: RETVAL SV * _overload_mul_eq (a, b, third) SV * a SV * b SV * third CODE: RETVAL = _overload_mul_eq (aTHX_ a, b, third); OUTPUT: RETVAL SV * _overload_sub_eq (a, b, third) SV * a SV * b SV * third CODE: RETVAL = _overload_sub_eq (aTHX_ a, b, third); OUTPUT: RETVAL SV * _overload_div_eq (a, b, third) SV * a SV * b SV * third CODE: RETVAL = _overload_div_eq (aTHX_ a, b, third); OUTPUT: RETVAL SV * _overload_equiv (a, b, third) SV * a SV * b SV * third CODE: RETVAL = _overload_equiv (aTHX_ a, b, third); OUTPUT: RETVAL SV * _overload_not_equiv (a, b, third) SV * a SV * b SV * third CODE: RETVAL = _overload_not_equiv (aTHX_ a, b, third); OUTPUT: RETVAL SV * _overload_lt (a, b, third) SV * a SV * b SV * third CODE: RETVAL = _overload_lt (aTHX_ a, b, third); OUTPUT: RETVAL SV * _overload_gt (a, b, third) SV * a SV * b SV * third CODE: RETVAL = _overload_gt (aTHX_ a, b, third); OUTPUT: RETVAL SV * _overload_lte (a, b, third) SV * a SV * b SV * third CODE: RETVAL = _overload_lte (aTHX_ a, b, third); OUTPUT: RETVAL SV * _overload_gte (a, b, third) SV * a SV * b SV * third CODE: RETVAL = _overload_gte (aTHX_ a, b, third); OUTPUT: RETVAL SV * _overload_spaceship (a, b, third) SV * a SV * b SV * third CODE: RETVAL = _overload_spaceship (aTHX_ a, b, third); OUTPUT: RETVAL SV * _overload_copy (a, b, third) SV * a SV * b SV * third CODE: RETVAL = _overload_copy (aTHX_ a, b, third); OUTPUT: RETVAL SV * D64toD64 (a) SV * a CODE: RETVAL = D64toD64 (aTHX_ a); OUTPUT: RETVAL SV * _overload_true (a, b, third) SV * a SV * b SV * third CODE: RETVAL = _overload_true (aTHX_ a, b, third); OUTPUT: RETVAL SV * _overload_not (a, b, third) SV * a SV * b SV * third CODE: RETVAL = _overload_not (aTHX_ a, b, third); OUTPUT: RETVAL SV * _overload_abs (a, b, third) SV * a SV * b SV * third CODE: RETVAL = _overload_abs (aTHX_ a, b, third); OUTPUT: RETVAL SV * _overload_inc (p, second, third) SV * p SV * second SV * third CODE: RETVAL = _overload_inc (aTHX_ p, second, third); OUTPUT: RETVAL SV * _overload_dec (p, second, third) SV * p SV * second SV * third CODE: RETVAL = _overload_dec (aTHX_ p, second, third); OUTPUT: RETVAL SV * _itsa (a) SV * a CODE: RETVAL = _itsa (aTHX_ a); OUTPUT: RETVAL SV * is_NaND64 (b) SV * b CODE: RETVAL = is_NaND64 (aTHX_ b); OUTPUT: RETVAL SV * is_InfD64 (b) SV * b CODE: RETVAL = is_InfD64 (aTHX_ b); OUTPUT: RETVAL SV * is_ZeroD64 (b) SV * b CODE: RETVAL = is_ZeroD64 (aTHX_ b); OUTPUT: RETVAL void _D64toME (a) SV * a PREINIT: I32* temp; PPCODE: temp = PL_markstack_ptr++; _D64toME(aTHX_ a); if (PL_markstack_ptr != temp) { /* truly void, because dXSARGS not invoked */ PL_markstack_ptr = temp; XSRETURN_EMPTY; /* return empty stack */ } /* must have used dXSARGS; list context implied */ return; /* assume stack size is correct */ void _c2ld (mantissa) char * mantissa PREINIT: I32* temp; PPCODE: temp = PL_markstack_ptr++; _c2ld(aTHX_ mantissa); if (PL_markstack_ptr != temp) { /* truly void, because dXSARGS not invoked */ PL_markstack_ptr = temp; XSRETURN_EMPTY; /* return empty stack */ } /* must have used dXSARGS; list context implied */ return; /* assume stack size is correct */ void _c2d (mantissa) char * mantissa PREINIT: I32* temp; PPCODE: temp = PL_markstack_ptr++; _c2d(aTHX_ mantissa); if (PL_markstack_ptr != temp) { /* truly void, because dXSARGS not invoked */ PL_markstack_ptr = temp; XSRETURN_EMPTY; /* return empty stack */ } /* must have used dXSARGS; list context implied */ return; /* assume stack size is correct */ SV * _wrap_count () CODE: RETVAL = _wrap_count (aTHX); OUTPUT: RETVAL SV * _get_xs_version () CODE: RETVAL = _get_xs_version (aTHX); OUTPUT: RETVAL void _d64_bytes (sv) SV * sv PREINIT: I32* temp; PPCODE: temp = PL_markstack_ptr++; _d64_bytes(aTHX_ sv); if (PL_markstack_ptr != temp) { /* truly void, because dXSARGS not invoked */ PL_markstack_ptr = temp; XSRETURN_EMPTY; /* return empty stack */ } /* must have used dXSARGS; list context implied */ return; /* assume stack size is correct */ void _bid_mant (bin) SV * bin PREINIT: I32* temp; PPCODE: temp = PL_markstack_ptr++; _bid_mant(aTHX_ bin); if (PL_markstack_ptr != temp) { /* truly void, because dXSARGS not invoked */ PL_markstack_ptr = temp; XSRETURN_EMPTY; /* return empty stack */ } /* must have used dXSARGS; list context implied */ return; /* assume stack size is correct */ SV * _endianness () CODE: RETVAL = _endianness (aTHX); OUTPUT: RETVAL SV * _DPDtoD64 (in) char * in CODE: RETVAL = _DPDtoD64 (aTHX_ in); OUTPUT: RETVAL void _assignDPD (a, in) SV * a char * in PREINIT: I32* temp; PPCODE: temp = PL_markstack_ptr++; _assignDPD(aTHX_ a, in); if (PL_markstack_ptr != temp) { /* truly void, because dXSARGS not invoked */ PL_markstack_ptr = temp; XSRETURN_EMPTY; /* return empty stack */ } /* must have used dXSARGS; list context implied */ return; /* assume stack size is correct */