/* * BigDecimal0.java * * Created on 08 December 2004, 16:23 */ package uk.ac.leeds.ccg.andyt.utilities; import java.math.BigDecimal; import java.math.BigInteger; /** * * @author geoagdt */ public class BigDecimal0 extends BigDecimal { /** Creates a new instance of BigDecimal0 */ public BigDecimal0( double d1 ) { super( d1 ); } /** * @param args the command line arguments */ public static void main(String[] args) { // TODO code application logic here //BigDecimal bd0 = new BigDecimal( BigInteger.ONE, 0 ); //BigDecimal bd0 = new BigDecimal( BigInteger.ONE, 1 ); //BigDecimal bd0 = new BigDecimal( BigInteger.ONE, 2 ); //BigDecimal bd0 = new BigDecimal( BigInteger.ONE, 3 ); //BigDecimal bd0 = new BigDecimal( BigInteger.ONE, 4 ); BigDecimal bd0 = new BigDecimal( BigInteger.ONE, 5 ); System.out.println( "" + bd0 ); //BigDecimal bd1 = new BigDecimal( "128902" ).add( bd0 ); BigDecimal bd1 = new BigDecimal( "0.0000000000000000000000000000002" ); int decimalPlaces = 100; sqrt0( bd1, decimalPlaces ); } /** * Returns the square root of the input BigDecimal as a BigDecimal. There * are limits to the size of BigDecimals this can handle, but they can have * Integer.MAX_VALUE numbers of digits in their decimal expansion and so * can be enormous! An exception should be thrown and caught if this is the * case but this needs implementing. */ public static BigDecimal sqrt0( BigDecimal input, int decimalPlaces ) { // Deal with special cases BigDecimal zero = new BigDecimal( BigInteger.ZERO ); if ( input.compareTo( zero ) == -1 ) { return null; } BigDecimal one = new BigDecimal( BigInteger.ONE ); if ( input.compareTo( one ) == 0 ) { return one; } // Deal with general case ( input >= 1 ) // Calculate number of digits numberOfDigits in result BigInteger b0 = input.toBigInteger(); System.out.println( b0.toString() ); int numberOfDigits = b0.toString().length() / 2; BigInteger b1; if ( numberOfDigits == 0 ) { b1 = BigInteger.ONE; } else { b1 = new BigInteger( "10" ).pow( numberOfDigits - 1 ); } // Calculate value of first digit int i = 1; BigInteger b2 = b1; BigInteger b3 = b2.multiply( new BigInteger( Integer.toString( i ) ) ); BigInteger b4 = null; while ( b0.compareTo( b2 ) == 1 ) { b4 = b3; b3 = b1.multiply( new BigInteger( Integer.toString( i ) ) ); b2 = ( b3 ).pow( 2 ); i ++; } if ( b4 == null ) { b4 = BigInteger.ONE; } System.out.println( "square root of " + input.toString() + " is between " + b4 + " and " + b3.toString() ); System.out.println( b4 + " squared is " + b4.pow( 2 ) ); System.out.println( b3 + " squared is " + b3.pow( 2 ) ); System.out.println( "Done digit 0" ); // Calculate value of remaining digits that are greater than 1 for ( int ite = 1; ite < numberOfDigits; ite ++ ) { b1 = new BigInteger( "10" ).pow( numberOfDigits - 1 - ite ); i = 1; b2 = b4; b3 = b2.add( b2.multiply( b1 ) ); while ( b0.compareTo( b2 ) == 1 ) { b4 = b3; b3 = b1.multiply( new BigInteger( Integer.toString( i ) ) ); b2 = ( b3 ).pow( 2 ); i ++; } System.out.println( "square root of " + input.toString() + " is between " + b4.toString() + " and " + b3.toString() ); System.out.println( b4.toString() + " squared is " + b4.pow( 2 ) ); System.out.println( b3.toString() + " squared is " + b3.pow( 2 ) ); System.out.println( "Done digit " + ite ); } // Iteratively approximate fractions until required precision (decimal places) is reached int roundingMode = BigDecimal.ROUND_HALF_DOWN; BigDecimal half = new BigDecimal( 0.5d ); System.out.println("" + half.toString() ); BigDecimal x = new BigDecimal( b4 ); BigDecimal y; int iteScale = decimalPlaces + 1; int divideScale = decimalPlaces + 10; do {//for ( int ite = 0; ite < 10; ite ++ ) { //System.out.println("" + input.toString() + " divide " + x.toString() + " equals " + input.divide( x, scale, roundingMode ).toString() ); y = half.multiply( ( x.add( ( input.divide( x, divideScale, roundingMode ) ) ) ) ); x = y; // System.out.println( "square root of " + input.toString() + " is nearly " + x.toString() ); System.out.println( x.toString() + " squared is " + x.multiply( x ) ); // System.out.println( "" + ( x.multiply( x ) ).setScale( scale, roundingMode ) ); } while ( ( ( x.multiply( x ) ).setScale( decimalPlaces, roundingMode ) ).compareTo( input.setScale( decimalPlaces, roundingMode ) ) != 0 ); roundingMode = BigDecimal.ROUND_DOWN; y = x.setScale( decimalPlaces, roundingMode ); System.out.println( y + " squared is " + y.multiply( y ) ); BigDecimal smallestDecimalFraction = new BigDecimal( BigInteger.ONE, decimalPlaces ); // Choose closest to return BigDecimal yplus = y.add( smallestDecimalFraction ); System.out.println( yplus + " squared is " + yplus.multiply( yplus ) ); //BigDecimal yminus = y.subtract( smallestDecimalFraction ); BigDecimal diffplus = ( yplus.multiply( yplus ) ).subtract( input ); BigDecimal diff = ( y.multiply( y ) ).subtract( input ); //BigDecimal diffminus = ( yplus.multiply( yplus ) ).subtract( input ); if ( diffplus.compareTo( diff ) == -1 ) { //if ( diffplus.compareTo( diffminus ) == -1 ) { System.out.println( "returning " + yplus ); return yplus; //} else { // return yminus; //} } else { //if ( diff.compareTo( diffminus ) == -1 ) { System.out.println( "returning " + y ); return y; //} else { // return yminus; //} } } /** * Returns the square root of the input BigDecimal as a BigDecimal. There * are limits to the size of BigDecimals this can handle, but they can have * Integer.MAX_VALUE numbers of digits in their decimal expansion and so * can be enormous! An exception should be thrown and caught if this is the * case but this needs implementing. */ public static BigDecimal sqrt1( BigDecimal input, int decimalPlaces ) { System.out.println( "sqrt(" + input + "," + decimalPlaces + ") {"); BigDecimal result; int inputScale = input.scale(); BigInteger bi0 = input.unscaledValue(); System.out.println( "bi0 " + bi0 ); int numberOfDigits = ( bi0.toString().length() - 1 ) / 2; BigInteger bi1 = new BigInteger( "10" ).pow( numberOfDigits ); System.out.println( "bi1 " + bi1 ); int i = 1; BigInteger bi2 = bi1; BigInteger bi3 = bi2.multiply( new BigInteger( Integer.toString( i ) ) ); BigInteger bi4 = null; while ( bi0.compareTo( bi2 ) == 1 ) { bi4 = bi3; bi3 = bi1.multiply( new BigInteger( Integer.toString( i ) ) ); bi2 = ( bi3 ).pow( 2 ); i ++; } System.out.println( "square root of " + bi0.toString() + " is between " + bi4.toString() + " and " + bi3.toString() ); System.out.println( bi4.toString() + " squared is " + bi4.pow( 2 ) ); System.out.println( bi3.toString() + " squared is " + bi3.pow( 2 ) ); System.out.println( "Done 0" ); for ( int ite = 1; ite < numberOfDigits + 1; ite ++ ) { bi1 = new BigInteger( "10" ).pow( numberOfDigits - ite ); i = 1; bi2 = bi4; bi3 = bi2.add( bi2.multiply( bi1 ) ); while ( bi0.compareTo( bi2 ) == 1 ) { bi4 = bi3; bi3 = bi1.multiply( new BigInteger( Integer.toString( i ) ) ); bi2 = ( bi3 ).pow( 2 ); i ++; } System.out.println( "square root of " + bi0.toString() + " is between " + bi4.toString() + " and " + bi3.toString() ); System.out.println( bi4.toString() + " squared is " + bi4.pow( 2 ) ); System.out.println( bi3.toString() + " squared is " + bi3.pow( 2 ) ); System.out.println( "Done " + ite ); } // // y = (1/2)(x + a/x). // int roundingMode = BigDecimal.ROUND_HALF_EVEN; // //BigDecimal one = new BigDecimal( BigInteger.ONE ); // //BigDecimal two = new BigDecimal( new BigInteger( "2" ) ); // //BigDecimal half = one.divide( two, scale, roundingMode ); // BigDecimal half = new BigDecimal( 0.5d ); // System.out.println("" + half.toString() ); // BigDecimal x = new BigDecimal( b4 ); // BigDecimal y; // int divideScale = inputScale * 2; // // do {//for ( int ite = 0; ite < 10; ite ++ ) { // //System.out.println("" + input.toString() + " divide " + x.toString() + " equals " + input.divide( x, scale, roundingMode ).toString() ); // y = half.multiply( ( x.add( ( input.divide( x, divideScale, roundingMode ) ) ) ) ); // x = y; // // System.out.println( "square root of " + input.toString() + " is nearly " + x.toString() ); // // System.out.println( x.toString() + " squared is " + x.multiply( x ) ); // // System.out.println( "" + ( x.multiply( x ) ).setScale( scale, roundingMode ) ); // //} while ( ( ( x.multiply( x ) ).setScale( scale, roundingMode ) ).compareTo( input ) != 0 ); // } while ( ( ( x.multiply( x ) ).setScale( inputScale, roundingMode ) ).compareTo( input ) != 0 ); // y = x.setScale( decimalPlaces, roundingMode ); // System.out.println( y.toString() + " squared is " + y.multiply( y ) ); // // BigDecimal check = new BigDecimal( BigInteger.ONE, decimalPlaces ); // System.out.println( y.add(check).toString() + " squared is " + y.add(check).multiply( y.add(check) ) ); // System.out.println( y.subtract(check).toString() + " squared is " + y.subtract(check).multiply( y.subtract(check) ) ); // //System.out.println( "" + y ); // return y; return null; } // public static BigDecimal abs( BigDecimal input ) { // if ( input.signum() = 1 ) // input.s // } }