How to solve "operator * cannot be applied to java.lang.string"? - java

I have been trying to convert value to decimal such as RM108.00. I have used
the method value = String.format("%.2f", curProduct.price); and it works,
but when i want to
apply value * ShoppingCartActivity.getProductQuantity(curProduct), it says
that operator * cannot applied to java.lang.string. How do i solve this
problem? How should i make the total price into 2 decimal?
item.productPrice = (TextView) convertView
.findViewById(R.id.textViewTotal);
value = String.format("%.2f", curProduct.price);
if (mShowPrice) {
item.productPrice.setText("Total Price: " +
String.valueOf(curProduct.price *
ShoppingCartActivity.getProductQuantity(curProduct)));
} else{
item.productPrice.setText("RM" + String.valueOf(value));
}

What this means is that one of the two following methods is a string, not a number:
curProduct.price
ShoppingCartActivity.getProductQuantity(curProduct)
You can convert them to an integer (Or float, if there is a decimal in it) by using the following code:
Integer.parseInt(curProduct.price);
Float.parseFloat(curProduct.price);
It might also be worth looking at where these value are defined, and making sure to use integers/floats whenever possible, as the conversions can take some time. Integers should always be used for whole numbers (If they aren't extremely large), and floats or doubles should be used for decimal numbers. Don't use strings for numbers unless you know exactly what you are doing!

Thats because String.format() gives you a formatted String and not any other formatted datatype you expect, and you cannot operate arithmetic operators (such as +) on Strings. Why don't you try to parse all strings to datatypes by using
Double.parseDouble(value) for double
Float.parseFloat(value) for float
Integer.parseInt(value) for int
and then perform the arithmetic operations.

Related

How to convert number from double to int without rounding?

I want to calculate how many columns can fit into container. First I calculate how many columns can fit in, then I calculate number of margins for them. After that I check if they will fit in with margins, if no - reduce amount of columns by one.
Code:
int columnMargin = 50;
double result = columnContainerHBox/minimalColumnWidth;
int columnCount = (int) result; // here's the problem
int numberOfMargins = columnCount - 1;
double finalCount = columnContainerHBox/minimalColumnWidth*columnCount+columnMargin*numberOfMargins;
if(finalCount<1){
columnCount--;
}
The problem is that I don't know how to convert from double to int without rounding number. I just need to get rid of all numbers after decimal. I already tried (int) double, (int)Math.floor(double) and new DecimalFormat('#').format(double). As a double I took 1.99999999999999999999. All above was converting it to 2. Desirable result - 1;
My double is going to be completely random. It can be 1.0, 1.9999999999, 2.45, 3.5959547324 etc.
What I need is to get a whole part and completely discard everything after decimal.
You do it by casting to int, as you're already doing in the code you've presented as an attempt.
I understand that you feel unsatisfied because you think you have found a case when your attempt will round the value instead of dropping the decimal part.
You have tried with value 1.99999999999999999999 and you've noticed that casting it to int produces an int of value 2. You concluded from there that casting is not just dropping the decimal part, it is rounding to the closest whole number 2.
Your conclusion is incorrect. The number 2 is not obtained as a result of casting to int. The number 2 is a result of the compiler parsing the written literal value 1.99999999999999999999. doubles don't have infinite precision. That means you can't write as many decimals as you want and expect it to be correctly kept in a double value. doubles only offer approximations of what you're asking. So when you type the literal value 1.99999999999999999999, the compiler knows that it is incapable to represent that value exactly, and instead it will take it as the closest value that can be represented in a double.
And the representable value closest to 1.99999999999999999999 is 2. As far as the Java compiler is concerned, these two numbers are one and the same.
So when you write:
double d = 1.99999999999999999999d;
the Java compiler treats it completely equivalent to:
double d = 2d;
You'll notice that at this point, you have yet to do any attempt to drop the decimals and only keep the whole part. You've only declared a value for your double, and as far as you're concerned this value could very well have a decimal part.
Your attempt to only keep the whole value only happens when you do:
int i = (int)d;
and here the decimals are dropped and your int contains only the whole part of what the double value contained.
However, in your example, since your double value was 2.0, then taking the whole part of it is 2. That's not rounding. That's not anything else than keeping only the whole part.
The correct way to drop decimals and only keep the whole part, is to cast to int.
(If it is important to you to be able to manipulate values such as 1.99999999999999999999 and have them not be the same as 2.0, then you cannot use doubles. They don't have sufficient precision. You should use BigDecimal, with new BigDecimal("1.99999999999999999999"). The constructor must be called with a String rather than a floating-point value, since floating-point values are unable to represent the value you want.)
Math.floor() is what you are looking for https://docs.oracle.com/javase/8/docs/api/java/lang/Math.html#floor-double-
Math.floorDiv() also might be useful in your case.
I have do this but it isn't a very good solution but I have that:
public class Main {
public static void main(String args[]) {
double d = 1.9999;
String s = (""+d).contains(".") ? (""+d).substring(0, (""+d).indexOf(".")) : (""+d);
System.out.println(Integer.parseInt(s));
}
}

Java rounding a double truncates zeroes

I have below logic that rounds a double value to 2 decimal places:
public double round(double value, int places) {
BigDecimal bd = new BigDecimal(value);
bd = bd.setScale(places, RoundingMode.HALF_UP);
return bd.doubleValue();
}
It is working for most of the cases but fails to round the result to 2 decimal places in some cases, below is an example for it.
If I call this method using code round(12.503, 2), I need the result as 12.50 because I need result in 2 decimal places, but I am getting output as 12.5
Please help me how to fix this case.
A double in Java represents a mathematical number where 12.50 is the same number as 12.5. How many digits of a number are shown is a concern of converting it to a string, not of the number itself.
So better do the rounding when you convert the number to a string for output, e.g.:
System.out.printf("%5.2f", value);
You are not getting the result as 12.5.
You are receiving back a double.
Then, you have chosen some arbitrary method of displaying that double, (which you have told us nothing about,) and based on the results of applying that method you think that its value is 12.5.
You see, the thing with doubles is that they cannot be thought of as having a fixed number of decimal digits. (Or, more accurately, the number of decimal digits that they have is so huge, that nobody ever wants to see them all.) So, in all likelihood the actual value of the double that you receive, without any bias introduced by various methods of displaying it, is something akin to 12.5000000... But you need to choose the right method of displaying it in order to see what it is. If the method that you chose simply strips trailing zeros, then you may be left with the impression that you are missing a trailing zero. Or 10 trailing zeros.
So, you need to convert it back to BigDecimal before you can make any assumptions as to what result you are getting.

Parsing a floating point number with mantissa in Java

Using the standard Java Double class to parse a floating point number with mantissa seems to omit the + sign from the exponent.
For example:
Double.parseDouble("1258124354E-28") returns 1.258124354E-19, but
Double.parseDouble("1243544322E+24") returns 1.243544322E33 (not E+33)
Is there any way to get the + sign using Double, without string post-processing?
The BigDecimal class does a better job, e.g.
new BigDecimal("1243544322E+24").toString() does return 1.243544322E+33
but it is generally slower than Double, which shows in intensive processing.
You need to differentiate between the value stored in a double and its string representation.
A double doesn't store a textual representation at all. 1.243544322E33 is 1.243544322E+33. They're the same value.
Now if you want to work on how you format a double value back to a String, that's a different matter - but the parsing you're doing is fine. You're not losing any information.
Jon is correct as above, its representing it correctly in memory. If you want it to display with the + on the mantissa then you are talking about string formatting the double.
Long winded official formatter reference
import java.util.Formatter;
double myDouble = Double.parseDouble("1243544322E+24");
Formatter formatter = new Formatter();
formatter.format("%+E", myDouble); //This should return with what you want, though with an extra + infront of the number
I haven't ran this code so I'm not 100% sure it will do the job. The + in the format specifier forces it to place a + or - sign for any number... I believe that extends to the mantissa.

How to print a large number with exponential notation?

If I have a number 52000000000, and I want to print it out as 5.2E+9, how do I do that with printf?
Since it's a simple method I'll guide you through it.
You'll need two counters: one for the number itself (type double, let's call it 'num'), and one for the exponent (integer, let's call it exp). You'll need a while loop such that while num is greater than 10, divide num by 10 and increase exp by 1. So, something like 7600 should have num = 7.6, exp = 3.
Depending on your return type, you can return these values in numerous ways. A simple way would be to have return type string and return num+"E"+exp.
This can be done with printf("%.2g", 52000000000);
"g" is the conversion character for scientific notation for formatting, and ".2" specifies the precision.
You need to have a look at this : DecimalFormat
formatter = new DecimalFormat("0.#E0");
System.out.println(formatter.format(value));//value is where you store the number to be formatted

operation with integer: result is only zero - Java

I have to do an operation with integers, very simple:
a=b/c*d
where all the variables are integer, but the result is ZERO whatever is the value of the parameters. I guess that it's a problem with the operation with this type of data (int).
I solved the problem converting first in float and then in integer, but I was wondering if there is a better method.
The / operator, when used with integers, does integer division which I suspect is not what you want here. In particular, 2/5 is zero.
The way to work around this, as you say, is to cast one or more of your operands to e.g. a float, and then turn the resulting floating point value back into an integer using Math.floor, Math.round or Math.ceil. This isn't really a bad solution; you have a bunch of integers but you really do want a floating-point calculation. The output might not be an integer, so it's up to you to specify how you want to convert it back.
More importantly, I'm not aware of any syntax to do this that would be more concise and readable than (for example):
a = Math.round((float)b / c * d)
In this case, you can reorder the expression so division is performed last:
a = (b*d)/c
Be careful that b*d won't ever be large enough to overflow an int. If it might be, you could cast one of them to long:
a = (int)(((long)b*d)/c)

Categories