I'm pretty new to Java programming and couldn't find an answer to my problem anywhere. Basically, I have successfully created a program that builds a chart of Celsius to Fahrenheit conversions and Fahrenheit to Celsius conversions, however my looped print statements are not lined up correctly after the number 9 similar this:
9.0 48.2 40.0 4.44
10.0 50.0 41.0 5.0
I was required to use two separate methods to calculate the conversions and then call them within the main method. Here is the main method with the println statement that I am reffering to:
public static void main(String[]args){
double celsius = 1;
double fahrenheit = 32;
while(celsius <= 50 && fahrenheit <= 120){
double toFarhenheit = celsiusToFahrenheit(celsius);
double toCelsius = fahrenheitToCelsius(fahrenheit);
DecimalFormat fardec = new DecimalFormat("#.##");
toFarhenheit = Double.valueOf(fardec.format(toFarhenheit));
DecimalFormat celsdec = new DecimalFormat("#.##");
toCelsius = Double.valueOf(celsdec.format(toCelsius));
System.out.println(celsius + " " + toFarhenheit + " " + fahrenheit +
" " +toCelsius);
celsius++;
fahrenheit++;
}
}
To make a long story short, is there anyway to use a printf with this kind of long print statement so that the numbers will line up with one another?
In the past I have used printf %3d and %5d and the like to line integers up, however, I couldn't get this to work at all with this particular print statement.
Any ideas and/or help would be much appreciated.
Use System.out.printf(...) and a format String to output your data in regular columns. Avoid using \t as it is unreliable. For example please look here.
Eventually your code would look like:
System.out.printf(formatString, celsius, toFarhenheit, fahrenheit, toCelsius);
Where the formatString is a String that uses printf format specifiers and width constants that would allow for pretty output. I'll let you experiment with format Strings. It would also end with "%n" so that it becomes in effect a println with formatting.
Adding to what Hovercraft Full Of Eels said, using System.out.printf without "\t" is a better solution.
For example, you should be able to do something like this:
String myformat = "%0$10s";
Explanation of the format:
%0s identifies your output as a string
$10 tells it to ensure that a minimum of 10 characters are written to the output. Hence, you'll have a fixed width.
See http://docs.oracle.com/javase/6/docs/api/java/util/Formatter.html#syntax for some more details
[haven't used java in a while so someone do correct me if I'm off]
Use \t to format them as this spaces them out evenly.
System.out.println(celsius + "\t" + toFarhenheit + "\t" + fahrenheit +
"\t" +toCelsius);
Using "\t" or using printf is probably not going to help you out as what ever space is being added takes into consideration the 2 string literals. For Eg. 9.0 is 3 chars long and 10.0 is 4 chars long.. so in this case spaces applied are correct but your string literals itself are of different length.
Try changing the code like below, use one more hash.
DecimalFormat fardec = new DecimalFormat("##.##");
Related
I am writing this program as an assignment for school. The program takes input in the form of 'sex' and 'age' from the user, and gives back the average age of all men and/or women.
The program has worked fine up until my mom beta tested it and we found a problem by happenstance. If by any chance the user were to input a number of individuals where the sum of their ages is not divisible by the number of individuals inputted, the output will give an answer with 15 decimal places.
For example if I input 3 men with the ages 98, 1 and 1, the program divides 100 by 3 and I get the output:
33.333333333333336.
So I took to SO to find a solution to this problem, and found this which I implemented in my program like below so that it would trim down the answer to a maximum of 3 decimal places:
/*
This method takes two values. The first value is divided by the second value to get the average. Then it trims the
answer to output a maximum of 3 decimal places in cases where decimals run amok.
*/
public static double average (double a, double b){
double d = a/b;
DecimalFormat df = new DecimalFormat("#.###");
return Double.parseDouble(df.format(d));
I wrote the code in the bottom of my program, in its own method, which I call in the main method at lines 76 and 77:
// Here we calculate the average age of all the people and put them into their respective variable.
double yAverage = average(yAge, men);
double xAverage = average(xAge, women);
However. I get this error message when I try to run the program, and I don't understand the error message. I tried googling the error, but found nothing.
Please keep in mind that I'm a beginner, and I need as simple an answer as anyone can give me.
Thank you in advance!
The problem is that DecimalFormat honors you Locale setting, formatting the number according to your language setting.
E.g. in US English the result is 33.333, but in Germany the result is 33,333.
However, Double.parseDouble(String s) is hardcoded to only parse US English formatting.
A few options to fix it:
Don't round the value. Recommended
Use a DecimalFormat wherever the value needs to be displayed, but keep the full precision of the value itself.
Force DecimalFormat to use US English formatting symbols.
DecimalFormat df = new DecimalFormat("#.###", DecimalFormatSymbols.getInstance(Locale.US));
Use the DecimalFormat to re-parse the value.
DecimalFormat df = new DecimalFormat("#.###");
try {
return df.parse(df.format(d)).doubleValue();
} catch (ParseException e) {
throw new AssertionError(e.toString(), e);
}
Don't convert to/from string to round to 3 decimal places.
Use Math.round(double a).
return Math.round(d * 1000d) / 1000d;
Use BigDecimal (and stick with it). Recommended
return BigDecimal.valueOf(d).setScale(3, RoundingMode.HALF_UP);
Use BigDecimal (temporarily).
return BigDecimal.valueOf(d).setScale(3, RoundingMode.HALF_UP).doubleValue();
Try this code
public static double average(double a, double b) {
double d = a / b;
DecimalFormat df = new DecimalFormat(
"#.###",
DecimalFormatSymbols.getInstance(Locale.ENGLISH)
);
return Double.parseDouble(df.format(d));
}
You're using a formatting with the point as decimal separator ("#.###"). Depending on the location where you run your program, the Java runtime uses a different localisation setting, e.g. in Germany, where a comma is used as decimal separator.
When you use new DecimalFormat("#.###") the default locale is used to interpret the string #.### which may work in some places, but won't in others. Luckily, there is another constructor for DecimalFormat where you can specify what symbols should be used. By using DecimalFormatSymbols.getInstance(Locale.ENGLISH) as second parameter you specify that you want the English formatting conventions ("." as decimal separator, "," for thousands).
required output:
Code: 123 Title: BookA Fees(SGD): $20.00
Loan Duration: 3 wks
return String.format("%-20s%-20s%\n", "Code: " + code, "Title: " + title, "%.2f\nFees(SGD): $" + fees, "Lesson Duration: " + lessonDuration + "wks");
it only returns only the first 3 (code, title, fees) but not loan duration. also where do i put in %.2f for fees so that it will always be of 2 decimal place?
Your question asks about "Loan Duration", but your example code uses "Lesson Duration". That could be your problem.
That %.2f should work for setting two decimal places. How is it behaving?
When you use String.format, you usually just pass your variables in and use the correct percent signs for your variables' types. For instance, if you want to format an integer, you use %d: String.format("Here is an integer: %d", myInt). For strings, you use %s, and for doubles, you use %f (with .2 to indicate the number of decimal places as you've already found out. You put all of your formatting in the first string parameter. All you have to do then is this:
String code = "123";
String title = "BookA";
double fees = 20.943;
int lessonDuration = 3;
String str = String.format("Code: %s\nTitle: %s\nFees(SGD): $%.2f\nLesson Duration: %d wks",
code,
title,
fees,
lessonDuration);
You should go read this article here so you understand formatting in Java and don't fail your test.
I'm doing a report, that I need to join 4 variables in one.
If I treat the variables separately I can format them with no problem.
But when I merge them into a String, the double value comes as 0.0 instead of 0.00
How can I make it comes as the original, 0.00?
The code right now looks like this:
$F{someDoubleField} + "a string" + $F{anotherDoubleField} + "another string"
It prints:
0.0 a string 0.0 another string
instead of:
0.00 a string 0.00 another string
Remember that iReport uses Java, so maybe, Java code can help me out.
Use like below:
new DecimalFormat("0.00").format(doubleField) + "str"
Do the next:
Open Properties window for your report (right-mouse click on top
node in tree view -> Properties)
Set the Language option to Java
Use such code in your text field expression:
String.format("%.2f",$V{Sum}) + " " + $F{unit}
Here
2 - number of digits after dot
$V{Sum} - Double or Floaf variable (or field - $F{...})
use DecimalFormat
here is howto:
double d = 0.00;
NumberFormat nf = new DecimalFormat("0.00");
String format = nf.format(d);
System.out.println(d); //0.00
Perhaps something like:
new DecimalFormat("0.00").format(new java.math.Double(($F{amount} == null) ? 0 : $F{amount}))
I want to convert exponential to decimal. e.g. 1.234E3 to 1234.
It is not really a conversion, but about how you display the number. You can use NumberFormat to specify how the number should be displayed.
Check the difference:
double number = 100550000.75;
NumberFormat formatter = new DecimalFormat("#0.00");
System.out.println(number);
System.out.println(formatter.format(number));
How about BigDecimal.valueOf(doubleToFormat).toPlainString()
While working with Doubles and Long numbers in Java you will see that most of the value are displayed in Exponential form.
For Example: In following we are multiplying 2.35 with 10000 and the result is printed.
//Division example
Double a = 2.85d / 10000;
System.out.println("1. " + a.doubleValue());
//Multiplication example
a = 2.85d * 100000000;
System.out.println("2. " + a.doubleValue());
Result:
2.85E-4
2.85E8
Thus you can see the result is printed in exponential format. Now you may want to display the result in pure decimal format like: 0.000285 or 285000000. You can do this simply by using class java.math.BigDecimal. In following example we are using BigDecimal.valueOf() to convert the Double value to BigDecimal and than .toPlainString() to convert it into plain decimal string.
import java.math.BigDecimal;
//..
//..
//Division example
Double a = 2.85d / 10000;
System.out.println("1. " + BigDecimal.valueOf(a).toPlainString());
//Multiplication example
a = 2.85d * 100000000;
System.out.println("2. " + BigDecimal.valueOf(a).toPlainString());
Result:
0.000285
285000000
The only disadvantage of the above method is that it generates long strings of number. You may want to restrict the value and round off the number to 5 or 6 decimal point. For this you can use java.text.DecimalFormat class. In following example we are rounding off the number to 4 decimal point and printing the output.
import java.text.DecimalFormat;
//..
//..
Double a = 2.85d / 10000;
DecimalFormat formatter = new DecimalFormat("0.0000");
System.out.println(formatter .format(a));
Result:
0.0003
I have just tried to compress this code with one line, it will print value of 'a' with two decimal places:
new DecimalFormat("0.00").format(BigDecimal.valueOf(a).toPlainString());
Happy Converting :)
you can turn it into a String using
DecimalFormat
the answer by #b.roth is correct only if it is country specific. I used that method and got i18n issue , because the new DecimalFormat("#0.00) takes the decimal seperator of the particular country. For ex if a country uses decimal seperation as "," , then the formatted value will be in 0,00 ( ex.. 1.2e2 will be 120.00 in some places and 120,00 ) in some places due to i18n issue as said here..
the method that i prefer is `(new BigDecimal("1.2e2").toPlainString() )
just add following tag to jspx:-
<f:convertNumber maxFractionDigits="4" minFractionDigits="2" groupingUsed="false"/>
String data = Long.toString((long) 3.42E8);
System.out.println("**************"+data);
try the following
long l;
double d; //It holds the double value.such as 1.234E3
l=Double.valueOf(time_d).longValue();
you get the decimal value in the variable l.
You can do:
BigDecimal
.valueOf(value)
.setScale(decimalLimit, RoundingMode.HALF_UP)
.toPlainString()
I'm returning this, it is similar to how you percieve dollars, $"32.95" etc. I calculate it in cents which is an int, but the problem is the second half cuts off the 10s of cents part if the number is less than that. For example if I have "32.08" it returns as "32.8". Any ideas ? i know i need an if but i cant think how to write it.
public String toString()
{
return (cents / 100)+ "." + (cents % 100);
}
You can use http://java.sun.com/j2se/1.5.0/docs/api/java/text/DecimalFormat.html
DecimalFormat is a concrete subclass of NumberFormat that formats decimal numbers. It has a variety of features designed to make it possible to parse and format numbers in any locale, including support for Western, Arabic, and Indic digits. It also supports different kinds of numbers, including integers (123), fixed-point numbers (123.4), scientific notation (1.23E4), percentages (12%), and currency amounts ($123). All of these can be localized.
String pattern = "$###,###.###";
double value = 12345.67;
DecimalFormat myFormatter = new DecimalFormat(pattern);
String output = myFormatter.format(value);
System.out.println(value + " " + pattern + " " + output);
// => 12345.67 $###,###.### $12,345.67
The quick hack:
return String.format("%d.%02d", cents/100, cents%100);
Use the BigDecimal class, that's what it's for.
You could always check if cents % 100 is less than 10, and if it is, add another 0. There's probably a more elegant solution though.
So, 32.08 % 100 is 8 not 08. You could of course add in a "0" for values less than 10.
However, you might want to think about using java.text, in particular NumberFormat, DecimalFormat and MessageFormat. java.util.Formatter and "printf" might be more appropriate if you are attempting to write machine readable text.
NumberFormat nf=NumberFormat.getInstance(); // Get Instance of NumberFormat
nf.setMinimumIntegerDigits(5); // The minimum Digits required is 5
return (cents / 100)+ "." + nf.format(cents % 100);
That should do it, been a while since I did java.
(""+(100+cents%100)).substring(1) // LOL
(cents / 100)+ "." + (cents /10 %10) + (cents % 10); // <<== OK
Where's the abstraction? Java's an object oriented language. Wouldn't it be a better idea to encapsulate all that implementation detail in a Money class and hide it from clients?