BigDecimal parseFactor() {
		BigDecimal v;
		boolean negate = false;
		eatSpace();
		if (c == '+' || c == '-') { // unary plus & minus
			negate = c == '-';
			eatChar();
			eatSpace();
		}
		if (c == '(') { // brackets
			eatChar();
			v = parseExpression();
			if (c == ')')
				eatChar();
		} else { // numbers
			StringBuilder sb = new StringBuilder();
			while (U.isMathExprNumberChar(c)) {
				sb.append((char) c);
				eatChar();
			}
			if (sb.length() == 0)
				throw new RuntimeException("Unexpected: " + (char) c);
			String s = sb.toString();
			if (s.startsWith("0x")) {
				v= new BigDecimal( new BigInteger(s.substring(2), 16));
			} else {
				v = new BigDecimal(s);
			}
		}
		eatSpace();
		if (c == '^') { // exponentiation
			eatChar();
			v = BigDecimal.valueOf(Math.pow(v.doubleValue(), parseFactor().doubleValue()));
		}
		if (negate) // unary minus is applied after exponentiation; e.g. -3^2=-9
			v = v.negate();

		return v;
	}