Reputation: 11
I'm trying to make a unit conversion program but I keep receiving value as infinity. I'm not sure where I need to fix since it's not giving me errors. I only tested oz to ml to make sure I'm doing it correctly but I'm receiving infinity as the answer.
UnitConverter.java:
public class UnitConverter {
final double oz_TO_ml = 29.5735;
final double gal_TO_g = 3.78541;
final double lb_TO_kg = 0.453592;
final double inc_TO_mm = 25.4;//Inc is inches
final double ft_TO_cm = 30.48;
final double mi_TO_km = 1.60934;
double factor;
public UnitConverter(String unit) {
if (unit.equals("oz")) {
factor = oz_TO_ml;
} else if (unit.equals("gal")) {
factor = gal_TO_g;
} else if (unit.equals("lb")) {
factor = lb_TO_kg;
}
}
public double toOz(double amount) {
return (amount * factor);
}
public double fromOz(double amount) {
return (amount / factor);
}
public double toMl(double amount) {
return (amount * factor);
}
public double fromMl(double amount) {
return (amount / factor);
}
}
Calculator.java:
import java.util.Scanner;
public class Calculator {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.print("Convert from: ");
String fromUnit = in.nextLine();
System.out.print("Convert to: ");
String toUnit = in.nextLine();
UnitConverter from = new UnitConverter(fromUnit);
UnitConverter to = new UnitConverter(toUnit);
System.out.print("Value ");
double val = in.nextDouble();
double oz = from.toOz(val);
double converted = to.fromOz(oz);
System.out.println(val + " " + fromUnit + " = " + converted + " " + toUnit);
}
}
Sample input:
Convert from: oz
Convert to: ml
Value 12
Output:
12.0 oz = Infinity ml
Upvotes: 1
Views: 121
Reputation: 7700
Your UnitConverter
class constructor only knows about 3 units: oz
, gal
, and lb
. If you instantiate it with one of those, it will correctly assign the factor and be able to convert units, as seen below:
public UnitConverter(String unit) {
if (unit.equals("oz")) {
factor = oz_TO_ml;
} else if (unit.equals("gal")) {
factor = gal_TO_g;
} else if (unit.equals("lb")) {
factor = lb_TO_kg;
}
}
However, in your Calculator class, you have this line:
UnitConverter from = new UnitConverter(fromUnit);
UnitConverter to = new UnitConverter(toUnit);
If you run your program with your sample input, from is oz
and to is ml
. But if you instantiate UnitConverter
with the unit ml
, what does factor get set to? According to your constructor, it is never set, and so it retains its default value of 0.0
.
Later, you call this line:
double converted = to.fromOz(oz);
This runs the fromOz
method
public double fromOz(double amount) {
return (amount / factor);
}
Which divides by the factor, which is 0.0
. This is the source of your Infinity output.
As the other answer says, you don't need to have two UnitConverter
objects to perform this calculation. The factor is correct to convert between ounces and millilitres, so this Calculator code is sufficient.
import java.util.Scanner;
public class Calculator {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.print("Convert from: ");
String fromUnit = in.nextLine();
UnitConverter from = new UnitConverter(fromUnit);
System.out.print("Value ");
double val = in.nextDouble();
double result = from.toMl(val);
System.out.println(val + " " + fromUnit + " = " + result + " ml.");
}
}
If you wanted to keep your current calculator code, you would need to add a condition in your UnitConverter
constructor for a scalefactor for ml (1.0
). However, I think this approach is flawed because what happens, for example, when you try to convert between oz and inches? The conversion makes no sense but your architecture would not prevent it.
Upvotes: 1
Reputation: 441
public UnitConverter(String unit)
{
if (unit.equals("oz"))
{
factor = oz_TO_ml;
} else if (unit.equals("gal"))
{
factor = gal_TO_g;
} else if (unit.equals("lb"))
{ factor = lb_TO_kg;
}
}
If you pass "ml" the factor will be zero
Your design currently needs two of these but you really only need one as "oz" has everything it needs to do the conversion.
Ignore the the toUnit in your line input code and just use fromUnit
Edit : I'll show you an alternative way to do things, it just supports one convert to show the rough design. Note the method calls are now static because you will only ever need one instance of them
UnitConverter.java
public class UnitConverter
{
private static final double oz_TO_ml = 29.5735;
public static double convert(String fromType, String toType,double amount) throws IllegalArgumentException
{
if (fromType.equals("oz") && toType.equals("ml"))
{
return (amount * oz_TO_ml);
}
else
{
throw new IllegalArgumentException("The combination of converting " + fromType + " to " + toType + " is not supported");
}
}
}
Calculator.java:
import java.util.Scanner;
public class Calculator {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.print("Convert from: ");
String fromUnit = in.nextLine();
System.out.print("Convert to: ");
String toUnit = in.nextLine();
System.out.print("Value ");
double val = in.nextDouble();
System.out.println(val + " " + fromUnit + " = " + UnitConverter.convert(fromUnit,toUnit,val) + " " + toUnit);
}
}
Upvotes: 1
Reputation: 210
Initialize the factor varible with one. A java with default give 0 to primitive double,
class UnitConvertor {
final double oz_TO_ml = 29.5735;
final double gal_TO_g = 3.78541;
final double lb_TO_kg = 0.453592;
final double inc_TO_mm = 25.4;//Inc is inches
final double ft_TO_cm = 30.48;
final double mi_TO_km = 1.60934;
double factor=1;//initialize with 1
But I am still not sure that what is the check you are using if the user input is 'ml'.
Upvotes: 1