public ExtDecimal sqrt(int scale) {
        if (type == Type.NUMBER) {
            if (this.compareTo(ExtDecimal.ZERO) >= 0) {
                double dblval = this.doubleValue();
                double dblguess = Math.sqrt(dblval);
                //ExtDecimal factor = ExtDecimal.valueOf(1 / (2 * dblguess));
                ExtDecimal half = ExtDecimal.valueOf(0.5);
                ExtDecimal guess = ExtDecimal.valueOf(dblguess);
                if (guess.compareTo(ExtDecimal.ZERO) == 0) {
                    guess = new ExtDecimal(0.00001);
                }
                ExtDecimal newguess = guess.add(ExtDecimal.ONE);
                while (guess.compareTo(newguess) != 0 && !guess.equals(newguess)) {
                    newguess = guess.plus();
                    // guess := guess - (guess^2 - this) * factor
                    // Newton's method
                    //guess = guess.subtract(guess.pow(2).setScale(scale + 2, RoundingMode.HALF_UP).subtract(this).multiply(factor).setScale(scale + 2, RoundingMode.HALF_UP));
                    // Heron's method
                    guess = guess.add(this.divide(guess, scale + 2, RoundingMode.DOWN)).multiply(half).setScale(scale + 2, RoundingMode.DOWN);
                    System.out.println("SQRTSTEP");
                }
                return guess.setScale(scale, RoundingMode.DOWN);
            } else {
                throw new ArithmeticException("sqrt of ".toString());
            }
        } else if (type == Type.POSITIVEZERO) {
            return POSITIVEZERO;
        } else if (type == Type.INFINITY) {
            return INFINITY;
        } else {
            throw new UnsupportedOperationException("sqrt of ".toString());
        }
    }