def _floor(space, d): """ floor - Round fractions down""" d = d.as_number(space) if isinstance(d, W_IntObject): return W_FloatObject(d.float_w(space)) elif isinstance(d, W_FloatObject): try: return W_FloatObject(math.floor(rpy_round(d.floatval, 2))) except OverflowError: return W_FloatObject(rfloat.INFINITY) else: return space.w_False
def test_floatval_object(self): with self.warnings([ 'Notice: Object of class stdClass ' 'could not be converted to double' ]): output, = self.run('echo floatval(new stdClass);') assert output == W_FloatObject(1.)
def create_float_const(self, v): try: return self.float_cache[v] except KeyError: a = len(self.consts) self.consts.append(W_FloatObject(v)) self.float_cache[v] = a return a
def _convert_octal(s, i): value_int = 0 value_float = 0.0 while True: c = nextchr(s, i) if '0' <= c <= '7': digit = ord(c) - ord('0') else: break value_int = intmask((value_int * 8) + digit) value_float = (value_float * 8.0) + digit i += 1 fully_processed = i == len(s) if abs(float(value_int) - value_float) < _OVERFLOWED: return W_IntObject(value_int), fully_processed else: # overflowed at some point return W_FloatObject(value_float), fully_processed
def _convert_hexadecimal(s, i): value_int = 0 value_float = 0.0 fully_processed = False while True: c = nextchr(s, i) if '0' <= c <= '9': digit = ord(c) - ord('0') elif 'A' <= c <= 'F': digit = ord(c) - ord('A') + 10 elif 'a' <= c <= 'f': digit = ord(c) - ord('a') + 10 else: break value_int = intmask((value_int * 16) + digit) value_float = (value_float * 16.0) + digit fully_processed = True i += 1 fully_processed = fully_processed and i == len(s) if abs(float(value_int) - value_float) < _OVERFLOWED: return W_IntObject(value_int), fully_processed else: # overflowed at some point return W_FloatObject(value_float), fully_processed
def test_floatval(self, input, expected): output, = self.run('echo floatval(%s);' % input) assert output == W_FloatObject(expected)
def newfloat(self, v): return W_FloatObject(v)
def convert_string_to_number(s, can_be_octal=False): """Returns (wrapped number, flag: number-fully-processed).""" i = _whitespaces_in_front(s) forced_float = False negative_sign = False at_least_one_digit = False if nextchr(s, i) == '-': negative_sign = True i += 1 elif nextchr(s, i) == '+': i += 1 elif nextchr(s, i) == '0': if nextchr(s, i + 1) in 'xX': return _convert_hexadecimal(s, i + 2) if can_be_octal: return _convert_octal(s, i + 1) value_int = 0 value_float = 0.0 while nextchr(s, i).isdigit(): digit = ord(s[i]) - ord('0') value_int = intmask((value_int * 10) + digit) value_float = (value_float * 10.0) + digit if abs(value_int - value_float) < _OVERFLOWED: value_float = float(value_int) # force equal at_least_one_digit = True i += 1 if nextchr(s, i) == '.': i += 1 fraction = 1.0 while nextchr(s, i).isdigit(): digit = ord(s[i]) - ord('0') fraction *= 0.1 value_float += fraction * digit at_least_one_digit = True i += 1 forced_float |= at_least_one_digit if nextchr(s, i) in 'Ee' and at_least_one_digit: at_least_one_digit = False negative_exponent = False i += 1 if nextchr(s, i) == '-': negative_exponent = True i += 1 elif nextchr(s, i) == '+': i += 1 exponent = 0 while nextchr(s, i).isdigit(): digit = ord(s[i]) - ord('0') exponent = exponent * 10 + digit if exponent > 99999: exponent = 99999 # exponent is huge enough already at_least_one_digit = True i += 1 if negative_exponent: exponent = -exponent try: value_float *= math.pow(10.0, exponent) except OverflowError: value_float = 0.0 # value_float *= math.pow(10.0, exponent) forced_float |= at_least_one_digit if negative_sign: value_int = intmask(-value_int) value_float = -value_float fully_processed = at_least_one_digit and i == len(s) if forced_float or abs(float(value_int) - value_float) > _OVERFLOWED: return W_FloatObject(value_float), fully_processed else: return W_IntObject(value_int), fully_processed