private static BigInteger[] fraction(double val){
		long bits = Double.doubleToLongBits(val);
		int sign = ((bits >> 63) == 0) ? 1 : -1;
		int exp = (int)((bits >> 52) & 0x7ffL);
		if(exp == 2047){
			throw new ArithmeticException("The double value "+val+" is Infinity or NaN, can't be represented as rational number");
		}
		
		long frac = bits & 0x000fffffffffffffL ; 
		if(exp!=0){//exp==0 for denormalized number
			frac = frac | 0x0010000000000000L ;//add 1 here. 1.Signficant for normalized number
		}		
		int numOfZeros = Math.min(Long.numberOfTrailingZeros(frac),52);//if significant are all zeros, 64 returned for numberofTrailingZeros() function.
		frac = frac >>> numOfZeros;//remove zeros, unsigned shift
		
		exp = Math.max(exp-BIAS,-BIAS+1);//biased exponent, -1022 for denormalized number
		
		int numOfShifts = 52 - numOfZeros;//move the decimal point to make the maginitude a integer
		int numerExp = exp-numOfShifts;//numerator is frac*2^numerExp
		int denomExp = 0;//denominator is 1*2^0. 
		if(numerExp<0){
			denomExp = - numerExp;//numerator is frac and denominator is 2^(-numerExp)
			numerExp = 0;
		}

		//numerator is frac*2^numerExp
		int n = numOfShifts+numerExp+1;//number of bits to store numerator		
		byte[] numer = new byte[n/8+(n%8==0?0:1)];
		frac = frac<<numerExp%8; //numerator is frac*2^(numerExp%8)*2^(numerExp/8)
		for(int i = numerExp/8; i<numer.length;i++){//big-endian
			numer[numer.length-1-i] = (byte)(frac%256);
			frac = frac>>8;
		}
		BigInteger numerator = new BigInteger(sign,numer);
		
		//denominator is 2^denomExp
		n = denomExp+1;//number of bits to store denominator
		byte[] denom = new byte[n/8+(n%8==0?0:1)];
		denom[0] |= 1<<(denomExp%8);//big-endian, 2^((denomExp%8)+(8*(denom.length-1)))=2^(deomExp/8+deomExp%8)
		BigInteger denominator = new BigInteger(1,denom);
		
		return new BigInteger[]{numerator,denominator};
	}