	// constants
	
	var PRECISION = 4;
	var preff_array;
	var preff_array_size = 0;
	
//////////////////////////////////////////////////////////////////////////////////////////
	function swap_R()
	{
		var temp;
		temp = max_r1;
		max_r1 = min_r1;
		min_r1 = temp;
		
		temp = max_r2;
		max_r2 = min_r2;
		min_r2 = temp;
	}
//////////////////////////////////////////////////////////////////////////////////////////
	function update_resistors()
	{

			document.divider_form.typ_r1.value  = parseFloat( typ_r1.toPrecision(3) );
			document.divider_form.min_r1.value  = parseFloat( min_r1.toPrecision(PRECISION) );
			document.divider_form.max_r1.value  = parseFloat( max_r1.toPrecision(PRECISION) );

			document.divider_form.typ_r2.value  = parseFloat( typ_r2.toPrecision(3) );
			document.divider_form.min_r2.value  = parseFloat( min_r2.toPrecision(PRECISION) );
			document.divider_form.max_r2.value  = parseFloat( max_r2.toPrecision(PRECISION) );
	}
//////////////////////////////////////////////////////////////////////////////////////////
	function update_voltages()
	{
		document.divider_form.typ_V_out.value  = parseFloat( typ_V_out.toPrecision(PRECISION) );
		document.divider_form.min_V_out.value  = parseFloat( min_V_out.toPrecision(PRECISION) );
		document.divider_form.max_V_out.value  = parseFloat( max_V_out.toPrecision(PRECISION) );
		
		document.divider_form.typ_V_in.value  = parseFloat( typ_V_in.toPrecision(PRECISION) );
		document.divider_form.max_V_in.value  = parseFloat( max_V_in.toPrecision(PRECISION) );
		document.divider_form.min_V_in.value  = parseFloat( min_V_in.toPrecision(PRECISION) );
	}
//////////////////////////////////////////////////////////////////////////////////////

	function nearest_preff(ideal)
	{		
		if(document.divider_form.series[0].checked == true)
		{
			return nearestE6(ideal);
		}
		
		if(document.divider_form.series[1].checked == true)
		{		
			return nearestE12(ideal);
		}
		
		if(document.divider_form.series[2].checked == true)
		{
			return nearestE24(ideal);
		}
		
		if(document.divider_form.series[3].checked == true)
		{
			return nearestE48(ideal);
		}
		
		if(document.divider_form.series[4].checked == true)
		{
			return nearestE96(ideal);
		}
	}
	
	//////////////////////////////////////////////////////////////////////////////////////
	function set_preff_series()
	{		
		if(document.divider_form.series[0].checked == true)
		{
			preff_array = new Array(100,150,220,330,470,680,1000,1500);
			preff_array_size = 6;
		}

		if(document.divider_form.series[1].checked == true)
		{		
			preff_array = new Array(100,120,150,180,220,270,330,390,470,560,680,820,1000,1200);
			preff_array_size = 12;
		}

		if(document.divider_form.series[2].checked == true)
		{
			preff_array = new Array(100,110,120,130,150,160,180,200,220,240,270,300,330,360,390,430,470,510,560,620,680,750,820,910,1000, 1100);
			preff_array_size = 24;
		}

		if(document.divider_form.series[3].checked == true)
		{
			preff_array = new Array(100,105,110,115,121,127,133,140,147,154,162,169,
						178,187,196,205,215,226,237,249,261,274,287,301,
						316,332,348,365,383,402,422,442,464,487,511,536,
						562,590,619,649,681,715,750,787,825,866,909,953,1000, 1050);
			preff_array_size = 48;
		}

		if(document.divider_form.series[4].checked == true)
		{
			preff_array = new Array(100,102,105,107,110,113,115,118,121,124,127,130,133,137,140,143,147,150,154,158,162,165,169,174,
							178,182,187,191,196,200,205,210,215,221,226,232,237,243,249,255,261,267,274,280,287,294,301,309,
							316,324,332,340,348,357,365,374,383,392,402,412,422,432,442,453,464,475,487,499,511,523,536,549,
							562,576,590,604,619,634,649,665,681,698,715,732,750,768,787,806,825,845,866,887,909,931,953,976,1000, 1020);
			preff_array_size = 96;
		}
	}
	
	//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	
	function preff_values(i)
	{		
		if(i >= preff_array_size)
		{
			return preff_array[preff_array_size -1];
		}

		return preff_array[i];
	}
	//////////////////////////////////////////////////////////////////////////////////////
	function get_r_tol()
	{
		if(document.divider_form.r_tol[0].checked == true)
		{
			// 5% tolerance
			return 0.05;
		}
				
		if(document.divider_form.r_tol[1].checked == true)
		{		
			// 1% tolerance
			return 0.01;
		}
		
		if(document.divider_form.r_tol[2].checked == true)
		{
			// 0.5% tolerance
			return 0.005;
		}
		
		if(document.divider_form.r_tol[3].checked == true)
		{
			// 0.1% tolerance
			return 0.001;
		}
		
		if(document.divider_form.r_tol[4].checked == true)
		{
			// other tolerance, so read from text field
			r_tol = parseFloat(document.divider_form.r_tolerance.value) / 100.0;
					
			if( isNaN(r_tol) )
				r_tol = 0;
			return r_tol;
		}
	}
	
	//////////////////////////////////////////////////////////////////////////////////////
	function get_v_tol()
	{
		if(document.divider_form.v_tol[0].checked == true)
		{
			// 5% tolerance
			return 0.05;
		}
		
		if(document.divider_form.v_tol[1].checked == true)
		{		
			// 1% tolerance
			return 0.01;
		}
		
		if(document.divider_form.v_tol[2].checked == true)
		{
			// 0.5% tolerance
			return 0.005;
		}
		
		if(document.divider_form.v_tol[3].checked == true)
		{
			// 0% tolerance, i.e. perfect
			return 0;
		}
		
		if(document.divider_form.v_tol[4].checked == true)
		{
			// other tolerance, so read from text field
			v_tol = parseFloat(document.divider_form.v_tolerance.value) / 100.0;
			
			if( isNaN(v_tol) )
				v_tol = 0;
				
			return v_tol;
		}
	}
	//////////////////////////////////////////////////////////////////////////////////////
	function calculate_v_in()
	{

	// read values from form
		V_out = parseFloat(document.divider_form.V_out.value);
		r1    = parseFloat(document.divider_form.r1.value);
		r2    = parseFloat(document.divider_form.r2.value);
		r_tol = get_r_tol();
		v_tol = get_v_tol();


	// check for -ve impedances
		if(r1 < 0)
		{
			r1=-r1;
			document.divider_form.r1.value = parseFloat(r1);
			alert("I cannot handle negative resistances. Sign will be ignored and R1 set to "+r1+" Ohms");
		}

		if(r2 < 0)
		{
			r2=-r2;
			document.divider_form.r1.value = parseFloat(r2);
			alert("I cannot handle negative resistances. Sign will be ignored and R2 set to "+r2+" Ohms");
		}

		// calculate V_in
		V_in = V_out*(r1+r2)/r2;
		
		// write ideal answers to form
		
		document.divider_form.V_in.value  = parseFloat( V_in.toPrecision(PRECISION) );
	
		// calculate max, min , typical values
		typ_r1 = r1;
		min_r1 = (1-r_tol)*typ_r1;
		max_r1 = (1+r_tol)*typ_r1;
	
		typ_r2 = r2;
		min_r2 = (1-r_tol)*typ_r2;
		max_r2 = (1+r_tol)*typ_r2;

		// if v_out is fixed the highest V_in will occur when R2 is at a minimum
		// and R1 is at a maximum so need to swap R max and R min

		swap_R();
		
		typ_V_out = V_out;
		min_V_out = (1-v_tol)*V_out
		max_V_out = (1+v_tol)*V_out
		
		typ_V_in = typ_V_out*(typ_r2+typ_r1)/typ_r2;
		max_V_in = max_V_out*(max_r2+min_r1)/max_r2;
		min_V_in = min_V_out*(min_r2+max_r1)/min_r2;

		
		//write R1 values to form
		
		document.divider_form.typ_r1.value  = parseFloat( r1 );
		document.divider_form.min_r1.value  = parseFloat( min_r1.toPrecision(PRECISION) );
		document.divider_form.max_r1.value  = parseFloat( max_r1.toPrecision(PRECISION) );
		
		//write R2 values to form
		document.divider_form.typ_r2.value  = parseFloat( r2 );
		document.divider_form.min_r2.value  = parseFloat( min_r2.toPrecision(PRECISION) );
		document.divider_form.max_r2.value  = parseFloat( max_r2.toPrecision(PRECISION) );
	
		// write v_out values to form
		document.divider_form.typ_V_out.value  = parseFloat( typ_V_out );
		document.divider_form.min_V_out.value  = parseFloat( min_V_out );
		document.divider_form.max_V_out.value  = parseFloat( max_V_out );

		
		document.divider_form.typ_V_in.value  = parseFloat( (typ_V_in.toPrecision(PRECISION)) );
		document.divider_form.max_V_in.value  = parseFloat( (max_V_in.toPrecision(PRECISION)) );
		document.divider_form.min_V_in.value  = parseFloat( (min_V_in.toPrecision(PRECISION)) );
	}

//////////////////////////////////////////////////////////////////////////////////////////////////////
	function calculate_v_out()
	{

	// read values from form
		V_in = parseFloat(document.divider_form.V_in.value);
		r1    = parseFloat(document.divider_form.r1.value);
		r2   = parseFloat(document.divider_form.r2.value);
		r_tol = get_r_tol();
		v_tol = get_v_tol();

	// check for -ve impedances
		if(r1 < 0)
		{
			r1=-r1;
			document.divider_form.r1.value = parseFloat(r1);
			alert("I cannot handle negative resistances. Sign will be ignored and R1 set to "+r1+" Ohms");
		}

		if(r2 < 0)
		{
			r2=-r2;
			document.divider_form.r1.value = parseFloat(r2);
			alert("I cannot handle negative resistances. Sign will be ignored and R2 set to "+r2+" Ohms");
		}

		// calculate V_out
		V_out = V_in*r2/(r1+r2);
		
		// write answers to form
		
		document.divider_form.V_out.value  = parseFloat( V_out.toPrecision(PRECISION) );


		// calculate max, min , typical values
		typ_r1 = r1;
		min_r1 = (1-r_tol)*typ_r1;
		max_r1 = (1+r_tol)*typ_r1;
	
		typ_r2 = r2;
		min_r2 = (1-r_tol)*typ_r2;
		max_r2 = (1+r_tol)*typ_r2;

		typ_V_in = V_in;
		min_V_in = (1-v_tol)*V_in
		max_V_in = (1+v_tol)*V_in

		typ_V_out = typ_V_in*typ_r2/(typ_r2+typ_r1);
		max_V_out = max_V_in*max_r2/(max_r2+min_r1);
		min_V_out = min_V_in*min_r2/(min_r2+max_r1);

		//write R1 values to form

		document.divider_form.typ_r1.value  = parseFloat( r1 );
		document.divider_form.min_r1.value  = parseFloat( min_r1.toPrecision(PRECISION) );
		document.divider_form.max_r1.value  = parseFloat( max_r1.toPrecision(PRECISION) );

		//write R2 values to form
		document.divider_form.typ_r2.value  = parseFloat( r2 );
		document.divider_form.min_r2.value  = parseFloat( min_r2.toPrecision(PRECISION) );
		document.divider_form.max_r2.value  = parseFloat( max_r2.toPrecision(PRECISION) );

		// write v_out values to form
		document.divider_form.typ_V_out.value  = parseFloat( typ_V_out.toPrecision(PRECISION) );
		document.divider_form.min_V_out.value  = parseFloat( min_V_out.toPrecision(PRECISION) );
		document.divider_form.max_V_out.value  = parseFloat( max_V_out.toPrecision(PRECISION) );

		document.divider_form.typ_V_in.value  = parseFloat( (typ_V_in.toPrecision(PRECISION)) );
		document.divider_form.max_V_in.value  = parseFloat( (max_V_in.toPrecision(PRECISION)) );
		document.divider_form.min_V_in.value  = parseFloat( (min_V_in.toPrecision(PRECISION)) );
	}
//////////////////////////////////////////////////////////////////////////////////////////////////////
	function calculate_R1()
	{
	// read values from form
		V_in  = parseFloat(document.divider_form.V_in.value);
		V_out = parseFloat(document.divider_form.V_out.value);
		r2    = parseFloat(document.divider_form.r2.value);
		r_tol = get_r_tol();
		v_tol = get_v_tol();

	// check for -ve impedances

		if(r2 < 0)
		{
			r2=-r2;
			document.divider_form.r2.value = parseFloat(r2);
			alert("I cannot handle negative resistances. Sign will be ignored and R2 set to "+r2+" Ohms");
		}

		// calculate R1
		r1 = V_in/V_out*r2 - r2;
		typ_r1 = nearest_preff(r1);
		
		// write ideal answers to form
		
		document.divider_form.r1.value  = parseFloat( (r1.toPrecision(6)) );
		
		min_r1 = (1-r_tol)*typ_r1;
		max_r1 = (1+r_tol)*typ_r1;
		
		typ_r2 = r2;
		min_r2 = (1-r_tol)*typ_r2;
		max_r2 = (1+r_tol)*typ_r2;
		
		
		if(document.divider_form.fixed[0].checked == true) // if V_in is fixed
		{
			typ_V_in = V_in;
			min_V_in = (1-v_tol)*V_in
			max_V_in = (1+v_tol)*V_in

			typ_V_out = typ_V_in*typ_r2/(typ_r2+typ_r1);
			max_V_out = max_V_in*max_r2/(max_r2+min_r1);
			min_V_out = min_V_in*min_r2/(min_r2+max_r1);
		}
		
		else // V_out is fixed
		{
			// if v_out is fixed the highest V_in will occur when R2 is at a minimum
			// and R1 is at a maximum so need to swap R max and R min
			
			swap_R();
			
			typ_V_out = V_out;
			min_V_out = (1-v_tol)*V_out
			max_V_out = (1+v_tol)*V_out
			
			typ_V_in = typ_V_out*(typ_r2+typ_r1)/typ_r2;
			max_V_in = max_V_out*(max_r2+min_r1)/max_r2;
			min_V_in = min_V_out*(min_r2+max_r1)/min_r2;
		}
		
		update_voltages();
		
		document.divider_form.typ_r1.value  = parseFloat( typ_r1.toPrecision(3) );
		document.divider_form.min_r1.value  = parseFloat( min_r1.toPrecision(PRECISION) );
		document.divider_form.max_r1.value  = parseFloat( max_r1.toPrecision(PRECISION) );

		document.divider_form.typ_r2.value  = parseFloat( r2 );
		document.divider_form.min_r2.value  = parseFloat( min_r2.toPrecision(PRECISION) );
		document.divider_form.max_r2.value  = parseFloat( max_r2.toPrecision(PRECISION) );
	}
//////////////////////////////////////////////////////////////////////////////////////////////////////
	function calculate_R2()
	{
	// read values from form
		V_in  = parseFloat(document.divider_form.V_in.value);
		V_out = parseFloat(document.divider_form.V_out.value);
		r1    = parseFloat(document.divider_form.r1.value);
		r_tol = get_r_tol();
		v_tol = get_v_tol();

	// check for -ve impedances

		if(r1 < 0)
		{
			r1=0.0-r1;
			document.divider_form.r1.value = parseFloat(r1);
			alert("I cannot handle negative resistances. Sign will be ignored and R2 set to "+r1+" Ohms");
		}

		// calculate R2
		r2 = r1*V_out/(V_in-V_out);
		typ_r2 = nearest_preff(r2);
		
		// write ideal answers to form
		
		document.divider_form.r2.value  = parseFloat( (r2.toPrecision(6)) );
		
		min_r2 = (1-r_tol)*typ_r2;
		max_r2 = (1+r_tol)*typ_r2;

		typ_r1 = r1;
		min_r1 = (1-r_tol)*typ_r1;
		max_r1 = (1+r_tol)*typ_r1;
		
		
		if(document.divider_form.fixed[0].checked == true) // if V_in is fixed
		{
			typ_V_in = V_in;
			min_V_in = (1-v_tol)*V_in
			max_V_in = (1+v_tol)*V_in

			typ_V_out = typ_V_in*typ_r2/(typ_r2+typ_r1);
			max_V_out = max_V_in*max_r2/(max_r2+min_r1);
			min_V_out = min_V_in*min_r2/(min_r2+max_r1);	
		}
		
		else // V_out is fixed
		{
			// if v_out is fixed the highest V_in will occur when R2 is at a minimum
			// and R1 is at a maximum so need to swap R max and R min
			
			swap_R();

			typ_V_out = V_out;
			min_V_out = (1-v_tol)*V_out
			max_V_out = (1+v_tol)*V_out

			typ_V_in = typ_V_out*(typ_r2+typ_r1)/typ_r2;
			max_V_in = max_V_out*(max_r2+min_r1)/max_r2;
			min_V_in = min_V_out*(min_r2+max_r1)/min_r2;
		}
			
		update_voltages()
		// write real answers to form

		document.divider_form.typ_r2.value  = parseFloat( typ_r2.toPrecision(3) );
		document.divider_form.typ_r1.value  = parseFloat( r1 );

		document.divider_form.min_r2.value  = parseFloat( min_r2.toPrecision(PRECISION) );
		document.divider_form.min_r1.value  = parseFloat( min_r1.toPrecision(PRECISION) );

		document.divider_form.max_r2.value  = parseFloat( max_r2.toPrecision(PRECISION) );
		document.divider_form.max_r1.value  = parseFloat( max_r1.toPrecision(PRECISION) );
	}
	
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	function calculate_both_R()
	{
		// read values from form
		V_in  = parseFloat(document.divider_form.V_in.value);
		V_out = parseFloat(document.divider_form.V_out.value);
		r_tol = get_r_tol();
		v_tol = get_v_tol();
		set_preff_series();
		
		if( Math.abs(V_out) > Math.abs(V_in) )
			{
				alert("Output Voltage > input Voltage.  Results will not be valid.")
			}
			
		if( V_out > 0)
		{
			if(V_in < 0)
			{
				alert("Negative input Voltage cannot give a positive output Voltage.  Results will not be valid.")
			}
		}
		
		if( V_out < 0)
		{
			if(V_in > 0)
			{
				alert("Positive input Voltage cannot give a negative output Voltage.  Results will not be valid.")
			}
		}


		// calculate ideal values.  These are not used, but may as well right something in the boxes
		if(V_in < 2*V_out)
		{
			r1 = 1;
			r2 = V_out*r1/(V_in-V_out);
		}
		else
		{
			r2 = 1
			r1 = r2*(V_in-V_out)/V_out;
		}
		
		document.divider_form.r1.value = r1.toPrecision(6);
		document.divider_form.r2.value = r2.toPrecision(6);

			
		best_R1 = 0;
		best_R2 = 0;

		best_error = 9999999.0;
		current_error = 9999999.0;
		R2 = 0;
		R1_ideal = 0;
		R1 = 0;
		ratio = 0;
		ideal_ratio = V_out/V_in;

		for(var j = 0; j < preff_array_size; j++)
		{
			R2 = preff_values(j);
			R1_ideal = R2/ideal_ratio - R2;

			R1 = nearest_preff(R1_ideal);
			
			ratio = R2/(R2+R1);
			current_error = Math.abs(ratio - ideal_ratio);

			if( current_error < best_error)
			{
				best_error = current_error;
				best_R1 = R1;
				best_R2 = R2;
			}
		}
		
		typ_r1 = best_R1/10;
		min_r1 = (1-r_tol)*typ_r1;
		max_r1 = (1+r_tol)*typ_r1;
		
		typ_r2 = best_R2/10;
		min_r2 = (1-r_tol)*typ_r2;
		max_r2 = (1+r_tol)*typ_r2;
	

	
		if(document.divider_form.fixed[0].checked == true) // if V_in is fixed
		{	
			typ_V_in = V_in;
			min_V_in = (1-v_tol)*V_in
			max_V_in = (1+v_tol)*V_in

			typ_V_out = typ_V_in*typ_r2/(typ_r2+typ_r1);
			max_V_out = max_V_in*max_r2/(max_r2+min_r1);
			min_V_out = min_V_in*min_r2/(min_r2+max_r1);	
		}
		
		else // V_out is fixed
		{
			// if v_out is fixed the highest V_in will occur when R2 is at a minimum
			// and R1 is at a maximum so need to swap R max and R min
			
			swap_R();

			typ_V_out = V_out;
			min_V_out = (1-v_tol)*V_out
			max_V_out = (1+v_tol)*V_out

			typ_V_in = typ_V_out*(typ_r2+typ_r1)/typ_r2;
			max_V_in = max_V_out*(max_r2+min_r1)/max_r2;
			min_V_in = min_V_out*(min_r2+max_r1)/min_r2;
		}
		
		update_voltages();
		update_resistors();
	}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

