Monthly Archives: March 2016

Followup

From the javadoc comments in Math.java: “If the argument is NaN or an infinity or positive zero or negative zero, then the result is the same as the argument.”

Let me just point out that Java thinks that NaN (Not a Number), positive zero, negative zero, or either positive or negative infinity are different values, and this is not a quirk of Java. The language thinks this because the standard for computer representation of real numbers thinks this; the language is just exposing the constructs so that programmers can handle these different values.

At least nowadays positive zero will test as equal to negative zero. (That wasn’t always true, you know.)

Order Matters

I’ve been playing Kerbal Space Program recently and using the MechJeb plugin. Some people criticise that plugin – “You can do anything that MechJeb does, and if you spend a little time, you can probably do it better” – and they’re right, for some values of right. And yet, “execute next node,” is blessedly useful. It keeps the game fun, for me.

Anyway, one of the problems with MechJeb is that some of its input fields that accept an angle want decimal degrees, and some want degrees – minutes – seconds, while the contracts seem uniformly to specify decimal degrees. I found an online tool that will convert between them, but have found that the author of the tool didn’t consider the way computers do floating point math. The algorithm would pass muster with a mathematician:

  1. Take the integer part of the decimal degrees. That is your degrees.
  2. Take everything to the right of the decimal point and multiply by 60. Take the integer portion of that product. That is your minutes.
  3. Take the decimal part of the product and multiply it by 60. That is your seconds.

The problem is that a computer might lose a few digits off the end when you start doing all that multiply, truncate, and subtract. For example, try using that online tool to convert 27.2 degrees. It’ll tell you that the answer is 27 degrees, 11 minutes, 60 seconds. And sure, that’s true, but what you really want is 27 degrees, 12 minutes.

The computer way to do this is to start out multiplying 27.2 by 3600. That gives you seconds, and you convert from there:

  1. Take the integer part of the decimal degrees. That is your degrees.
  2. Multiply the decimal degrees by 3600. That is the total number of seconds (still a floating point number).
  3. Multiply degrees by 3600. Subtract that product from the total number of seconds.
  4. Divide the new (smaller) total number of seconds by 60. Take the integer portion of that value. That is your minutes.
  5. Multiply minutes by 60 and subtract that product from the total number of seconds. Now the total number of seconds is really your seconds, and it will be smaller than 60.

I feel like this is the sort of thing that I learned from writing BASIC programs to do my math homework back in high school. Didn’t these guys ever get told off by their math teachers for being imprecise?