static Variant HHVM_FUNCTION(bcpowmod, const String& left, const String& right, const String& modulus, int64_t scale /* = -1 */) { if (scale < 0) scale = BCG(bc_precision); bc_num first, second, mod, result; bc_init_num(&first); bc_init_num(&second); bc_init_num(&mod); bc_init_num(&result); SCOPE_EXIT { bc_free_num(&first); bc_free_num(&second); bc_free_num(&mod); bc_free_num(&result); }; php_str2num(&first, (char*)left.data()); php_str2num(&second, (char*)right.data()); php_str2num(&mod, (char*)modulus.data()); if (bc_raisemod(first, second, mod, &result, scale) == -1) { return false; } if (result->n_scale > scale) { result->n_scale = scale; } String ret(bc_num2str(result), AttachString); return ret; }
int64 f_bccomp(CStrRef left, CStrRef right, int64 scale /* = -1 */) { if (scale < 0) scale = BCG(bc_precision); bc_num first, second; bc_init_num(&first); bc_init_num(&second); bc_str2num(&first, (char*)left.data(), scale); bc_str2num(&second, (char*)right.data(), scale); int64 ret = bc_compare(first, second); bc_free_num(&first); bc_free_num(&second); return ret; }
static int64_t HHVM_FUNCTION(bccomp, const String& left, const String& right, int64_t scale /* = -1 */) { if (scale < 0) scale = BCG(bc_precision); bc_num first, second; bc_init_num(&first); bc_init_num(&second); bc_str2num(&first, (char*)left.data(), scale); bc_str2num(&second, (char*)right.data(), scale); int64_t ret = bc_compare(first, second); bc_free_num(&first); bc_free_num(&second); return ret; }
virtual void moduleInit() { IniSetting::Bind("bcmath.scale", "0", ini_on_update_long, ini_get_long, &BCG(bc_precision)); HHVM_FE(bcscale); HHVM_FE(bcadd); HHVM_FE(bcsub); HHVM_FE(bccomp); HHVM_FE(bcmul); HHVM_FE(bcdiv); HHVM_FE(bcmod); HHVM_FE(bcpow); HHVM_FE(bcpowmod); HHVM_FE(bcsqrt); loadSystemlib(); }
Variant f_bcsqrt(CStrRef operand, int64 scale /* = -1 */) { if (scale < 0) scale = BCG(bc_precision); bc_num result; bc_init_num(&result); php_str2num(&result, (char*)operand.data()); Variant ret; if (bc_sqrt(&result, scale) != 0) { if (result->n_scale > scale) { result->n_scale = scale; } ret = String(bc_num2str(result), AttachString); } else { Logger::Warning("Square root of negative number"); } bc_free_num(&result); return ret; }
static Variant HHVM_FUNCTION(bcsqrt, const String& operand, int64_t scale /* = -1 */) { if (scale < 0) scale = BCG(bc_precision); bc_num result; bc_init_num(&result); php_str2num(&result, (char*)operand.data()); Variant ret; if (bc_sqrt(&result, scale) != 0) { if (result->n_scale > scale) { result->n_scale = scale; } ret = String(bc_num2str(result), AttachString); } else { raise_warning("Square root of negative number"); } bc_free_num(&result); return ret; }
String f_bcdiv(CStrRef left, CStrRef right, int64 scale /* = -1 */) { if (scale < 0) scale = BCG(bc_precision); bc_num first, second, result; bc_init_num(&first); bc_init_num(&second); bc_init_num(&result); php_str2num(&first, (char*)left.data()); php_str2num(&second, (char*)right.data()); if (bc_divide(first, second, &result, scale) == -1) { Logger::Warning("Division by zero"); return String(); } String ret(bc_num2str(result), AttachString); bc_free_num(&first); bc_free_num(&second); bc_free_num(&result); return ret; }
String f_bcsub(CStrRef left, CStrRef right, int64 scale /* = -1 */) { if (scale < 0) scale = BCG(bc_precision); bc_num first, second, result; bc_init_num(&first); bc_init_num(&second); bc_init_num(&result); php_str2num(&first, (char*)left.data()); php_str2num(&second, (char*)right.data()); bc_sub(first, second, &result, scale); if (result->n_scale > scale) { result->n_scale = scale; } String ret(bc_num2str(result), AttachString); bc_free_num(&first); bc_free_num(&second); bc_free_num(&result); return ret; }
static String HHVM_FUNCTION(bcsub, const String& left, const String& right, int64_t scale /* = -1 */) { if (scale < 0) scale = BCG(bc_precision); bc_num first, second, result; bc_init_num(&first); bc_init_num(&second); bc_init_num(&result); php_str2num(&first, (char*)left.data()); php_str2num(&second, (char*)right.data()); bc_sub(first, second, &result, scale); if (result->n_scale > scale) { result->n_scale = scale; } String ret(bc_num2str(result), AttachString); bc_free_num(&first); bc_free_num(&second); bc_free_num(&result); return ret; }
static Variant HHVM_FUNCTION(bcdiv, const String& left, const String& right, int64_t scale /* = -1 */) { if (scale < 0) scale = BCG(bc_precision); bc_num first, second, result; bc_init_num(&first); bc_init_num(&second); bc_init_num(&result); php_str2num(&first, (char*)left.data()); php_str2num(&second, (char*)right.data()); if (bc_divide(first, second, &result, scale) == -1) { raise_warning("Division by zero"); return Variant(); } String ret(bc_num2str(result), AttachString); bc_free_num(&first); bc_free_num(&second); bc_free_num(&result); return ret; }
char bc_is_zero (bc_num num TSRMLS_DC) { int count; char *nptr; /* Quick check. */ if (num == BCG(_zero_)) return TRUE; /* Initialize */ count = num->n_len + num->n_scale; nptr = num->n_value; /* The check */ while ((count > 0) && (*nptr++ == 0)) count--; if (count != 0) return FALSE; else return TRUE; }
Variant f_bcpowmod(CStrRef left, CStrRef right, CStrRef modulus, int64 scale /* = -1 */) { if (scale < 0) scale = BCG(bc_precision); bc_num first, second, mod, result; bc_init_num(&first); bc_init_num(&second); bc_init_num(&mod); bc_init_num(&result); php_str2num(&first, (char*)left.data()); php_str2num(&second, (char*)right.data()); php_str2num(&mod, (char*)modulus.data()); if (bc_raisemod(first, second, mod, &result, scale) == -1) { return false; } if (result->n_scale > scale) { result->n_scale = scale; } String ret(bc_num2str(result), AttachString); bc_free_num(&first); bc_free_num(&second); bc_free_num(&mod); bc_free_num(&result); return ret; }
void bc_raise (bc_num num1, bc_num num2, bc_num *result, int scale) { bc_num temp, power; long exponent; int rscale; int pwrscale; int calcscale; char neg; /* Check the exponent for scale digits and convert to a long. */ if (num2->n_scale != 0) bc_rt_warn ("non-zero scale in exponent"); exponent = bc_num2long (num2); if (exponent == 0 && (num2->n_len > 1 || num2->n_value[0] != 0)) bc_rt_error ("exponent too large in raise"); /* Special case if exponent is a zero. */ if (exponent == 0) { bc_free_num (result); *result = bc_copy_num (BCG(_one_)); return; } /* Other initializations. */ if (exponent < 0) { neg = TRUE; exponent = -exponent; rscale = scale; } else { neg = FALSE; rscale = MIN (num1->n_scale*exponent, MAX(scale, num1->n_scale)); } /* Set initial value of temp. */ power = bc_copy_num (num1); pwrscale = num1->n_scale; while ((exponent & 1) == 0) { pwrscale = 2*pwrscale; bc_multiply (power, power, &power, pwrscale); exponent = exponent >> 1; } temp = bc_copy_num (power); calcscale = pwrscale; exponent = exponent >> 1; /* Do the calculation. */ while (exponent > 0) { pwrscale = 2*pwrscale; bc_multiply (power, power, &power, pwrscale); if ((exponent & 1) == 1) { calcscale = pwrscale + calcscale; bc_multiply (temp, power, &temp, calcscale); } exponent = exponent >> 1; } /* Assign the value. */ if (neg) { bc_divide (BCG(_one_), temp, result, rscale); bc_free_num (&temp); } else { bc_free_num (result); *result = temp; if ((*result)->n_scale > rscale) (*result)->n_scale = rscale; } bc_free_num (&power); }
static bool HHVM_FUNCTION(bcscale, int64_t scale) { BCG(bc_precision) = scale < 0 ? 0 : scale; return true; }
virtual void threadInit() { IniSetting::Bind(this, IniSetting::PHP_INI_ALL, "bcmath.scale", "0", &BCG(bc_precision)); }
void bc_str2num (bc_num *num, char *str, int scale TSRMLS_DC) { int digits, strscale; char *ptr, *nptr; char zero_int; /* Prepare num. */ bc_free_num (num); /* Check for valid number and count digits. */ ptr = str; digits = 0; strscale = 0; zero_int = FALSE; if ( (*ptr == '+') || (*ptr == '-')) ptr++; /* Sign */ while (*ptr == '0') ptr++; /* Skip leading zeros. */ while (isdigit((int)*ptr)) ptr++, digits++; /* digits */ if (*ptr == '.') ptr++; /* decimal point */ while (isdigit((int)*ptr)) ptr++, strscale++; /* digits */ if ((*ptr != '\0') || (digits+strscale == 0)) { *num = bc_copy_num (BCG(_zero_)); return; } /* Adjust numbers and allocate storage and initialize fields. */ strscale = MIN(strscale, scale); if (digits == 0) { zero_int = TRUE; digits = 1; } *num = bc_new_num (digits, strscale); /* Build the whole number. */ ptr = str; if (*ptr == '-') { (*num)->n_sign = MINUS; ptr++; } else { (*num)->n_sign = PLUS; if (*ptr == '+') ptr++; } while (*ptr == '0') ptr++; /* Skip leading zeros. */ nptr = (*num)->n_value; if (zero_int) { *nptr++ = 0; digits = 0; } for (;digits > 0; digits--) *nptr++ = CH_VAL(*ptr++); /* Build the fractional part. */ if (strscale > 0) { ptr++; /* skip the decimal point! */ for (;strscale > 0; strscale--) *nptr++ = CH_VAL(*ptr++); } }
bool f_bcscale(int64 scale) { BCG(bc_precision) = scale < 0 ? 0 : scale; return true; }