Refining an answer to x decimal places in java - java

I have an assignment and I need to get an input from the user to refine an answer to an x(the input of the user) number of decimal places. I'm going to refine my answer until there aren't any changes in the x decimal place.Can you please help on how I could achieve this answer?

It's not very clear what you are trying to achieve, but I think you want to accept a number and then round it up as the user specifies it.
Java's BigDecimal http://docs.oracle.com/javase/1.5.0/docs/api/java/math/BigDecimal.html class has all the functions you may need for this purpose. Please don't use the primary data types (float, double) as they will result in rounding errors sooner or later.

While it is true what #Thihara answers, maybe you need a bit simpler approach. Unless you need the precision of BigDecimal, you can do this:
int x = 4;
double value = 3.141593;
long answer = (long) (value * Math.pow(10, x));
The point is: multiply the value by 10^x and then convert to long (or int). Of course, this only works for small x.

There are a bunch of issues floating around here, that you should be aware of.
The first is that if you use a floating point number to represent your answer, you cannot represent every possible real number so you almost definitely will get rounding errors. Check out http://floating-point-gui.de/ for great information about this.
Secondly, when you print a float or double value, Java does some magic with it so that it looks nice. See Float.toString(float) and Double.toString(double) for more information.
So in reality, if you enter
double answer = 3.14159265;
it is stored as
3.141592650000000208621031561051495373249053955078125
which you can see using
System.out.println(new BigDecimal(answer));
So assuming you get your answer as a double (or float), you should use BigDecimal's setScale method. Also, if you want to limit the decimal places that your user can choose to the number visible when you print the double as a string, pass String.valueOf(answer) to BigDecimal's constructor.
Here is a little program that demonstrates how to do this
public static void main(String[] args) {
double answer = 3.14159265;
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
String input = null;
do {
System.out.println("Answer: " + answer);
System.out.println("How many decimal places do you want? ");
try {
input = in.readLine();
} catch (IOException e) {
e.printStackTrace();
}
if (input != null) {
try {
int decimalPlaces = Integer.parseInt(input);
if (decimalPlaces < 0) {
System.out.println("Enter a positive value.");
} else {
BigDecimal scaled = new BigDecimal(
String.valueOf(answer));
if (decimalPlaces > scaled.scale()) {
System.out
.println("Answer does not have that many decimal places.");
} else {
scaled = scaled.setScale(decimalPlaces,
RoundingMode.HALF_EVEN);
System.out.println("Rounded answer: " + scaled);
}
}
} catch (Exception e) {
System.out.println("Not a valid number.");
}
}
} while (input != null);
}
Most of the code is error/input checking. The real work is done by setScale. Just keep in mind that there are many boundary conditions when working with floating point numbers, and you should be good!

Related

How to remove the E7 when a number is too high? [duplicate]

Here is my simple code
#Override
public void onClick(View v) {
try {
double price = Double.parseDouble(ePrice.getText().toString());
double percent = Double.parseDouble(ePercent.getText().toString());
double priceValue = price * percent/100.0f;
double percentValue = price - priceValue;
moneyToGet.setText(String.valueOf(priceValue));
moneyToPay.setText(String.valueOf(percentValue));
moneyToGet.setText("" + priceValue);
moneyToPay.setText("" + percentValue);
// catch
} catch (NumberFormatException ex) {
// write a message to users
moneyToGet.setText("");
}
}
});
This is a simple code for Percentage Calculator.
What I want is to avoid the Scientific Notation in my Calculator cause I don't want to explain to user what is Scientific Notation.
For example if I want to calculate 100,000,000 and cut 50% of it, it Should give me 50,000,000 which is giving me 5.0E7 And in my case this doesn't make any sense to the user. And of course I know both results are correct.
Thanks in Advance.
Check answer here. You can write
moneyToGet.setText(String.format("%.0f", priceValue));
You can try this DecimalFormat
DecimalFormat decimalFormatter = new DecimalFormat("############");
number.setText(decimalFormatter.format(Double.parseDouble(result)));
I would suggest using BigDecimals instead of doubles. That way you will have a more precise control over your calculation precision. Also you can get a non-scientific String using BigDecimal.toPlainString().
DecimalFormat decimalFormatter = new DecimalFormat("##.############");
decimalFormatter.setMinimumFractionDigits(2);
decimalFormatter.setMaximumFractionDigits(15);
This option will help you ##.## suffix 0 before decimal, otherwise output will be .000
btc.setText(decimalFormatter.format(btcval));
use this for displaying content
Use NumberFormater like
NumberFormat myformatter = new DecimalFormat("########");
String result = myformatter.format(yourValue);

Java Exception Handling to Check Primitive Types

I have a GUI program that simulates a fuel station.
In the program, there are 3 input fields:
itemName
number of Units(or volume in L)
and amount in pence (per unit or litre).
You can then chose to add the item by volume, or by units. The idea is that you can buy fuel and other items (such as food), with minimal input boxes.
I'm using exception handling to check the input is what I want it to be:
An int value to add by units
and a double value to add by volume.
My code so far recognises that a double has been entered where it wants an integer, and throws the error.
For example, the input of: item Name: Chocolate, Amount(or Litres): 2.5, Price: 85 gives the error: The code used looks like this
if (e.getSource () == AddByNumOfUnits) {
try {
Integer.parseInt(NumOfUnitsField.getText());
} catch (NumberFormatException exception) {
SetErrorField("Input must be the appropriate type (real number for volume, integer for units)");
}
However when adding by volume, I can't get the program to only accept double values, or anything that uses a decimal point. An int can be passed in and accepted as a double value, which I don't want. The code I'm using is very similar:
if (e.getSource() == AddByVolume) {
try {
double itemVolume = Double.parseDouble(NumOfUnitsField.getText());
} catch (NumberFormatException exception) {
SetErrorField("Input must be the appropriate type (real number for volume, integer for units)");
}
If anyone could point me in the right direction of any way of solving this, that would be great.
Thank you
Try this. It checks if the number contains a . char which would make it a double
try {
if(!NumOfUnitsField.getText().contains(".")){
throw new NumberFormatException("Not a double");
}
double itemVolume = Double.parseDouble(NumOfUnitsField.getText());
} catch (NumberFormatException exception) {
SetErrorField("Input must be the appropriate type (real number for volume, integer for units)");
}
EDIT: combined with codeboxs answer a solution would be
try {
Pattern p = Pattern.compile("\\d+\\.\\d+");
if(!p.matcher(NumOfUnitsField.getText()).matches()){
throw new NumberFormatException("Not a double");
}
double itemVolume = Double.parseDouble(NumOfUnitsField.getText());
} catch (NumberFormatException exception) {
SetErrorField("Input must be the appropriate type (real number for volume, integer for units)");
}
Double.parseDouble() will happily accept integer values, so you should probably try a regular expression instead. This checks that you have at least 1 digit before and after a decimal point:
Pattern p = Pattern.compile("\\d+\\.\\d+");
boolean isDecimalValue = p.matcher(NumOfUnitsField.getText()).matches();

Simple Double calculation in java (Centimeter square to meter square)

I was doing a simple calculation program in java when I encountered this problem. I want to convert centimeter square to meter square. 1 cm² = 0.0001 m². When i create the program in java to do this conversion I got result in '1.0E-4' instead of '0.0001'. I don't know why it is showing in that way. may someone guide me how to do it or something that may help
Here is the code:
import java.io.*;
class First {
public static void main(String x[]) {
try {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.println("Please Enter the number");
double number = Double.parseDouble(br.readLine());
double d1 = 0.0001;
double result = number * d1;
System.out.println("Result is " + result);
} catch(Exception ex) {
ex.printStackTrace();
}
}
}
Doubles within a certain range are printed as a base and an exponent using the scientific notation.
1.0E-4 simply means 1 * 10^(-4), or 0.0001, so the answer you're getting is correct. As suggested by Smutje, you can change the way in which doubles are printed, like this.

Strange behaviour managing double and float values (Java)

I have a GUI which works like the following: there are 2 buttons and 1 textField. The textField is used to hold double/float values, 1 of the buttons adds a value (in this case, 0.1) and the other one subtracts (adds -0.1).
Here is my following problem: after pressing one of the buttons many times, the resulting value is not behaving the way I would like. In other words, instead of "1.5" turning into "1.6", it will be something like "1.5999998". I have tried many changes (like changing the variables types and the value to add/subtract), but none of these worked. Here's a piece of my code:
public void sumTextField(){
try{
if(textField.getText() == "")
textField.setText("0.1");
else{
float aux = Float.parseFloat(textField.getText());
aux += 0.10000000;
textField.setText(String.valueOf(aux));
}
}
catch(NumberFormatException nfe){
nfe.printStackTrace();
JOptionPane.showMessageDialog(null, "Please, provide a valid value in the text field!", "Impossible sum", JOptionPane.INFORMATION_MESSAGE);
}
}
public void subtractTextField(){
try{
if(textField.getText() == "")
textField.setText("-0.1");
else{
float aux = Float.parseFloat(textField.getText());
aux -= 0.10000000;
textField.setText(String.valueOf(aux));
}
}
catch(NumberFormatException nfe){
nfe.printStackTrace();
JOptionPane.showMessageDialog(null, "Please, provide a valid value in the text field!", "Impossible subtraction", JOptionPane.INFORMATION_MESSAGE);
}
}
Any ideas are welcome
Your problem is due to the way in which double and float work.
In floating-point arithmetic, the computer only calculates to a certain precision, i.e. after so many decimal places, it just rounds the number off. 0.1 may seem like a nice round number in decimal, but in binary it is recurring - 0.0001100110011 and so on. With each calculation, the rounding-off makes the result a bit more inaccurate. Have a look at this page for a more thorough explanation.
double is more precise than float, but it will still display rounding errors like this.
To circumvent the problem, you could do one of two things. First, as Jon Skeet said in the comments, you could use arbitrary-precision arithmetic like BigDecimal.
Alternatively, you could print out only a couple of decimal places like this:
String answer = String.format("%.2f", myNumber);
This will round off the printed value to 2 decimal places.
Hope this helps!

Do you have to parse a string to a double every time you want to use it?

I am writing a program where the application has text fields to enter dollar amounts.
There are methods that need to throw exceptions for items such as dollar amounts less than zero. when doing this I have check for exceptions like this:
if (Double.parseDouble(str) <= 0 || Double.parseDouble(str) > 10000)
throw new InvaildDepositAmount("Deposit Amount " + str);
else
totalBalance += amount;
My question is : Do I need to use the Double.parseDouble(str) every time I want to use this input, such in the InvalidDepositAmount class?
The simple answer is no. You can parse it once and use it as a variable later.
double depositAmount = Double.parseDouble(str);
if (depositAmount <= 0 || depositAmount > 10000)
throw new InvaildDepositAmount("Deposit Amount " + depositAmount);
else
totalBalance += depositAmount;
This is also more efficient because, what if the call to parseDouble were expensive (that is, it took a long time for it to get an answer)? Calling it once would be more efficient and easier to read in the long run.
You can just use a variable.
double x = 0;
try {
double x = Double.parseDouble(str);
} catch(Exception ex) {
throw new InvaildDepositAmount("Deposit Amount " + str)
}
if (x <= 0 || x > 10000) {
throw new InvaildDepositAmount("Deposit Amount " + str)
}
I think it makes to code readable, but I'm not sure if it makes it more efficient because the compiler or JVM could notice that and use that expression just once (and do exactly what i'm doing in the code :))
Looks like you have following cases here:
1. input field that should accept only double numbers
2. some functions which accept limited range of double numbers
Obviously you can cache entered value to avoid redundant invocation of Double.parseDouble. Also you should keep that cached value actual and update it if user changed the value in input field.
In case of exceptions related to limits in your functions you can show some popup, or update status line or whatever is suitable for your application. Or probably you want to limit input field about entered value and validate value after each change.

Categories