Question

If the next statement is true:

DataStreams uses one very bad programming technique: it uses floating point numbers to represent monetary values. In general, floating point is bad for precise values. It's particularly bad for decimal fractions, because common values (such as 0.1) do not have a binary representation.

It's then true that datastreams are to be used only for non floating point values? It's not that useful if it is in this way.

Was it helpful?

Solution

The quote is confusing for a number of reasons

DataStreams uses one very bad programming technique: it uses floating point numbers to represent monetary values.

DataStream don't have anything to say about how monetary values are sent. There is no send Price/Money/Currency methods. How you send monetary values is entirely up to you,

In general, floating point is bad for precise values.

float is very bad for precise values as it only has 6 digits of precision. double on the other hand has at least 15 digits of precision and this is usually more than enough for money. i.e. you can accurately represent values up to $70,000,000,000,000.00

In general, I would avoid float as it isn't worth the memory you save (unless you have millions or billions of them)

It's particularly bad for decimal fractions, because common values (such as 0.1) do not have a binary representation.

This does not have a precise binary representation, something the double to text conversion implicitly compensate for. e.g.

double d = 0.1; // no a precise representation
System.out.println(d); // print 0.1 as the conversion is aware this what should be displayed.

While representation errors can be a head ache, they are not random errors which some people seems to believe. They can be determined and controlled with sensible rounding.

Never the less if you want to use BigDecimal for your values, you can and you can write this to a DataStream.

BTW C and C++ don't have a decimal type and yet many trading systems (in the past most trading systems) used these languages. They did this by using int, long and double types in general, as do many Java based trading systems. Most investment banks in London use double AFAIK. (I have worked at more than a few ;)

It's then true that datastreams are to be used only for non floating point values?

A common misused of DataInputStream is for reading text. There are about 30 questions and answer posted to SO a month which use DataInputStream to read text from a file and it is something I am actively trying to stop.

However DataInputStream is useful for reading all primitive types, Strings and reading a full byte[] e.g.

byte[] bytes = new byte[64];
dataInputSTream.readFully(bytes); // don't return unless 64 bytes have been read.

Note: the DataStream assume Big Endian or Network order. Unfortunately most desktop and mobile systems use Little Endian meaning you need to use ByteBuffer if you want to exchange data with a C program.


If you want a simple comparison of how inefficient BigDecimal compared with double

  • BigDecimal is approximately 100x slower to perform basic calculations and it does not support complex ones that double does.
  • double produces no garbage, BigDecimal produces a lot.
  • Writing one double to a stream 8 bytes, write one BigDecimal to an ObjectOutputStream 290 bytes.

What BigDecimal does for you is give you precise and controlled rounding built in. With double you have to know how to use functions like Math.round, Math.floor, Math.ceil to do the same thing.

OTHER TIPS

DataStream implementations don't reduce the precision of the data types that were written.

If you write an float value using writeFloat(..) you will read exactly the same value using readFloat(). There is only lost of precision when you convert values, e.g. from double to float. But that this is not related to DataStreams.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top