-2

Here is the extracted code :

long timeMs = 1473;
double timeS = (timeMs / 1000) + (timeMs% 1000) / 1000.0;
System.out.println(timeS);

And the output is:

1.4729999999999999

So basically, I was just trying to convert the time taken in seconds into milliseconds. After I saw this I thought my method is wrong, so I've tried other inputs, such as 1472, 1474, 1173, 3 etc which all gave the correct values(1.472, 1.474, 1.173, 0.003).

I think I've came across something similar to this a while ago in a book called Java Puzzlers, but have forgotten. Can anyone tell me why this is happening (and a proper term/error)?

Thanks.

Topstar
  • 41
  • 5
  • Floating point precision. – Sotirios Delimanolis Dec 04 '13 at 20:50
  • -1 floating point .. Google it. – Silviu Burcea Dec 04 '13 at 20:50
  • 3
    Read [What Every Computer Scientist Should Know About Floating-Point Arithmetic](http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html) – Reimeus Dec 04 '13 at 20:51
  • You get the correct result from the correct division. Just use `timeMs / 1000.0`. With it I get `1.473`. – rgettman Dec 04 '13 at 20:51
  • 1
    @SilviuBurcea I do not understand why I need to be down voted, is it because its a simple question? It may be in your eyes... but how can I possibly know otherwise? why do people like you expect a beginner to know these technical terms and search for it? If I knew what to search, it would have taken much much less time than asking here. – Topstar Dec 04 '13 at 21:01
  • @Topstar it was asked million times before on SO and you get a nice autocomplete when you ask a question. That's why. – Silviu Burcea Dec 04 '13 at 21:04
  • @SilviuBurcea Autocomplete? Did I ask for a code? I only asked the reasons for it happening, and the proper term. As I've said, I couldn't find the proper terms for the error. Next time I hope you read the question. Don't assume everyone has intentions like yours. – Topstar Dec 04 '13 at 21:15

2 Answers2

3

Use this instead, but it's because of IEEE 754 rounding rules.

double timeS = (timeMs / 1000.0); //+ ((double) (timeMs % 1000) / 1000.0);
Elliott Frisch
  • 198,278
  • 20
  • 158
  • 249
0

Use BigDecimal for more accurate rounding and scaling.

   long timeMs = 1473;
   double timeS = (timeMs / 1000d);
   BigDecimal usefulName = new BigDecimal(timeS).setScale(3, RoundingMode.HALF_UP);
   System.out.println(usefulName);
Nick Allen
  • 917
  • 11
  • 24