I need to extract the decimal part of a float number, but I get weird results:
float n = 22.65f;
// I want x = 0.65f, but...
x = n % 1; // x = 0.6499996
x
Short answer: You can't represent some numbers exactly in binary that are "exact" in decimal.
Long answer: http://www-users.math.umd.edu/~jkolesar/mait613/floating_point_math.pdf
[Edit]
Also an interesting read: http://www.cs.berkeley.edu/~wkahan/JAVAhurt.pdf
If you just want to print the number to 2dp you can use DecimalFormat.
DecimalFormat df= new DecimalFormat("#.##");
System.out.println(df.format(f));
If you want fixed point numbers internally use BigDecimal
The sound and perfect way to get decimal part of float and double data types, is using with String like this code:
float num=2.35f;
String s= new Float(num).toString();
String p=s.substring(s.indexOf('.')+1,s.length());
int decimal=Integer.parseInt(p);
float
only has a few digit of precision so you should expect to see a round error fairly easily. try double
this has more accuracy but still has rounding errors. You have to round any answer you get to have a sane output.
If this is not desireable you can use BigDecimal which does not have rounding errors, but has its own headaches IMHO.
EDIT: You may find this interesting. The default Float.toString() uses minimal rounding, but often its not enough.
System.out.println("With no rounding");
float n = 22.65f;
System.out.println("n= "+new BigDecimal(n));
float expected = 0.65f;
System.out.println("expected= "+new BigDecimal(expected));
System.out.println("n % 1= "+new BigDecimal(n % 1));
System.out.println("n - Math.floor(n) = "+new BigDecimal(n - Math.floor(n)));
System.out.println("n - (int)n= "+new BigDecimal(n - (int)n));
System.out.println("With rounding");
System.out.printf("n %% 1= %.2f%n", n % 1);
System.out.printf("n - Math.floor(n) = %.2f%n", n - Math.floor(n));
System.out.printf("n - (int)n= %.2f%n", n - (int)n);
Prints
With no rounding
n= 22.6499996185302734375
expected= 0.64999997615814208984375
n % 1= 0.6499996185302734375
n - Math.floor(n) = 0.6499996185302734375
n - (int)n= 0.6499996185302734375
With rounding
n % 1= 0.65
n - Math.floor(n) = 0.65
n - (int)n= 0.65