/* divide two phpnums, potentially converting to a double. */ obj_t phpdiv(obj_t a, obj_t b) { if ((ELONGP(b) && (BELONG_TO_LONG(b) == 0)) || (REALP(b) && (REAL_TO_DOUBLE(b) == 0.0))) { phpnum_fail("Derision by zero"); } if (ELONGP(a) && ELONGP(b)) { if (BELONG_TO_LONG(a) % BELONG_TO_LONG(b) == 0) { /* integer */ long lval = BELONG_TO_LONG(a) / BELONG_TO_LONG(b); /* if (WITHIN_PDL_RANGE(lval)) { */ /* return GET_PDL(lval); */ /* } else { */ return LONG_TO_ONUM(lval); /* } */ } else { double dval = ((double) BELONG_TO_LONG (a)) / BELONG_TO_LONG(b); return DOUBLE_TO_REAL(dval); } } if ((REALP(a) && ELONGP(b)) || (ELONGP(a) && REALP(b))) { double dval = (ELONGP(a) ? (((double) BELONG_TO_LONG(a)) / REAL_TO_DOUBLE(b)) : (REAL_TO_DOUBLE(a) / ((double) BELONG_TO_LONG(b)))); return DOUBLE_TO_REAL(dval); } if (REALP(a) && REALP(b)) { double dval = REAL_TO_DOUBLE(a) / REAL_TO_DOUBLE(b); return DOUBLE_TO_REAL(dval); } phpnum_fail("no clue"); }
/* multiply two phpnums, potentially converting to a double. */ obj_t phpmul(obj_t a, obj_t b) { long lval; double dval; unsigned char tx; if (ELONGP(a) && ELONGP(b)) { int use_dval; long alval = BELONG_TO_LONG(a); long blval = BELONG_TO_LONG(b); FAST_LONG_MULTIPLY(alval, blval, lval, dval, use_dval); if (use_dval) { return DOUBLE_TO_REAL(dval); } else { return LONG_TO_ONUM(lval); } } else if (REALP(a) && REALP(b)) { dval = REAL_TO_DOUBLE(a) * REAL_TO_DOUBLE(b); return DOUBLE_TO_REAL(dval); } else if (REALP (a) && ELONGP(b)) { dval = REAL_TO_DOUBLE(a) * (double) BELONG_TO_LONG(b); return DOUBLE_TO_REAL(dval); } else if (ELONGP(a) && REALP(b)) { dval = (double) BELONG_TO_LONG(a) * REAL_TO_DOUBLE(b); return DOUBLE_TO_REAL(dval); } phpnum_fail("jeepers creepers"); }
/* subtract two phpnums, potentially converting to a double. */ obj_t phpsub(obj_t a, obj_t b) { if (ELONGP(a) && ELONGP(b)) { long lval = BELONG_TO_LONG(a) - BELONG_TO_LONG(b); /* if (WITHIN_PDL_RANGE(dval)) { */ /* return GET_PDL(dval); */ /* } else */ if ( (BELONG_TO_LONG(a) & PHP_LONGMIN) != (BELONG_TO_LONG(b) & PHP_LONGMIN) && (BELONG_TO_LONG(a) & PHP_LONGMIN) != (lval & PHP_LONGMIN) ) { return DOUBLE_TO_REAL((double) BELONG_TO_LONG(a) - (double) BELONG_TO_LONG(b)); } else { return LONG_TO_ONUM(lval); } } if ((REALP(a) && ELONGP(b)) || (ELONGP(a) && REALP(b))) { double dval = (REALP(a) ? (REAL_TO_DOUBLE(a) - ((double) BELONG_TO_LONG (b))) : ((double) BELONG_TO_LONG (a) - REAL_TO_DOUBLE(b))); return DOUBLE_TO_REAL(dval); } if (REALP(a) && REALP(b)) { double dval = REAL_TO_DOUBLE(a) - REAL_TO_DOUBLE(b); return DOUBLE_TO_REAL(dval); } phpnum_fail("phpsub: unknown operand types"); }
/* add two phpnums, potentially converting to a double. */ obj_t phpadd(obj_t a, obj_t b) { if (ELONGP(a) && ELONGP(b)) { long lval = BELONG_TO_LONG( a ) + BELONG_TO_LONG( b ); /* if (WITHIN_PDL_RANGE(dval)) { */ /* return GET_PDL(dval); */ /* } else */ if ( (BELONG_TO_LONG(a) & PHP_LONGMIN) == (BELONG_TO_LONG(b) & PHP_LONGMIN) && (BELONG_TO_LONG(a) & PHP_LONGMIN) != (lval & PHP_LONGMIN) ) { return DOUBLE_TO_REAL( (double)BELONG_TO_LONG( a ) + (double)BELONG_TO_LONG( b ) ); } else { return LONG_TO_ONUM( lval ); } } if ((REALP(a) && ELONGP(b)) || (ELONGP(a) && REALP(b))) { double dval = (ELONGP(a) ? (((double) BELONG_TO_LONG(a)) + REAL_TO_DOUBLE(b)) : ((REAL_TO_DOUBLE(a) + ((double) BELONG_TO_LONG(b))))); return DOUBLE_TO_REAL(dval); } if (REALP(a) && REALP(b)) { double dval = REAL_TO_DOUBLE(a) + REAL_TO_DOUBLE(b); return DOUBLE_TO_REAL(dval); } phpnum_fail("I'm lost!"); }
/* get the value of a phpnum as a long. doesn't mutate the phpnum. */ long phpnum_to_long(obj_t a) { if (REALP(a)) { return (REAL_TO_DOUBLE(a) > PHP_LONGMAX) ? (unsigned long) REAL_TO_DOUBLE(a) : (long) REAL_TO_DOUBLE(a); } else { return BELONG_TO_LONG(a); } }
/* get the value of a phpnum as a double. doesn't mutate the phpnum. */ double phpnum_to_double(obj_t a) { if (ELONGP(a)) { return (double)BELONG_TO_LONG(a); } else { return REAL_TO_DOUBLE(a); } }
double attribute_align_arg mpg123_geteq(mpg123_handle *mh, enum mpg123_channels channel, int band) { double ret = 0.; #ifndef NO_EQUALIZER /* Handle this gracefully. When there is no band, it has no volume. */ if(mh != NULL && band > -1 && band < 32) switch(channel) { case MPG123_LEFT|MPG123_RIGHT: ret = 0.5*(REAL_TO_DOUBLE(mh->equalizer[0][band])+REAL_TO_DOUBLE(mh->equalizer[1][band])); break; case MPG123_LEFT: ret = REAL_TO_DOUBLE(mh->equalizer[0][band]); break; case MPG123_RIGHT: ret = REAL_TO_DOUBLE(mh->equalizer[1][band]); break; /* Default case is already handled: ret = 0 */ } #endif return ret; }
/* convert a phpnum to a string. precision is irrelevant for longs. */ obj_t phpnum_to_string(obj_t a, int precision, int efg, int style) { int actual_length; #define ARB_STRING_SIZE 1024 char result[ARB_STRING_SIZE]; if (REALP(a)) { double dval = REAL_TO_DOUBLE(a); while (1) { switch (efg) { case 0: actual_length = pcc_snprintf(result, ARB_STRING_SIZE, E_FORMAT, precision, dval); break; case 1: actual_length = pcc_snprintf(result, ARB_STRING_SIZE, F_FORMAT, precision, dval); break; case 2: if (style == 0) { // echo actual_length = snprintf(result, ARB_STRING_SIZE, G_FORMAT, precision, dval); } else { // var_dump actual_length = pcc_snprintf(result, ARB_STRING_SIZE, G_FORMAT, precision, dval); } break; default: phpnum_fail("bad value for efg"); } /* this bit is from man snprintf. */ if (actual_length > -1 && actual_length < ARB_STRING_SIZE) return string_to_bstring_len(result, actual_length); if (actual_length > -1) /* glibc 2.1 */ phpnum_fail("Arbitrary constant not large enough"); else /* glibc 2.0 */ phpnum_fail("Arbitrary constant not large enough"); } } else { //long long lval = BELONG_TO_LONG(a); /* same game as above */ while (1) { actual_length = snprintf(result, ARB_STRING_SIZE, "%ld", lval); if (actual_length > -1 && actual_length < ARB_STRING_SIZE) return string_to_bstring_len(result, actual_length); if (actual_length > -1) phpnum_fail("Arbitrary constant not large enough"); else phpnum_fail("Arbitrary constant not large enough"); } } phpnum_fail("Reached end of phpnum_to_string unexpectedly."); }