I have some problem with precised comparison of float values entered by users into an editable text field in my app. Here is example:
if ((temp>=39.0)&&(temp<=40.9)) {
ball=ball+3;
}
If user enters, for example, 40.9, the code in the loop isn't called. I am just a beginner, any help appreciated.
You should represent your literal values as 40.9f. If you omit the 'f' the type of the literal will default to double. Also check what the type is of your temp variable. You didnt show how you declare temp.
EDIT
If you declared temp as a Float or a float, and 40.9 is a double, your expression (temp <= 40.9) is comparing a float to a double, so the compiler will automatically cast the double to a float. Converting a double to a float means halving the number of bytes of the variable, so the resulting float may be very different from the expected value.
Try to create a very small margin:
float epsilon = 0.0001f;
if (39.0f - epsilon <= temp && temp <= 40.9f + epsilon)
{
}
And make sure you are parsing the user input correctly.
float temp = Float.parseFloat(inputField.getText());
Related
See screenshot:
What is going on there? i see that we're casting 23F to an int so in choice "II", we wind up doing 23/7 which should give us 3... at least so I thought. But why do we have 3.0? Why do we get a double?
Here is the context:
float x = myFunc(23F);
int myFunc(float x) { ... }
The right hand side of the expression is an int and you have correctly deduced that its value is 3.
When you assign an int value to a float variable, the integer will be converted to a float.
This is an example of a primitive widening conversion. It can happen in various contexts when you are going from a "smaller" primitive numeric type to a "larger" primitive numeric type. The int type is "smaller" than the float type. In general:
byte < short and char < int < long < float < double.
Why do we get a double?
See above. But it is a float not a double.
When you output a number in Java using println, a float and a double will look the same. The println method won't output a float with an F suffix. The F and D suffixes are only used in Java source code.
Because the function that return the result is assigned to z, and the type of z is float.
How to identify decimal portion value that exists with a float data type?
If the decimal part results as zero, exempting the decimal portion shall be a good practice. How this can be achieved when dealing with float values making it easeful?
Your variables num1 and num2 are both floats not integers as mentioned in your question, I guess that what you want to achieve is to find a way to know if a given float has decimals or not and for this you can proceed as next:
float f = 46.0f;
if (f % 1.0 == 0.0){
System.out.printf("float without decimal %.0f%n", f);
} else {
System.out.printf("float with decimals %.2f%n", f);
}
Output:
float without decimal 46
inputValue.getClass().getName()
example: value: type = java.lang.String
inputValue.getClass().getSimpleName();
example: value: String
Ended up with the below solution.
if (Value - (int) Value) != 0)
//Contains the decimal portion
else
//Decimal portion doesn't exist
Helps in identifying the type of value stored and avoid unnecessary usage of decimal portion if an int value.
I'm having two float numbers, they can be decimals or not, depending on the operation I want to print the result either with decimal or without.
I'm using String.format to take off the decimal when not needed. However, I have trouble identifying when the result will be decimal. Tried the n1 % n2 > 0 method from a similar question, but when entering for example 6 + 7 the result becomes 13.0 instead of just 13.
Code so far:
float n1 = Float.parseFloat(request.getParameter("num1").toString().trim());
float n2 = Float.parseFloat(request.getParameter("num2").toString().trim());
String res = String.valueOf(n1+n2);
if(n1 % n2 > 0)
{
out.println("It's decimal");
out.println(n1+n2);
}else{
out.println(String.format("%.0f", n1+n2));
}
For doing exact math with non-integers (numbers with fractions) in Java you should use BigDecimal. This class allows for exact representation of non-integers of arbitrary precision.
That is your code should be changed to:
final BigDecimal n1 = new BigDecimal(request.getParameter("num1").toString().trim());
final BigDecimal n2 = new BigDecimal(request.getParameter("num2").toString().trim());
final BigDecimal res = n1.add(n2);
final BigDecimal remainder = n1.remainder(n2);
//if (res.stripTrailingZeros().scale() > 0) {
if (remainder.compareTo(BigDecimal.ZERO) != 0) {
System.out.println("It's decimal");
System.out.println(res);
} else {
final DecimalFormat df = new DecimalFormat("#.0f");
System.out.println(df.format(res));
}
The other answer will not give you the correct result, if a user inputs a number larger than Integer.MAX_VALUE or lower than Integer.MIN_VALUE. Casting to long will probably yield wrong results due to the precision of float that might cause the result to have a decimal fraction even if the input numbers did not...
However I hope you're doing some input validation of the request data. Otherwise you'll most likely get a lot of NumberFormatExceptions from your JSP-page.
UPDATE:
Updated the code example to check for scale instead of precision.
You can use Math.round to tell if a float is an integer. (There are other approaches if your only purpose is to suppress the decimal point for integers when formatting as a string--see KevinO's comment.)
If f is a float, Math.round(f) returns an int, which is f rounded to the nearest integer, unless f is outside the range of an int. However, if f is outside the range of an int, then f must be an integer, for all practical purposes--if f is large enough that it is too big to fit in an int, then it's too big to distinguish between values that are less than 1.0 apart (there are fewer bits of precision in a float than in an int). So there's no way for f to represent a non-integer of that magnitude.
Given that, and assuming that f isn't +/- infinity, you can test whether f is an integer like this:
public boolean isInteger(float f) {
return f > (float)Integer.MAX_VALUE ||
f < (float)Integer.MIN_VALUE ||
f == (float)Math.round(f);
}
But please note that even a non-integer could appear as something.000000 when you format it, since the formatter will have to round f to a certain number of decimal places when printing. It depends on what kind of format you're using.
NOTE: The above method is a correct way to determine whether a float is an integer, if the float is the only information you have. However, in the context of a larger program, there are other considerations. If the parameter string is "2000000000.1", when you parse it as a float you will get 2000000000, which is an integer, because the float doesn't have enough precision to represent the .1. At that point, your float will be an integer value, and it's too late for it to know about the .1--that information has been lost. If you don't want to lose that information, then don't use float or double--use BigDecimal instead.
Cast to int then back:
boolean isDecimal = myFloat != (float)(int)myFloat;
Casting to int truncates the decimal part.
Or, you can use a string approach. Decimals have non-zero digits after the dot, so:
boolean isDecimal = String.valueOf(myFloat).matches(".*\\.(?=.*[1-9]).*");
If you just need that for output, the easiest approach is probably to do this with string manipulation:
String s = String.format("%.4f", n1 + n2); // use whatever decimal places you like
s = s.replaceFirst("\\.0*$", "");
System.out.println(s);
This will fail if the decimal separator in your Locale is , instead of ., so be careful.
To really check if a double value x is integral you can use this test:
if (x % 1 == 0) {
// integral
} else {
// not integral
}
I have some for loop which require some float local variables:
float price=0;
float weight=0;
int[] amountArray={2,5,3};
for(int i=0;i<=10;i++){
int amount=0;
if(i<amountArray.length){
amount=amountArray[i];
}
//other codes for price and weight
}
I want the price and weight to be embedded in for loop as local variables so I change the i from int to float:
int[] amountArray={2,5,3};
for(float i=0,price=0,weight=0;i<=10;i++){
int amount=0;
if(i<amountArray.length){
amount=amountArray[(int)i];
}
//other codes for price and weight
}
Does the modified version works identical to the original version? Since i contains integer value only, which can be represented by IEEE 754 standard correctly, and it does not depend on any hardware (especially in android), so I think comparing float with <, <= ,== and casting to int are not a problem in this case, am I correct?
It depends on how big the integer is. A float has 23 bits for the mantissa, and it's always assumed that the bit to the left of the mantissa is 1. That means that any positive integer whose value can fit into 24 bits can be represented exactly. But if an integer is larger than that, there won't be enough bits.
For a demonstration, try visiting http://www.adambeneschan.com/How-Does-Floating-Point-Work/showfloat.php?floatvalue=30000001&floattype=float, which shows that if you try to represent the number 30000001 as a float, it will actually have the value 30000000. Obviously == isn't going to work on integers that are that high.
Sorry for the title name but this is probably a funny question. i need to have this like it is. I have an array of floats in the format [10.0, 20.0, 30.0, 40.0, 50.0] i need the array to be represented like [10.0f, 20.0f, 30.0f, 40.0f, 50.0f]. I have tried using array List to convert and add the notation and convert back.. but no matter what i try, i still get a float array that looks like a double. Any ideas Please?
even tried something like this:
ArrayList<String> valuelist = new ArrayList<String>();
for(int z = 0; z < mValues.length; z++){
valuelist.add(Float.toString(mValues[z]) + "f");
} //its fine here but later changes
Object[] objarray2 = valuelist.toArray();
String[] stringfloat = Arrays.copyOf(objarray2, objarray2.length, String[].class);
float[] myfloat = new float[stringfloat.length];
for(int j =0; j< myfloat.length; j++){
//myfloat[j] = Float.parseFloat(stringfloat[j]);
myfloat[j] = Float.valueOf(stringfloat[j]);
}
f is used to tell the compiler that treat this as float number. If you want your array in this format use an array of string and append f in each element
As per JLS:
A floating-point literal is of type float if it is suffixed with an ASCII letter F or f; otherwise its type is double and it can optionally be suffixed with an ASCII letter D or d (ยง4.2.3).
You have:
myfloat[j] = Float.valueOf(stringfloat[j]);
Here's Float.valueOf(String):
public static Float valueOf(String s) throws NumberFormatException
{
return new Float(FloatingDecimal.readJavaFormatString(s).floatValue())
}
As you can see, it returns a Float, which is created through Float(float) constructor, which is simply:
public Float(double value)
{
this.value = (float) value;
}
The readJavaFormatString(String) converts the String to a double, and .floatValue() converts the double, wrapped in a FloatingDecimal to a float, which is passed to the above constructor.
So, im short, you do have a float.
NB:
float num1 = XYZ;
float num2 = XYZf;
Despite the different notation, num1 and num2 compile to the same bytecode (where XYZ are some numbers, say 123); however, you cannot make an assignment of a number ending in an f to say an int. Additionally, if you try to put an int into a float, you do not need the f at the end, but if your number has any numbers to the right of the radix, you need to append the f so that it will compile with a possible loss of precision error.
Also, you really shouldn't be using float unless there's a good reason to do so, especially if you're planning to use == for comparison; instead, use double. float and double are essentially the same thing, except that double is 64-bits, whereas a float is 32-bits, so a double is more precise.
Keep the original array where members are float and just create a "String myToString()" method to print it like you want, with the +"f".
I mean, create a personalized method to print the array like you want it to appear.
I assume you just want the print out of the array of float to "appear" with a final f.
The representation in the machine of the number will not change with an f at the end or not.
The final f in the string is useful when parsing a number, so you the parser knows which kind of number it is, if you already do not tell it.