class ALU {

	public String floatAddition (String operand1, String operand2, int eLength, int sLength, int gLength) {
		
		if (operand1.substring(1).indexOf("1")==-1){
			return "0"+operand2;
		}
		if (operand2.substring(1).indexOf("1")==-1){
			return "0"+operand1;
		}
		
		
		
		
		
		boolean operand1IsInfinity = floatIsInfinity(operand1, eLength, sLength);
		boolean operand2IsInfinity = floatIsInfinity(operand2, eLength, sLength);
		
		if ((operand1IsInfinity && operand2IsInfinity) | (operand1.matches(String.format("(1|0)(1{%d})[01]{%d}",eLength,sLength)) || operand2.matches(String.format("(1|0)(1{%d})[01]{%d}",eLength,sLength)))){
			return "0"+repeatedString("1", eLength)+repeatedString("0", sLength-1)+"1";
		}
		
		if (operand1IsInfinity){
			return operand1;
		}
		
		if (operand2IsInfinity){
			return operand2;
		}
		
		
		String value1 = "1."+operand1.substring(eLength+1);
		String value2= "1."+operand2.substring(eLength+1);
		

		boolean operand1Denormalized = operand1.substring(1,eLength+1).equals(repeatedString("0", eLength));
		boolean operand2Denormalized = operand2.substring(1,eLength+1).equals(repeatedString("0", eLength));
		//unifies order
		int order1 = Integer.parseInt(integerTrueValue("0"+operand1.substring(1, eLength+1)));
		int order2 = Integer.parseInt(integerTrueValue("0"+operand2.substring(1, eLength+1)));
		int biggerOrder = order1;
		if (operand1Denormalized){
			//operand1 is denormalized
			value1 = "0."+value1.split("\\.")[1];
		}
		
		if (operand2Denormalized){
			//operand2 is denormalized
			value2 = "0."+value2.split("\\.")[1];
		}
		
		int originalValue1Length = value1.length();
		int originalValue2Length = value2.length();
		
		
		if (order1-order2>0){
			//uses order1
			value2 = movePoint(value2, order2-order1);
			if (value2.length()>originalValue2Length + gLength){
				value2 = value2.substring(0, originalValue2Length + gLength);
			}
		}else{
			//uses order2
			biggerOrder = order2;
			value1 = movePoint(value1, order1-order2);
			if (value1.length()>originalValue1Length + gLength){
				value2 = value2.substring(0, originalValue1Length + gLength);
			}
		}
		

		
		//add leading letter for sign
		value1 = operand1.charAt(0)+ value1;
		value2 = operand2.charAt(0)+ value2;
		
		//add ending 0 to correct bits 
		if (value1.length()<value2.length()){
			value1= value1 + repeatedString("0", value2.length()-value1.length());
		}else{
			value2 = value2+repeatedString("0", value1.length()-value2.length());
		}
		
		String totalResult = signedAddition(value1.replace(".", ""), value2.replace(".",""), value1.length()-1);
		
		//returns 0 if it's 0
		if (!totalResult.substring(2).contains("1")){
			return repeatedString("0", sLength+eLength+2);
		}
		
		
		totalResult = (new StringBuilder(totalResult)).insert(4, ".").toString();
	
		
		
		char sign = totalResult.charAt(1);
		
		if (totalResult.charAt(totalResult.indexOf(".")-2) == '1'){
			//carry exists in integer parts
			biggerOrder++;
			totalResult = movePoint(totalResult, -1);
		}
		
		while(totalResult.charAt(totalResult.indexOf(".")-1)!='1'){
			totalResult = movePoint(totalResult, 1);
			biggerOrder--;
			if (biggerOrder==0) break;
		}
		
		
		
		//Inf
		if (biggerOrder > Math.pow(2, eLength)-1){
			return "1"+sign+repeatedString("1", eLength)+repeatedString("0", sLength);
		}
		
		
		totalResult = totalResult.split("\\.")[1];
		totalResult = totalResult + repeatedString("0", sLength-totalResult.length());
		totalResult = totalResult.substring(0, sLength);
		
		StringBuilder result = new StringBuilder();
		
		result.append("0");
		result.append(sign).append(biggerOrder <= 0 ? repeatedString("0", eLength) : integerRepresentation(String.valueOf(biggerOrder), eLength));
		result.append(totalResult);
		
		return result.toString();
	}

}