0

I'm reading the following code(in ch. 5, inheritance, of Horstman's Core Java):

double dx = (to - from) / (n-1);

for (double x = from; x <= to; x += dx)
{
  double y = (Double) f.invoke(null, x);
  System.out.printf(%10.4f |  %10.4f%n" + y, x, y);
}

Why would you use double variables at all in a for-loop? And what is invoke used for? thanks

Edit: f is something related to Field

Caffeinated
  • 10,270
  • 37
  • 107
  • 197

5 Answers5

4

It's perfectly fine to do, especially if you want to loop through fractional values or increment by fractional values.

However I just wanted to add something to the other answers, which is that if you employ this technique, do not compare with == for the condition to end the loop. Due to precision errors, this can easily result in an infinite loop in spite of the best intentions. That's why your book's code uses <=.

asteri
  • 10,842
  • 12
  • 53
  • 82
  • Of course, old programmers (as opposed to bold programmers) never use `==` to terminate even an integer-indexed loop, having been bit too often by strange bugs that cause one to increment past the stopping point. – Hot Licks Jun 28 '13 at 21:36
  • @HotLicks To be fair, I've always been taught that if you're going to fail... fail hard and loudly, so that you pick up the bug before going to production. Haha. At least you're not as likely to miss an infinite loop as an oddly incremented value? – asteri Jun 28 '13 at 21:40
  • You've apparently never been handed two boxes of printout at the output window, each line bearing simply an ever-incrementing number. – Hot Licks Jun 28 '13 at 21:42
  • 1
    Hm. Touche, sir. Touche. – asteri Jun 28 '13 at 21:43
4

It's not a good idea to use floating point values as for-loop variables because of subtleties in arithmetic and comparison. Your loop might not iterate through the values you expect because of rounding errors. An out-by-one error is likely.


For example, this loop

 for (double x=0.0; x < 100.0; x += 0.1)

might be expected to pass through the values 0.0, 0.1, 0.2,... but because of rounding errors passes through slightly different values.

Raedwald
  • 40,290
  • 35
  • 127
  • 207
  • 2
    I think the statement you should make is "Use the data type that is appropriate to your problem." You get a lot fewer rounding errors incrementing a float/double by 0.1 than you get incrementing an int. – Hot Licks Jun 28 '13 at 21:38
  • See http://stackoverflow.com/questions/8897579/on-doubles-and-equality – Raedwald Jun 28 '13 at 21:42
  • See http://stackoverflow.com/questions/4937402/moving-decimal-places-over-in-a-double – Raedwald Jun 28 '13 at 21:45
  • I don't see what relevance either of those references have to this topic. – Hot Licks Jun 28 '13 at 21:49
1

For example, if you want to loop from 1.5 up to no more than 8 in increments of 0.11, you would need double variables in the for loop.

jh314
  • 24,533
  • 14
  • 58
  • 79
1

There's no reason not to. Typically you loop with integers, but there's no reason you couldn't do the same thing with doubles applying an arbitrary instruction to the end of the loop iteration like x = x*1.2 or something like that. Also we need to know what f is to tell you what invoke does ;)

Chris Thompson
  • 33,380
  • 11
  • 76
  • 105
  • it looks like f is associated with java Field class ( http://docs.oracle.com/javase/6/docs/api/java/lang/reflect/Field.html ) . thanks! – Caffeinated Jun 28 '13 at 21:35
1

This is a very bad idea. For large n (relative to to - from), dx will be so small that x += dx won't change the value of x, leaving you with a loop condition that will always be true, and you'll be stuck in the loop.

Do not use imprecise data (such as float and double) to control the flow of your program.

Instead, you should use an integer (e.g. ranging from 0 inclusive to n exclusive) to control the loop. There are a few ways to do it (and most of them are wrong when it comes to handling rounding errors), but at least you can be sure that your loop will terminate.


Regarding your question about invoke: I think f is a Method rather than a Field. java.lang.reflect is a set of classes for reflection. Using reflection, the programmer made it so that f points to a method, and invoke can be used to call that method. Since it's being invoked with null as the first argument (which would normally specify what this is), f must refer to some static method in order to succeed.