10

I need to make use of numbers coming from another system that are 128-bit (quadruple-precision) floating point numbers in java.

Considering that there is no equivalent type in java, I would like to reduce the precision of the numbers using java code so they can be stored in a java double. This can be done fairly easily in c or using assembly but I would like to do it purely in java.

It is fair to assume that the quadruple-precision number is stored in a 128-bit byte array in java.

Is there a good solution, using only java? Thanks.

user474762
  • 117
  • 2
  • 6
  • 7
    [`BigDecimal`](http://docs.oracle.com/javase/1.5.0/docs/api/java/math/BigDecimal.html) might work for you. – crush Jan 10 '14 at 18:05
  • How would you import the numbers? Is it your intention to parse string representations of the original numbers? – Robert Harvey Jan 10 '14 at 18:07
  • @RobertHarvey I assume he'd pass the hi 64 bits and the low 64 bits as two doubles, then use some logic to rejoin them. This makes sense to me when dealing with long's, but I don't really understand how doubles bits are organized yet, so I might be wrong. Maybe that's not possible with doubles. – crush Jan 10 '14 at 18:09
  • Robert- That is exactly the problem - there is no way to represent the number as anything but a byte array. I am assuming that I will have to manually manipulate the bytes but I was hoping for an alternative. The same problem exists with BigDecimal there is no easy way to convert the byte array to something BigDecimal can understand - that I know of. – user474762 Jan 10 '14 at 18:12
  • I assume you'd get the number in as an array of bytes. You can then manipulate the bytes as needed to produce a 64 bit double, place the resulting bits in a `long`, and use `Double.longBitsToDouble` to produce your `double` result. (It should be possible to transliterate the C algorithm into Java with a bit of work.) – Hot Licks Jan 10 '14 at 18:16
  • 4
    Doing the bit-twiddling to extract the exponent and the mantissa and generate a new java double value from them is an entirely reasonable approach. (Assuming the exponent is within a double's range.) – keshlam Jan 10 '14 at 18:16
  • Do you need the _behavior_ of a 128-bit double, or just storage/representation? Note that converting to a different bit depth will likely result in a different value – Clockwork-Muse Jan 12 '14 at 08:20

3 Answers3

24

I was so intrigued by this question that I was compelled to write a library to handle IEEE-754 floating point numbers. With the library, you can use the following:

byte[] quadBytes; // your quad-floating point number in 16 bytes
IEEE754 quad = IEEE754.decode(IEEE754Format.QUADRUPLE, 
        BitUtils.wrapSource(quadBytes));
// IEEE754 holds the number in a 'lossless' format

From there, you can:

ByteBuffer doubleBuffer = ByteBuffer.allocateDirect(8);
quad.toBits(IEEE754Format.DOUBLE, BitUtils.wrapSink(doubleBuffer));
doubleBuffer.rewind();
double converted = doubleBuffer.asDoubleBuffer().get();

But the above snippet is just to illustrate general usage... a shorthand is provided for double:

double converted = quad.doubleValue();

The code is available at kerbaya.com/ieee754lib.

Glenn Lane
  • 3,892
  • 17
  • 31
3

Depending on the size of the data set BigDecimal instantiated from an imported String representation might be an easy and accurate option. I assume one can export string representations of those numbers from any programming language.

Oleg Sklyar
  • 9,834
  • 6
  • 39
  • 62
1

Although the question was asked rather long ago, perhaps it may still be of interest for someone. There is a Java class for 128-bit floating point arithmetic, that has methods for converting 128-bit IEEE-754 floating-point values into its own internal representation without any loss of precision. It can perform arithmetic operations on such values, and convert them back to IEEE-754 binary128, as well as to other common numeric types like BidDecimal, double and long. It can also parse strings containing decimal representations of such values and convert them back to strings. Internally, it stores 128 bits of the mantissa, so that the relative error of the calculations does not exceed 1.47e-39.

m. vokhm
  • 669
  • 1
  • 6
  • 24