I know, there are dozens of topic like this in site but I am having trouble with 3 problems and I couldnt figure out all of them at the same time.
Actually, I am trying to make a calculator for Android but sometimes I cannot get what I am expected to.
A part of my code is;
}else if(operator.equals("/")){
if(resultScreen.indexOf("/")==0){
strNum2 = resultScreen.substring(resultScreen.indexOf("/")+1,resultScreen.length());
intNum1 = result;
}else{
strNum1 = resultScreen.substring(0,resultScreen.indexOf("/"));
strNum2 = resultScreen.substring(resultScreen.indexOf("/")+1,resultScreen.length());
intNum1 = new BigDecimal(strNum1);
}
intNum2 = new BigDecimal(strNum2);
if(intNum2.equals(0)){
tvScreen.setText("Err");
resultScreen ="";
}else{
result = intNum1.divide(intNum2);
resultScreen = result.toString();
tvScreen.setText(resultScreen);
resultScreen ="";
}
}
When I try to;
22/7
It comes up;
3
How can I fix that?
By the way, I want to keep the exact value of decimal.
This works
BigDecimal a = new BigDecimal("22");
BigDecimal b = new BigDecimal("3");
BigDecimal res = a.divide(b, 2, RoundingMode.HALF_UP);
System.out.println(res);
The key thing is to have a roundingMode else if the value can not be represented exactly an Exception will be thrown.
Related
I have two values and I am trying to compare them, but getting the worng results:
public void subtotal() throws Exception {
WebDriverWait wait = new WebDriverWait(session.driver, 100);
double subtotal_price = 0;
DecimalFormat decimal = new DecimalFormat("0.00");
WebElement subtotal = wait.until(ExpectedConditions.visibilityOf( element("Subtotal_cart")));
Float subtotal_value = Float.parseFloat(subtotal.getText().substring(1));
logger.info("subtotal_value"+subtotal_value);
File file = new File("ItemUPC/ItemUPC.txt");
Scanner sc = new Scanner(file);
while (sc.hasNextLine()) {
String[] line = sc.nextLine().split("[|]");
String price = line[2];
subtotal_price = subtotal_price + Double.parseDouble(price);
}
logger.info("subtotal_price"+subtotal_price);
if ((subtotal_value)==(subtotal_price))
{
logger.info("Subtotals updated");
}
else
{
logger.info("Subtotals not updated");
}
}
The following is the ItemUPC file:
2|BATH BENCH|19.00
203|ORANGE BELL|1.78
When I print the value of subtotal_price and Subtotal_value I am getting both as 20.78, but when its getting compared in the if statement, I am getting output as "Subtotals not updated"
Not sure where I am getting wrong. Can someone please help? Thank you.
Comparing floating point numbers can be challenging, due to differences in precision between floating point types and their binary representations of decimal numbers.
You have two simple options:
Compare the absolute value of the difference between the two values to an epsilon, or threshold, value
Use BigDecimal as a substitute for your Float and double variable types
Example 1:
// simplification that may fail in certain edge cases
static final double EPSILON = .001; // acceptable error - adjust to suit your needs
if (Math.abs(subtotal_price - subtotal_value) < EPSILON) {
logger.info("Subtotals updated");
}
// ...
Example 2:
BigDecimal subtotal_price = new BigDecimal("0");
// ...
BigDecimal subtotal_value = new BigDecimal(subtotal.getText().substring(1));
// ...
if(subtotal_price.compareTo(subtotal_value) == 0) {
logger.info("Subtotals updated");
}
// ...
Im using MPandroid chart to inflate Pie Chart, with some String JSON return
i tried to cast String value with float.parseFloat("3584907054456.48")
but it had exponent value when i log it, something like this 3584907E12
i need to get float value 3584907054456.48
is it possible ?
List<String> dataStackedSalesVolume1;
List<String> dataStackedSalesVolume2;
float[] firstDataStacked = new float[counte];
float[] secondDataStacked = new float[counte];
int counte = merchantECommerceDataAll.getData().getMerchantECommerceTipekartuList().getMerchantECommerceTipeKartuData().get(1).getDataSalesVolume().size();
dataStackedSalesVolume1 = merchantECommerceDataAll.getData().getMerchantECommerceTipekartuList().getMerchantECommerceTipeKartuData().get(0).getDataSalesVolume();
dataStackedSalesVolume2 = merchantECommerceDataAll.getData().getMerchantECommerceTipekartuList().getMerchantECommerceTipeKartuData().get(1).getDataSalesVolume();
for (int i=0; i< counte; i++) {
firstDataStacked[i] = Float.parseFloat(dataStackedSalesVolume1.get(i));
secondDataStacked[i] = Float.parseFloat(dataStackedSalesVolume2.get(i));
}
i tried to get the string and put it into new list and then parse that list and put parsed value into float[]
but it the results is rounded, i need to get the full length of data without rounded
Edit - The BigDecimal value can be converted to float value by using the floatValue() method. (Example - float requiredValue = bigDecimalValue.floatValue();)
Do note however that this will result in a drop in precision.
BigDecimal bigDecimalValue = new BigDecimal("3584907054456.48");
System.out.println(bigDecimalValue); //3584907054456.48
float floatValue = bigDecimalValue.floatValue();
System.out.println(floatValue); //3.58490702E12
//Formatted better to show the drop in precision.
System.out.println(String.format("%.2f", floatValue)); //3584907018240.00
Don't use float, use BigDecimal instead.
Do note that you won't be directly able to use operators such as +,-,*,etc. You'll have to use the provided methods, refer to the official documentation or an article such GeeksForGeeks articles to help you get an initial hang of it.
Sample code -
List<String> dataStackedSalesVolume1;
List<String> dataStackedSalesVolume2;
BigDecimal[] firstDataStacked = new BigDecimal[counte];
BigDecimal[] secondDataStacked = new BigDecimal[counte];
int counte = merchantECommerceDataAll.getData().getMerchantECommerceTipekartuList().getMerchantECommerceTipeKartuData().get(1).getDataSalesVolume().size();
dataStackedSalesVolume1 = merchantECommerceDataAll.getData().getMerchantECommerceTipekartuList().getMerchantECommerceTipeKartuData().get(0).getDataSalesVolume();
dataStackedSalesVolume2 = merchantECommerceDataAll.getData().getMerchantECommerceTipekartuList().getMerchantECommerceTipeKartuData().get(1).getDataSalesVolume();
for (int i=0; i< counte; i++) {
firstDataStacked[i] = new BigDecimal(dataStackedSalesVolume1.get(i));
secondDataStacked[i] = new BigDecimal(dataStackedSalesVolume2.get(i));
}
You can use something like BigDecimal.valueOf(new Double("3584907054456.48")) from java.math
After this you can divide, compare your value and so on
I'm new to the Java language (Just started about 2 weeks ago)
Basically, the user enters their year/month/day they were born on in order and I use this information to perform a math calculation that will show their age.
I need numbers from 0-9 to be taken in as 01, 02, 03... So, I searched around and found that I can use Decimal.Format and then print out the format later on.
My code crashes whenever it reaches the println(twodigits.format) part no mater where I put it. There are no errors displayed that I need to address.
Why is it doing this and is there a better way to do this? I need it to be 2 digits at all times or the calculation won't work.
Here's a part of my code, I can provide more if needed.
DecimalFormat twodigits = new DecimalFormat("00");
System.out.println("Calculating...");
Integer CurrentDate2 = Integer.valueOf(CurrentDate);
Integer BirthDate2 = Integer.valueOf(BirthDate);
int a = CurrentDate2.intValue();
int b = BirthDate2.intValue();
int age = (a - b) / 1000;
Thread.sleep(300);
System.out.println(".");
Thread.sleep(300);
System.out.println(".");
Thread.sleep(300);
System.out.println(".");
System.out.println(twodigits.format(CurrentDate));
System.out.println(twodigits.format(BirthDate));
Any help is appreciated!
What types are "CurrentDate" and "BirthDate" because it's not clear from your code? You first use them to set "CurrentDate2" and "BirthDate2". And then you use them in the println().
If I were to guess, I'd say they are of type 'String', and 'twodigits.format()' can't handle Strings, which is why it's crashing.
This takes two dates and split time on "/". It then prints them out in the format that you want.
DecimalFormat twodigits = new DecimalFormat("00");
System.out.println("Calculating...");
String CurrentDate = "01/02/2007";
String BirthDate = "02/03/2007";
String[] currentDateParts = CurrentDate.split("/");
String[] birthDateParts = BirthDate.split("/");
int cdp0 = Integer.parseInt(currentDateParts[0]);
int cdp1 = Integer.parseInt(currentDateParts[1]);
int cdp2 = Integer.parseInt(currentDateParts[2]);
int bdp0 = Integer.parseInt(birthDateParts[0]);
int bdp1 = Integer.parseInt(birthDateParts[1]);
int bdp2 = Integer.parseInt(birthDateParts[2]);
//do your calculations
System.out.println(twodigits.format(cdp0));
System.out.println(twodigits.format(cdp1));
System.out.println(twodigits.format(cdp2));
System.out.println(twodigits.format(bdp0));
System.out.println(twodigits.format(bdp1));
System.out.println(twodigits.format(bdp2));
public BigDecimal calculateTotal() {
BigDecimal percent = BigDecimal.valueOf(0.9);
int i = 0;
BigDecimal price = BigDecimal.valueOf(0.0);
while(!myOrders.isEmpty()){
if (!myOrders.get(i).getItem().isBulk() && myMembership == true){
price = price.add(myOrders.get(i).calculateOrderTotal().multiply(percent));
myOrders.remove(i);
}
else{
price = price.add(myOrders.get(i).calculateOrderTotal());
myOrders.remove(i);
}
}
//WHY IS THIS UNREACHABLE?!
return price.setScale(2, RoundingMode.HALF_EVEN);
}
I know that anything after a return statement is unreachable code, but my only return statement is unreachable and I can't figure out why. The while loop is the way it is because I'm grasping at straws, I'm aware that it probably won't do what I want it to do. myOrders is an ArrayList.
EDIT: Since OP said it is an ArrayList, my answer no longer applies.
You never update your index i. This should work:
public BigDecimal calculateTotal() {
BigDecimal percent = BigDecimal.valueOf(0.9);
int i = 0;
BigDecimal price = BigDecimal.valueOf(0.0);
while(!myOrders.isEmpty()) {
if (!myOrders.get(i).getItem().isBulk() && myMembership == true) {
price = price.add(myOrders.get(i).calculateOrderTotal().multiply(percent));
myOrders.remove(i);
} else {
price = price.add(myOrders.get(i).calculateOrderTotal());
myOrders.remove(i);
}
i++; // <-- You were missing this
}
// Not unreachable anymore :)
return price.setScale(2, RoundingMode.HALF_EVEN);
}
Your variable i is never incremented. Depending on what type of Collection myOrders is, removing the 0th element each time may not shift the elements in the collection, and myOrders will never be empty.
There is nothing in the posted code to explain the error.
Since you said your IDE is Eclipse, I suggest to clean the project.
Also, make sure to fix all other errors before looking at this one.
This error doesn't make sense,
I suspect you have other compiler errors in your project,
which somehow cause this as a strange side effect.
After you fix everything else, this one should naturally disappear.
Btw, to see clearer, here's a cleaned up version of the same code, doing exactly the same thing:
BigDecimal percent = BigDecimal.valueOf(0.9);
BigDecimal price = BigDecimal.ZERO;
while (!myOrders.isEmpty()) {
Order first = myOrders.get(0);
BigDecimal subtotal = first.calculateOrderTotal();
if (!first.getItem().isBulk() && myMembership) {
subtotal = subtotal.multiply(percent);
}
price = price.add(subtotal);
myOrders.remove(0);
}
return price.setScale(2, RoundingMode.HALF_EVEN);
Cleaning eclipse solved the problem.
I am trying to display numbers in a string dynamically, so if the number has decimal's display them but if not don"t show the .0
example: display 5.5 as 5.5 and 5.0 as 5
This is what I have so far: (answer is a double)
double temp = answer;
long temp2 = (long) temp;
if (temp == temp2) {
output = String.valueOf(temp2);
System.out.println(output);
this work's fine up to about 1e18 then will error out because of the maximum size of a Long.
So how would I achieve this on bigger numbers like 5.43e86
Use DecimalFormat
double answer = 5.0;
DecimalFormat df = new DecimalFormat("###.#");
System.out.println(df.format(answer));
The DecimalFormat suggestions are the easiest way to handle this. If they aren't sufficient, here's another idea.
If you're starting to hit the maximum values that can be represented by primitives in Java, then you may need to move to BigInteger and BigDecimal.
Try playing around with the BigDecimal.toBigInteger() method coupled with the toString() methods on BigDecimal and BigInteger.
It's not good solution
if you use new DecimalFormat("0.#") you are missing data, for example
PI = 3.14, but after parse you ae geting 3.1
Another solution to use eval%1 ? (int)d : d
this time couse max integer limit , again missing data
my solution is working, but it's not good idea
res = removeLastChars(eval,".0");
private String removeLastChars(double eval, String text){
String res = String.valueOf(eval);
int length = text.length();
if (res.length() > length){
res = res.substring((res.length() - length), res.length()).equals(text)
? res.substring(0, (res.length() - length)) : res;
}
return res;
}
Look at
http://download.oracle.com/javase/6/docs/api/java/text/DecimalFormat.html
you would want just DecimalFormat("0.0")