Bigdecimal userinput or double to Bigdecimal - java

I am creating a Currency converter using BigDecimal and now I am suck with an issue.
I have a user-defined number - "Amount" (this is the amount of currency you want to convert)
I am putting that userValue through the scanner class but I have only ever done this successfully with the following :
int userInput = new scanner.nextint();
I would have loved userinput to be passed as a BigDecimal
but my understanding of java is very limited.
would you suggest converting the double to BigDecimal or is there a much simple way.

If you would like to get user input as a BigDecimal then you can use one of Scanner class method nextBigDecimal() To convert existing double to BigDecimal you can use BigDecimal.valueOf() method.
Code sample:
public static void main(String[] args) {
var scanner = new Scanner(System.in);
System.out.println("Enter BigDecimal");
var number = scanner.nextBigDecimal();
System.out.println("BigDecimal from user input: " + number);
var doubleNumber = 2.15;
var decimal = BigDecimal.valueOf(doubleNumber);
System.out.println("Double converted to BigDecimal: " + decimal);
}
Listing:
Enter BigDecimal
2,15
BigDecimal from user input: 2.15
Double converted to BigDecimal: 2.15
Process finished with exit code 0
Keep in mind that while converting double to BigDecimal you may loose some accuracy of data, because double is less accurate comparing to BigDecimal.

Related

Why is nextDouble() from the Scanner method sending me "Exception"

I'm suppose to enter 2 numbers, one int that is the amount to withdraw and one double which is the balance (with a space between them). Since every withdraw charges a fee of 0.5, balance must be a double. And thats what must be printed.
I get error at nextDouble, why? I have just 1 month coding, I thought this was going to be a piece of cake, I think BASIC syntax ruined me 30 years ago :(
import java.util.Scanner;
public class Test {
public static void main(String[] args) {
//init variables
int amount;
double balance;
//insert amount and balance
Scanner input = new Scanner (System.in);
amount = input.nextInt();
balance = input.nextDouble();
//reduce amount+fee from balance
balance=balance-(amount + 0.50);
//print new balance
System.out.print(balance);
input.close();
}
}
It is dependant on Locale, try to use comma instead of a dot or vice versa.
Ex: 1,5 instead of 1.5
You can check, if there is some int or double to read.
And you have to use , or . depending on the country, you are.
If you need it country independent, read it as string and parse then (see below)
A solotion would be to read the line as a string and parse it then to int and double.
Checking if double is available:
input.hasNextDouble();
Read as String:
String line = input.nextLine();
String[] sl = line.split(" ");
amount = Integer.parseInt(sl[0]);
balance = Double.parseDouble(sl[1]); //solve the problem with . and ,
You also could check if there are enough inputs.

Rounding Decimals in Java

So, I was making a program, where I have the user insert a numerator and denominator, the program converts the pseudo-fraction, to a decimal. It works fine, just one thing. One, if I enter a fraction that is a repeating decimal, (ex. 1/3, 0.3333333...), I want either it say 0.33 repeat, or for irrational numbers, It would round it after let's say 7 digits, and then stop and have "... Irrational" after. How could I do this? Code is below.
package Conversions;
import java.util.*;
public class FractionToDecimal {
public static void main (String[] args) {
Scanner sc = new Scanner (System.in);
System.out.println("Enter Numerator: ");
int numerator = sc.nextInt();
System.out.println("Enter Denominator: ");
int denominator = sc.nextInt();
if (denominator == 0) {
System.out.println("Can't divide by zero");
}
else {
double fraction = (double)numerator / denominator;
System.out.println(fraction);
}
}
}
You could use this:
DecimalFormat df = new DecimalFormat("#.######");
df.setRoundingMode(RoundingMode.CEILING);
Add as many # as you want decimals and then ou can simply use it like this:
Double d = 12345.789123456;
System.out.println(df.format(d));
Using three # would give you for the example above: 12345.789 for instance.
Please note that you can pick your rounding mode of course.
Small other note: Next time you ask a question on SO, please show some research, there are thousands of post about this and thousands of tutorials online. It would be nice to show what you have tried, what doesn't work ...

Loss of accuracy with large values

I am having a problem with large values.
Please help me.
Scanner scanner=new Scanner(System.in);
double rate=1.0000;
double value=scanner.nextDouble();
value*=rate;
BigDecimal bigDecimal=new BigDecimal(value);
System.out.println(bigDecimal);
But when I enter the input as
121212121212121212121212121212121212121212121212
My output is
121212121212121209445819616146456785067331026944
Please help me.
How can I get values accurately?
There's no point in using BigDecimal if you are initializing it with a double, which has a limited precision.
You should initialize it with a String instead :
Scanner scanner=new Scanner(System.in);
String value=scanner.nextLine();
BigDecimal bigDecimal=new BigDecimal(value);
System.out.println(bigDecimal);
If you wish to multiple your input by a value other than 1 (multiplying by 1 is pointless), use bigDecimal.multiply(...).

NumberFormatException when parsing String to Float value [duplicate]

This question already has answers here:
How to do an Integer.parseInt() for a decimal number?
(10 answers)
Closed 4 years ago.
System.out.println("Enter a number: ");
String in1 = input.nextLine();
Integer input1 = Integer.valueOf(in1);
Float input2 = Float.parseFloat(in1);
Double input3 = Double.valueOf(in1).doubleValue();
System.out.println();
System.out.println("Enter another number: ");
String in2 = input.nextLine();
Integer input21 = Integer.valueOf(in2);
Float input22 = Float.parseFloat(in2);
Double input23 = Double.valueOf(in2).doubleValue();
FloatN fco = new FloatN();
System.out.println();
System.out.println("The sum of both of your numbers is: " + fco.add(input2, input22));
done = true;
I'm well aware that this program is completely impractical, I only wrote it to practice parsing, generics, and interfaces. I tried Integer, which worked fine, but upon trying the Float and Double.add() functions, I get 3 errors:
at java.lang.NumberFormatException.forInputString
at java.lang.Integer.parseInt
at java.lang.Integer.valueOf
I removed the Integer parsers, and the program worked fine. I'm confused as to why I get the errors only when I enter Decimal values and would like someone to help point out what exactly is causing the exception so I can avoid any errors like this in the future, and since removing the Integer parser removes any functionality from the IntegerN class.
Also, if anyone needs the FloatN class for whatever reason:
public static class FloatN implements Summization<Float>{
public FloatN(){}
public Float add(Float a, Float b)
{
return a + b;
}
}
Summization is a generic interface with an add() method.
Thanks in advance.
If you enter a decimal value as input, Integer.parseInt() method won't be able to parse it. If you still want to have them all in your code, you have to get int value of that Float value. You can use intValue() method:
Float input2 = Float.parseFloat(in1);
Integer input1 = Integer.valueOf(input2.intValue());
Maybe add string which is not contain a parsable float or it is null.
From javadoc:
NullPointerException - if the string is null
NumberFormatException - if the string does not contain a parsable float.
becuase Integer.valueOf(in2); this line will give NumberFormatException with float and double you can use
Number num = NumberFormat.getInstance().parse(myNumber);
see # http://docs.oracle.com/javase/7/docs/api/java/text/NumberFormat.html
The NumberFormatException comes in the Integer parser, and not in the Double and Float parsers if input contains decimal.
In such situations, you can get the the integer part of the decimal number using split and parse:
String[] s = in1.split("\\.");
Integer input1 = Integer.valueOf(s[0]);
Float input2 = Float.parseFloat(in1);
Double input3 = Double.valueOf(in1).doubleValue();

Java double input

I am trying to let the user freedom of entering a number at his own style like he can choose to enter 2 or 2.00 but as you know the double cannot accept this (2). i want the double to accept this with 2 decimal places only (basically i am representing money).
this is what i am not sure how to take the input and convert that in to the 2decimals format. New to java.tks
Tried google but cant find where i can format at the input itself, means dont even let the user type any more decimal places other than 2decimal places, not post-process after entered in to multiple different variables., tks
public static void add()
{
double accbal;
Scanner sc = new Scanner(System.in);
DecimalFormat df = new DecimalFormat("0.00");
System.out.println("Enter account balance");
accbal = sc.nextDouble();
//this is the part where i need to know the entered value is formated to only 2 decimal places
}
Since showing decimal places is really a formality to the end user, you could read your value in as a String instead and convert it to a Double or BigDecimal, the latter being preferred if you're working with actual finances.
Related: What Every Computer Scientist Should Know About Floating-Point Arithmetic
public static void add() {
BigDecimal accbal; // could declare a Decimal
Scanner sc = new Scanner(System.in);
DecimalFormat df = new DecimalFormat("#.00");
System.out.println("Enter account balance");
accbal = new BigDecimal(sc.nextLine());
System.out.println(df.format(accbal.doubleValue()));
}
Try this:
DecimalFormat df = new DecimalFormat ("#.##");//format to 2 places
accbal = sc.nextDouble();
System.out.print(df.format(aacbal));//prints double formatted to 2 places
however I see you say:
Tried google but cant find where i can format at the input itself,
means dont even let the user type any more decimal places other than
2decimal places
If the above is your intention for whatever reason then simply read in the input using nextLine() and then check to make sure after the decimal point it only has a length of 2:
double accbal=0;
Scanner sc = new Scanner(System.in);
while (true) {
System.out.println("Enter account balance");
String s = sc.nextLine();
if (s.substring(s.indexOf('.') + 1).length() <= 2)//accept input and convert to double
{
accbal = Double.parseDouble(s);
break; //terminates while loop
} else {
System.out.println("Incorrect input given! Decimal places cant exceed 2");
}
}
System.out.println("Balance: "+accbal);
If you want to accept input of the form "#.##" just specify a custom regex for Scanner.hasNext :-)
final Scanner input = new Scanner(System.in);
final Pattern pattern = Pattern.compile("\\d+\\.\\d{2}?");
while (input.hasNext()) {
System.out.println((input.hasNext(pattern) ? "good" : "bad")
+ ": " + input.nextDouble());
}
Using the following input:
2.00
3.14159
2
The result is: (also found here)
good: 2.0
bad: 3.14159
bad: 2.0
This way allows you to verify they enter an amount with two decimal places.
Even though you said you do not want a mere post-processing solution, in case you already have an amount and wish to convert it to use 2 decimal places, and you're focused on precision (since this is money), maybe try using BigDecimal -- in particular, see BigDecimal.setScale:
while (input.hasNextBigDecimal()) {
System.out.println(input.nextBigDecimal().setScale(2, RoundingMode.HALF_UP));
}
The output is thus:
2.00
3.14
2.00

Categories