Search code examples
javabigdecimal

Using BigDecimal in number factorisation


I would like to archive number factorisation in java but am getting errors when try to run the program.I am also getting unrealiable results but am convinced this should work.

Below is my code

  import java.math.*;

public class FactorizerBig{
    private BigDecimal input;
    FactorizerBig(BigDecimal x){
    input = x;
    }
    public void processBig(){//main algorithm
    String s = "";
    MathContext mc = new MathContext(2); // 2 precision
    BigDecimal idx = new BigDecimal("2");
    BigDecimal z = new BigDecimal("0");
    while((idx.compareTo(input)) == -1 || (idx.compareTo(input)) == 0 ){
        int comp =  (input.remainder(idx,mc)).compareTo(z);
        if(comp != 0){
        idx = idx.add(idx);
        }else{ 
        s = s.concat(" * "+idx);
        input = input.divide(idx);
        idx = new BigDecimal("2");
        }

    }

    System.out.println(s.substring(2));
    }
}

And here is what I am getting as output

javac FactorizerBig.java Test.java && java Test
12
 2 * 2
23
Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: -2
    at java.lang.String.substring(String.java:1875)
    at FactorizerBig.processBig(FactorizerBig.java:25)
    at Test.main(Test.java:10)

Solution

  • You converted i++ into idx = idx.add(idx) which means i = i + i.

    Use idx = idx.add(BigDecimal.ONE)

    By the way, you can also replace i <= input by (idx.compareTo(input)) < 1

    import java.math.*;
    
    public class FactorizerBig {
        private BigDecimal input;
    
        FactorizerBig(BigDecimal x) {
            input = x;
        }
    
        public void processBig() {//main algorithm
            String s = "";
            MathContext mc = new MathContext(2); // 2 precision
            BigDecimal idx = new BigDecimal("2");
            BigDecimal z = new BigDecimal("0");
            while ((idx.compareTo(input)) < 1) {
                int comp = (input.remainder(idx, mc)).compareTo(z);
                if (comp != 0) {
                    idx = idx.add(BigDecimal.ONE);
                } else {
                    s = s.concat(" * " + idx);
                    input = input.divide(idx);
                    idx = new BigDecimal("2");
                }
    
            }
    
            System.out.println(s.substring(2));
        }
    }