Truncating a number
How do I round a number? I am writing a program that converts an inputted temperature in Fahrenheit to celsius. The limitations were that the input has to be an integer, but the converted temperature has to have 1 decimal place.
So,here is a snippet of the code:
double degreesC;
//gets the user input in integer fahrenheit
degreesF = keyboard.nextInt();
//converts integer to double fahrenheit
double dblDegreesF = (double)degreesF;
//calculates celsius equivalent as a double
degreesC = (5 * (dblDegreesF - 32) / 9);
//prints the inputted integer then its equivalent celsius with one decimal
System.out.println(degreesF + " fahrenheit = " + degreesC + " celsius.");
The problem is, that the degreesC prints out with like 8 decimal places behind it. I have looked at BigDecimal, DecimalFormat, ROUND_UP, etc.. but I cannot find what is appropriate, and how to implement it into my code. I am very new to Java and I find that Java API lacks examples very much. Thanks for all the help!
[1058 byte] By [
eristica] at [2007-11-27 5:38:37]

Use DecimalFormat but note that it doesn't change the value. It simply gives you a String that represents the format you want.
if you just want the representation to be rounded use System.printf or String.format
System.out.printf("%.1f\n", degreesC);
orString formated = String.format("%.1f", degreesC);
rounding with BigDecimalBigDecimal big = new BigDecimal(degreesC);
big = big.setScale(1, RoundingMode.HALF_UP); // exact value
degreesC = big.doubleValue(); // rounding errors can happen here
without BigDecimaldegreesC = Math.floor(degreesC * 10.0 + 0.5) / 10.0;
[]
Or String.format() whose usage is further described in the Formatter class http://java.sun.com/javase/6/docs/api/java/util/Formatter.html
The Java Developers Almanac 1.4 is a good source of examples
http://www.exampledepot.com/egs/java.text/FormatNum.html
[Edit] Slow! I was looking - unsucessfully - for some exmples of String.format(). You could google for this: it closely resembles the printf() function of C and other languages.
rounding with BigDecimal
BigDecimal big = new BigDecimal(degreesC);
big = big.setScale(1, RoundingMode.HALF_UP); // exact value
degreesC = big.doubleValue(); // rounding errors can happen here
--
I used this method and it worked. I am reading the API on BigDecimal but it is very very difficult to understand. Would you mind explaining it a little bit. Why did you call it "big"? Or is that part of the syntax? Also, why would big.doubleValue have rounding errors when the line above it you say it is exact ? Thanks for the help!
I was just going to divide and multiply by 1000 or whatever I needed to get the right decimal, but I knew there had to be a function built into Java that I could use. Basically, I am trying to learn all the methods and classes instead of trying to go around them :)
> bit. Why did you call it "big"? Or is that part of
because it's easy to type ;--) , it's just a (variable) name.
> the syntax? Also, why would big.doubleValue have
> rounding errors when the line above it you say it is
> exact ?
doubleValue() returns a double which has a limit number of bits for representing numbers (more than enough for degrees). Try this
System.out.println(1.04 - 1);
results in something like "0.040000000000000036" == same problem you had converting degrees.With BigDecimal you decide how many decimal digits you need.
Suppose you do the F to C conversion and obtain degreesC=1.4500000000.
Check this out:import java.math.BigDecimal;
import java.math.RoundingMode;
public class Round {
public static void main(String[] args) {
double degreesC = 1.45;
System.out.println(degreesC);
BigDecimal big = new BigDecimal(degreesC);
System.out.println(big);
big = big.setScale(1, RoundingMode.HALF_UP); // exact value
System.out.println(big);
degreesC = big.doubleValue(); // rounding errors can happen here
System.out.println(degreesC);
// same thing with a different BigDecimal constructor
System.out.println("");
big = new BigDecimal("1.45");
System.out.println(big);
big = big.setScale(1, RoundingMode.HALF_UP);
System.out.println(big);
degreesC = big.doubleValue();
System.out.println(degreesC);
}
}
It has the output1.45
1.4499999999999999555910790149937383830547332763671875
1.4
1.4
1.45
1.5
1.5As you can see the BigDecimal constructor that takes a double will result in a BigDecimal that is a little less than 1.45 and which rounds, therefore, to 1.4 The other constructor - with a String argument - doesn't do this.
I would question whether you really need to use BigDecimal at all in this case. All you are trying to do is display a numeral (a string representing a numerical value) in a way that is not too long (only has 1 decimal place). This is really a question of formatting and not rounding. What I mean is that you are changing the appearance of degreesC when it is printed, not the value of degreesC: any change can only make it less accurate.
As such the problem is no different from formatting (preparing for display) a date or a boolean value or anything else. And its the formatting methods that were suggested earlier that are most natural for this, not numerical ones.
@pbrockway2
I see what you mean. This is definately a formatting issue than a numerical one. So, what would I use to merely truncate, rather than round? Also, what kind of variable is "big"? Is it a double/float? it appears that it is its own kind.Thank you very much for the explanation, it is much much more helpful than the API which reads too technical for me.
As you know doubles and floats only use a (quite small) number of bits. Consequently there will always be some imprecision. BigDecimal is a class representing numerical magnitudes that does not suffer from this restriction. Big decimal numbers will "grow" as much as you want them to - subject only to the amount of memory and disk space in your computer, and the amount of time you can wait for arithmetic to be done on them.
"it appears to be its own kind" is about right.
Back to your question concerning degreesC. There is no reason why you shouldn't use the rules that we all learnt at school: the 5's going up business (rather than truncating). But realise that this is a matter of changing the appearance not the value of degreesC.value appearance
1.43 --> "1.4"
1.44 --> "1.4"
1.45 --> "1.5"
1.46 --> "1.5"(Writing the 1dp strings as strings with quote marks, not as numbers)
You can do this either with DecimalFormat as flounder suggested (and the Almanac link I gave has examples of this). Or with String.format() which I suggested (S_i_m_u's post gave examples of this.)
The example given of using BigDecimal for this is - I would submit - buggy in that it sometimes rounds up and sometimes truncates, depending on which way the wind is blowing. But, further, it seems a bit odd to employ a class with potentially infinite precision in order to solve a problem involving a single decimal place. It looks like what one of my teachers used to describe as "using a steam hammer to crack a walnut". The wrong tool for the job.
