DEC_TYPE INTERNAL_FUNCTION_NAME (DEC_TYPE x) { decContext context; decNumber dn_result; DEC_TYPE result, one; decNumber dn_x, dn_one; one = DFP_CONSTANT(1.0); FUNC_CONVERT_TO_DN (&one, &dn_one); FUNC_CONVERT_TO_DN (&x, &dn_x); if (decNumberIsNaN (&dn_x) || decNumberIsZero (&dn_x) || decNumberIsInfinite (&dn_x)) { return x + x; } decContextDefault (&context, DEFAULT_CONTEXT); /* using trig identity: acosh(x) = log(x+sqrt(x*x-1)) */ decNumberMultiply (&dn_result, &dn_x, &dn_x, &context); decNumberAdd (&dn_result, &dn_result, &dn_one, &context); decNumberSquareRoot (&dn_result, &dn_result, &context); decNumberAdd (&dn_result, &dn_result, &dn_x, &context); decNumberLn (&dn_result, &dn_result, &context); FUNC_CONVERT_FROM_DN (&dn_result, &result, &context); return result; }
static DEC_TYPE IEEE_FUNCTION_NAME (DEC_TYPE x) { decContext context; decNumber dn_result; DEC_TYPE result, one, temp; decNumber dn_x, dn_temp, dn_one; /* int comp;*/ one=DFP_CONSTANT(1.0); FUNC_CONVERT_TO_DN (&one, &dn_one); FUNC_CONVERT_TO_DN (&x, &dn_x); /* Handle NaN and early exit for x==0 */ if (decNumberIsNaN (&dn_x) || decNumberIsZero (&dn_x)) return x + x; decContextDefault (&context, DEFAULT_CONTEXT); decNumberAbs (&dn_temp, &dn_x, &context); FUNC_CONVERT_FROM_DN (&dn_temp, &temp, &context); if(temp==one) { /* |x| == 1 -> Pole Error */ DFP_EXCEPT (FE_DIVBYZERO); return decNumberIsNegative(&dn_x) ? -DFP_HUGE_VAL:DFP_HUGE_VAL; } else if (temp>one) { /* |x| > 1 -> Domain Error (this handles +-Inf too) */ DFP_EXCEPT (FE_INVALID); return DFP_NAN; } // comp = decCompare (&dn_temp, &dn_one); // switch (comp) // { // case 0: /* |x| == 1 -> Pole Error */ // DFP_EXCEPT (FE_DIVBYZERO); // return decNumberIsNegative(&dn_x) ? -DFP_HUGE_VAL:DFP_HUGE_VAL; // case 1: /* |x| > 1 -> Domain Error (this handles +-Inf too) */ // DFP_EXCEPT (FE_INVALID); // return DFP_NAN; // } /* Using trig identity: atanh(x) = 1/2 * log((1+x)/(1-x)) */ decNumberAdd (&dn_result, &dn_one, &dn_x, &context); decNumberSubtract (&dn_temp, &dn_one, &dn_x, &context); decNumberDivide (&dn_result, &dn_result, &dn_temp, &context); decNumberLn (&dn_result, &dn_result, &context); decNumberAdd (&dn_temp, &dn_one, &dn_one, &context); /* 2 */ decNumberDivide (&dn_result, &dn_result, &dn_temp, &context); FUNC_CONVERT_FROM_DN (&dn_result, &result, &context); return result; }
void zetadk(decNumber *dk, int n, int k, decContext *ctx) { int i; decNumber t, r, s, v, sum, const_4; int_to_dn(&const_4, 4, ctx); decNumberZero(&sum); for (i=0; i<=k; i++) { int_to_dn(&t, n+i-1, ctx); decNumberFactorial(&s, &t, ctx); int_to_dn(&t, i, ctx); decNumberPower(&r, &const_4, &t, ctx); decNumberMultiply(&v, &s, &r, ctx); int_to_dn(&t, n-i, ctx); decNumberFactorial(&s, &t, ctx); int_to_dn(&t, 2*i, ctx); decNumberFactorial(&r, &t, ctx); decNumberMultiply(&t, &r, &s, ctx); decNumberDivide(&r, &v, &t, ctx); decNumberAdd(&sum, &sum, &r, ctx); } int_to_dn(&t, n, ctx); #if 1 // Don't bother rounding to int, the conversion in compile_consts // will do this if required due to the extra precision being carries. decNumberMultiply(dk, &t, &sum, ctx); #else // We can round this to integers this way.... decNumberMultiply(&s, &t, &sum, ctx); decNumberToIntegralValue(dk, &s, ctx); #endif }
void* decSingleAdd (decSingle* _0, const decSingle* _1, const decSingle* _2, decContext* ctx) noexcept { decNumber _0num; decNumber _1num; decNumber _2num; decSingleToNumber (_1, &_1num); decSingleToNumber (_2, &_2num); decNumberAdd (&_0num, &_1num, &_2num, ctx); return decSingleFromNumber (_0, &_0num, ctx); }
const DecimalDecNumber &DecimalDecNumber::operator ++() { if (decNumberIsNaN(&m_value)) { throw("Performing arithmetic on uninitialised decimal [Nan]"); } decNumberAdd(&m_value, &m_value, &ONE.m_value, &m_context); return *this; }
const DecimalDecNumber &DecimalDecNumber::operator +=(const DecimalDecNumber &rhs) { if (decNumberIsNaN(&m_value) || decNumberIsNaN(&rhs.m_value)) { // FTHROW(InvalidStateException, "Performing arithmetic on uninitialised decimal [Nan]"); throw("Performing arithmetic on uninitialised decimal [Nan]"); } decNumberAdd(&m_value, &m_value, &rhs.m_value, &m_context); return *this; }
DEC_TYPE FUNC_NAME (_Decimal128 hi, _Decimal128 mid, _Decimal128 low) { DEC_TYPE result; /* hi = m_hi * 10^34 * mid = m_mid * 10^17 * low = m_low * 10^0 * * Note, m_hi is only at most 5 digits for int128. */ decNumber dn_hi, dn_mid, dn_low, dn_result; decNumber dn_hi_s, dn_mid_s, dn_result_s; decNumber dn_17, dn_34; decContext context; decContextDefault (&context, DEC_INIT_DECIMAL128); /* Hack, we're using 39 digits here. */ context.digits = 39; decNumberFromInt32(&dn_17, 17); decNumberFromInt32(&dn_34, 34); __DECIMAL_TO_DECNUMBER (&hi, &dn_hi, 128); __DECIMAL_TO_DECNUMBER (&mid, &dn_mid, 128); __DECIMAL_TO_DECNUMBER (&low, &dn_low, 128); /* Rotate addends into proper position. */ decNumberShift(&dn_hi_s,&dn_hi,&dn_34,&context); decNumberShift(&dn_mid_s,&dn_mid,&dn_17,&context); /* Sum the three components. */ decNumberAdd(&dn_result_s, &dn_hi_s, &dn_mid_s, &context); decNumberAdd(&dn_result, &dn_result_s, &dn_low, &context); /* Convert to the destination format. */ FUNC_CONVERT_FROM_DN (&dn_result, &result, &context); /* Don't care about exceptions here... I don't think. */ return result; }
int main(int argc, char *argv[]) { { // excerpt for User's Guide starts here--------------------------| decNumber one, mtwo, hundred; // constants decNumber start, rate, years; // parameters decNumber total; // result decContext set; // working context uint8_t startpack[]={0x01, 0x00, 0x00, 0x0C}; // investment=100000 int32_t startscale=0; uint8_t ratepack[]={0x06, 0x5C}; // rate=6.5% int32_t ratescale=1; uint8_t yearspack[]={0x02, 0x0C}; // years=20 int32_t yearsscale=0; uint8_t respack[16]; // result, packed int32_t resscale; // .. char hexes[49]; // for packed->hex int i; // counter if (argc<0) printf("%s", argv[1]); // noop for warning decContextDefault(&set, DEC_INIT_BASE); // initialize set.traps=0; // no traps set.digits=25; // precision 25 decNumberFromString(&one, "1", &set); // set constants decNumberFromString(&mtwo, "-2", &set); decNumberFromString(&hundred, "100", &set); decPackedToNumber(startpack, sizeof(startpack), &startscale, &start); decPackedToNumber(ratepack, sizeof(ratepack), &ratescale, &rate); decPackedToNumber(yearspack, sizeof(yearspack), &yearsscale, &years); decNumberDivide(&rate, &rate, &hundred, &set); // rate=rate/100 decNumberAdd(&rate, &rate, &one, &set); // rate=rate+1 decNumberPower(&rate, &rate, &years, &set); // rate=rate^years decNumberMultiply(&total, &rate, &start, &set); // total=rate*start decNumberRescale(&total, &total, &mtwo, &set); // two digits please decPackedFromNumber(respack, sizeof(respack), &resscale, &total); // lay out the total as sixteen hexadecimal pairs for (i=0; i<16; i++) { sprintf(&hexes[i*3], "%02x ", respack[i]); } printf("Result: %s (scale=%ld)\n", hexes, (long int)resscale); } //---------------------------------------------------------------| return 0; } // main
static DEC_TYPE IEEE_FUNCTION_NAME (DEC_TYPE x) { decContext context; decNumber dn_result; DEC_TYPE result; decNumber dn_x; decNumber dn_sum; decNumber dn_one; DEC_TYPE one = DFP_CONSTANT(1.0); FUNC_CONVERT_TO_DN (&x, &dn_x); FUNC_CONVERT_TO_DN (&one, &dn_one); /* For NaN, 0, or +Inf, just return x */ if (decNumberIsNaN (&dn_x) || decNumberIsZero (&dn_x) || (decNumberIsInfinite (&dn_x) && !decNumberIsNegative (&dn_x))) return x+x; decContextDefault(&context, DEFAULT_CONTEXT); decNumberAdd(&dn_sum, &dn_x, &dn_one, &context); if (decNumberIsZero(&dn_sum)) /* Pole Error if x was -1 */ { DFP_EXCEPT (FE_DIVBYZERO); return -DFP_HUGE_VAL; } if (decNumberIsNegative(&dn_sum)) /* Domain Error if x < -1 */ { DFP_EXCEPT (FE_INVALID); return DFP_NAN; } decNumberLn(&dn_result, &dn_sum, &context); FUNC_CONVERT_FROM_DN(&dn_result, &result, &context); return result; }
int main(int argc, char *argv[]) { int need=3; if (argc<need+1) { // not enough words printf("Please supply %d number(s).\n", need); return 1; } { // excerpt for User's Guide starts here--------------------------| decNumber one, mtwo, hundred; // constants decNumber start, rate, years; // parameters decNumber total; // result decContext set; // working context char string[DECNUMDIGITS+14]; // conversion buffer decContextDefault(&set, DEC_INIT_BASE); // initialize set.traps=0; // no traps set.digits=25; // precision 25 decNumberFromString(&one, "1", &set); // set constants decNumberFromString(&mtwo, "-2", &set); decNumberFromString(&hundred, "100", &set); decNumberFromString(&start, argv[1], &set); // parameter words decNumberFromString(&rate, argv[2], &set); decNumberFromString(&years, argv[3], &set); decNumberDivide(&rate, &rate, &hundred, &set); // rate=rate/100 decNumberAdd(&rate, &rate, &one, &set); // rate=rate+1 decNumberPower(&rate, &rate, &years, &set); // rate=rate^years decNumberMultiply(&total, &rate, &start, &set); // total=rate*start decNumberRescale(&total, &total, &mtwo, &set); // two digits please decNumberToString(&total, string); printf("%s at %s%% for %s years => %s\n", argv[1], argv[2], argv[3], string); } //---------------------------------------------------------------| return 0; } // main
int main(int argc, char *argv[]) { decNumber a, b; // working numbers decContext set; // working context char string[DECNUMDIGITS+14]; // conversion buffer decContextTestEndian(0); // warn if DECLITEND is wrong if (argc<3) { // not enough words printf("Please supply two numbers to add.\n"); return 1; } decContextDefault(&set, DEC_INIT_BASE); // initialize set.traps=0; // no traps, thank you set.digits=DECNUMDIGITS; // set precision decNumberFromString(&a, argv[1], &set); decNumberFromString(&b, argv[2], &set); decNumberAdd(&a, &a, &b, &set); // a=a+b decNumberToString(&a, string); printf("%s + %s => %s\n", argv[1], argv[2], string); return 0; } // main
static DEC_TYPE IEEE_FUNCTION_NAME (DEC_TYPE x, DEC_TYPE y) { decContext context; decNumber dn_result; DEC_TYPE result; decNumber dn_x; decNumber dn_y; decNumber dn_diff; DEC_TYPE temp_diff; DEC_TYPE temp_result; FUNC_CONVERT_TO_DN (&x, &dn_x); FUNC_CONVERT_TO_DN (&y, &dn_y); if(decNumberIsNaN (&dn_x) || decNumberIsNaN (&dn_y)) return x; decContextDefault (&context, DEFAULT_CONTEXT); decNumberSubtract (&dn_diff, &dn_x, &dn_y, &context); decNumberSubtract (&dn_result, &dn_x, &dn_x, &context); FUNC_CONVERT_FROM_DN (&dn_diff, &temp_diff, &context); FUNC_CONVERT_FROM_DN (&dn_result, &temp_result, &context); if(temp_diff>temp_result) decNumberAdd (&dn_result,&dn_result,&dn_diff,&context); /* if(decCompare (&dn_diff,&dn_result) == 1) decNumberAdd (&dn_result,&dn_result,&dn_diff,&context); */ FUNC_CONVERT_FROM_DN (&dn_result, &result, &context); if (context.status & DEC_Overflow) DFP_EXCEPT (FE_OVERFLOW); return result; }