Steer clear of Java pitfalls (3)(一)

2014-11-23 23:14:05 · 作者: · 浏览: 0

Pitfall 3: Dont mix floats and doubles when generating text or XML messages

While developing an order execution system for an online brokerage, I stumbled across a serious bug that incorrectly converted certain values from doubles to strings. Here is the scenario: The Website presents a stock-trade form to the user. A Java servlet processes the form and sends the trade information to the order execution server, a Java RMI server. The Java RMI server formats the message as either XML or another text format -- the common message switch (CMS) format, for example -- and passes it to one of several executing agents. One of the fields in the stock-trade message is the stock price, which is stored as a double. For certain double values, the Java platform incorrectly converts the price when formatting the order message, and the trade is rejected. Customers dont like that!

What if this was embedded software in a medical device, and the double value represented the amount of radiation administered to a patient A low-level bug like this can be extremely dangerous.

Below is an applet that simulates the above scenario and generates two stock transaction messages. The first price formats correctly, while the second value -- 100.28 -- formats incorrectly.

Message 1...

BUY
SUNW
1000
98.5


Message 2...

BUY
SUNW
1000
100.27999877929688


I originally labeled this problem a bug, and I did find that Suns JDC bug database reports it several times, in numbers 4030639, 4087318, 4068996, and 4169083. Unfortunately, these similar bugs are described inconsistently. Some are reported fixed, others are not even considered bugs, and one is labeled as a bug "in progress." Unfortunately for the many application developers who must generate XML messages that contain double values, this bug exists in JDK 1.1, 1.2, and 1.3. Thus I consider it a pitfall.

The following is a simple example of the bug. The problem lies in converting a float to a double, prior to converting to a String. This occurred in the brokerage software when one developer primarily used floats for decimals, but another implemented doubles. That caused the bug to surface; this crashed the executing agents stock trading system, which received our incorrectly formatted trade message. Notice that the method genTradeMessage() uses a float to represent the price. The purpose of genTradeMessage() is to generate a simple text XML order message. In turn, genTradeMessage() calls formatStockPrice(), which takes a double as the price parameter. Here is the invocation of genTradeMessage() that fails:

  1. String msg2 = genTradeMessage("SUNW", "BUY", 1000, 100.28f);


Notice that a float of 100.28 is passed into genTradeMessage(). Here is the code for genTradeMessage() and formatStockPrice():

  1. public String genTradeMessage(String symbol,
  2. String action,
  3. int shares,
  4. float pri