diff --git a/src/main/java/com/linuxense/javadbf/DBFReader.java b/src/main/java/com/linuxense/javadbf/DBFReader.java index 07fcf67..6c9d36e 100644 --- a/src/main/java/com/linuxense/javadbf/DBFReader.java +++ b/src/main/java/com/linuxense/javadbf/DBFReader.java @@ -488,13 +488,13 @@ protected Object getFieldValue(DBFField field) throws IOException { return readMemoField(field); case BINARY: if (field.getLength() == 8) { - return readDoubleField(field); + return readDoubleFieldLittleEndian(field); } else { return readMemoField(field); } case DOUBLE: - return readDoubleField(field); + return readDoubleFieldBigEndian(field); case NULL_FLAGS: byte [] data1 = new byte[field.getLength()]; this.dataInputStream.readFully(data1); @@ -505,12 +505,18 @@ protected Object getFieldValue(DBFField field) throws IOException { } } - private Object readDoubleField(DBFField field) throws IOException { + private Object readDoubleFieldLittleEndian(DBFField field) throws IOException { byte[] data = new byte[field.getLength()]; -// return this.dataInputStream.readDouble(); this.dataInputStream.readFully(data); - return DBFUtils.toDouble(field, data); + return DBFUtils.toDoubleLittleEndian(data); } + + private Object readDoubleFieldBigEndian(DBFField field) throws IOException { + byte[] data = new byte[field.getLength()]; + this.dataInputStream.readFully(data); + return DBFUtils.toDoubleBigEndian(data); + } + private Object readMemoField(DBFField field) throws IOException { Number nBlock = null; diff --git a/src/main/java/com/linuxense/javadbf/DBFUtils.java b/src/main/java/com/linuxense/javadbf/DBFUtils.java index 63c5e25..8a511ba 100644 --- a/src/main/java/com/linuxense/javadbf/DBFUtils.java +++ b/src/main/java/com/linuxense/javadbf/DBFUtils.java @@ -425,33 +425,26 @@ protected static BitSet getBitSet(byte[] bytes) { return bits; } - protected static double toDouble(byte[] data) { - double d = ByteBuffer.wrap(data).order(ByteOrder.BIG_ENDIAN).getDouble(); - if (d!= 0.0) { - d = -d; + protected static double toDoubleLittleEndian(byte[] data) { + double d = ByteBuffer.wrap(data).order(ByteOrder.LITTLE_ENDIAN).getDouble(); + if (d == -0.0) { + d = 0.0; } - return d; - } + return d; + } - // FIXME delete - @Deprecated - protected static double toDouble(DBFField field, byte[] data) { - double d = toDouble(data); - StringBuilder sb = new StringBuilder() ; - for(byte b: data) { - if (sb.length() == 0) { - sb.append("{"); - } - else { - sb.append(","); - } - sb.append(b); - } - sb.append("}"); - System.out.println(field.getName() + " " + sb + "; " + d); - if (d!= 0.0) { + + protected static double toDoubleBigEndian(byte[] data) { + double d = ByteBuffer.wrap(data).order(ByteOrder.BIG_ENDIAN).getDouble(); + + if (d != 0.0) { + // For some reason sign is swapped d = -d; + } + if (d == -0.0) { + d = 0.0; } - return d; + return d; } + } diff --git a/src/test/java/com/linuxense/javadbf/UtilsTest.java b/src/test/java/com/linuxense/javadbf/UtilsTest.java index 1bc314e..f8cc93b 100644 --- a/src/test/java/com/linuxense/javadbf/UtilsTest.java +++ b/src/test/java/com/linuxense/javadbf/UtilsTest.java @@ -23,22 +23,16 @@ import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; -import java.math.BigInteger; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; import org.junit.Assert; -import org.junit.Ignore; import org.junit.Test; -// TODO Rename to DBFUtilsTest public class UtilsTest { private static final Charset ISO_8859_1 = StandardCharsets.ISO_8859_1; @@ -166,215 +160,40 @@ public void testTrimRightSpaces() { } - @Test - @Ignore - public void testConverterDoublePostive() throws Exception { - double expected = 193786.00; - byte[] data = new byte[] {-63, 7, -89, -48, 0, 0, 0, 0}; - - System.out.println(toHexString(data)); - System.out.println(toBinaryString(data)); - - double calculated = convertBigInteger(data); - Assert.assertEquals(expected, calculated, 0.01); - } - - @Test - @Ignore - public void testConverterDoubleNegative() throws Exception { -// MaxPeakNoUnit {-64,-73,122,80,-76,-95,104,-121}; -6010.315256202716 -// MinPeakNoUnit {63,-98,8,64,16,-128,33,-113}; 0.029328347212897617 - - double expected = -143.74; - byte[] data = new byte[] {63,-98,8,64,16,-128,33,-113}; - System.out.println(toHexString(data)); - System.out.println(toBinaryString(data)); - - - double calculated = convertBigInteger(data); - Assert.assertEquals(expected, calculated, 0.01); - } - - @Test - @Ignore - //Tz {-64,90,98,-125,120,90,126,-7}; -105.5392742999792 - public void testConverterDouble2() throws Exception { - double expected = 105.539; - byte[] data = new byte[] {-64,90,98,-125,120,90,126,-7}; - System.out.println(toHexString(data)); - System.out.println(toBinaryString(data)); + private class Pair { + byte[] data; + double expected; - //405A6283785A7EF9 - //c05a6283785a7ef9 - double calculated = convertBigInteger(data); - Assert.assertEquals(expected, calculated, 0.01); - } - - - @Test - public void testDoubles() throws Exception { - - List expectedList = new ArrayList(Arrays.asList(193786.00, 193786.00, 105.539, -143.74, -110488.58)); - List rawDataList = new ArrayList(Arrays.asList( - new byte[] {-63, 7, -89, -48, 0, 0, 0, 0}, - new byte[] {65, 7, -89, -48, 0, 0, 0, 0}, - new byte[] {-64,90,98,-125,120,90,126,-7}, - new byte[] {63,-98,8,64,16,-128,33,-113}, - new byte[] {63,5,6,118,-63,114,-45,-118} - )); - - for (int i = 0; i < expectedList.size(); i++) { - double expected = expectedList.get(i); - byte[] data = rawDataList.get(i); - double bigInteger = convertBigInteger(data); - double byteBufferBE = convertByteBufferBigEndian(data); - double byteBufferLE = convertByteBufferLittleEndian(data); - System.out.println("---"); - System.out.println(toHexString(data)); - System.out.println(toBinaryString(data)); - System.out.println(expected); - System.out.println("biginteger =" + bigInteger); - System.out.println("bytebufferBE=" + byteBufferBE); - System.out.println("bytebufferLE=" + byteBufferLE); - + private Pair(byte[] data, double expected) { + this.data = data; + this.expected = expected; } - for (byte[] data : rawDataList) { - System.out.println("raw=" + toBinaryString(data)); - } - - long a = 0xFFFFFFFF; - a = a & new BigInteger(new byte[] {63,-98,8,64,16,-128,33,-113}).longValue(); - a = a & new BigInteger(new byte[] {63,5,6,118,-63,114,-45,-118}).longValue(); - System.out.println("long=" + Long.toBinaryString(a)); - - - } - - /* - * MaxPeakNoUnit {-64,-73,122,80,-76,-95,104,-121}; 6010.315256202716 -MinPeakNoUnit {63,-98,8,64,16,-128,33,-113}; -0.029328347212897617 -T1 {-65,15,-54,102,-98,53,-91,-17}; 6.063581147481764E-5 -T2 {-128,0,0,0,0,0,0,0}; -0.0 -Tp {-128,0,0,0,0,0,0,0}; -0.0 -Td {-128,0,0,0,0,0,0,0}; -0.0 -Tc {-128,0,0,0,0,0,0,0}; -0.0 -Tz {-64,90,98,-125,120,90,126,-7}; 105.5392742999792 -BetaDash {-65,-59,-10,25,-76,122,28,-53}; 0.17157288849214178 -FreqOsc {-128,0,0,0,0,0,0,0}; -0.0 -Urms {-128,0,0,0,0,0,0,0}; -0.0 -FreqAC {-128,0,0,0,0,0,0,0}; -0.0 -Udc {-128,0,0,0,0,0,0,0}; -0.0 -UpValue {-128,0,0,0,0,0,0,0}; -0.0 -SpareF1 {-64,89,0,0,0,0,0,0}; 100.0 -SpareF2 {0,0,0,0,0,0,0,0}; 0.0 -SpareF3 {0,0,0,0,0,0,0,0}; 0.0 -MinPeakNoUnit=0.029328347212897617 -MaxPeakNoUnit=-6010.315256202716 -MinPeakN=-143.74 A -MaxPeak=6.010 kA - */ - - /* - * DataNumber {-63,7,-88,64,0,0,0,0}; 193800.0 -ChannelNum {-65,-16,0,0,0,0,0,0}; 1.0 -TerminalDi {-64,117,-32,0,0,0,0,0}; 350.0 -CurveType {-65,-16,0,0,0,0,0,0}; 1.0 -FilterCoun {-128,0,0,0,0,0,0,0}; -0.0 -ErrorMessa {0,0,0,0,0,0,0,0}; 0.0 -MaxPeakNoUnit {63,5,6,118,-63,114,-45,-118}; -4.010248101719075E-5 -MinPeakNoUnit {-128,0,0,0,0,0,0,0}; -0.0 -T1 {-66,-80,-109,-69,93,70,-61,1}; 9.880708279169888E-7 -T2 {-65,5,-121,107,-35,50,-104,55}; 4.1063288926765735E-5 -Tp {-128,0,0,0,0,0,0,0}; -0.0 -Td {-128,0,0,0,0,0,0,0}; -0.0 -Tc {-128,0,0,0,0,0,0,0}; -0.0 -Tz {-64,-98,109,31,-5,-6,-36,115}; 1947.2812346646358 -BetaDash {-64,42,-90,-117,42,-118,-51,29}; 13.325280503695973 -FreqOsc {-128,0,0,0,0,0,0,0}; -0.0 -Urms {-128,0,0,0,0,0,0,0}; -0.0 -FreqAC {-128,0,0,0,0,0,0,0}; -0.0 -Udc {-128,0,0,0,0,0,0,0}; -0.0 -UpValue {-128,0,0,0,0,0,0,0}; -0.0 -SpareF1 {-64,89,0,0,0,0,0,0}; 100.0 -SpareF2 {0,0,0,0,0,0,0,0}; 0.0 -SpareF3 {0,0,0,0,0,0,0,0}; 0.0 -MinPeakNoUnit=-0.0 -MaxPeakNoUnit=4.010248101719075E-5 -MinPeakN=0.000 V -MaxPeak=-110.48 kV - */ - - private double convertByteBufferLittleEndian(byte[] data) { -// double d = ByteBuffer.wrap(data).order(ByteOrder.LITTLE_ENDIAN).getDouble(); - ByteBuffer buffer = ByteBuffer.allocate(8); -// buffer.order(ByteOrder.LITTLE_ENDIAN); - buffer.put(data,0,data.length); - buffer.order(ByteOrder.BIG_ENDIAN); - double d = buffer.getDouble(0); - return d; - } - private double convertByteBufferBigEndian(byte[] data) { - double d = ByteBuffer.wrap(data).order(ByteOrder.BIG_ENDIAN).getDouble(); -// if (d!= 0.0) { -// d = -d; -// } - return d; } - private double convertBigInteger(byte[] data) { - long longValue = new BigInteger(data).longValue(); - double d = Double.longBitsToDouble(longValue); -// if (d != 0) { -// return -d; -// } - return d; -// return DBFUtils.toDouble(data); - - } - //0011111100000101000001100111011011000001011100101101001110001010 <- memo - //1100000011111010111110011000100101000111101011100001010001111011 <- calculado - - // 193786.00 - //1100000100000111101001111101000000000000000000000000000000000000 <- memo - //0100000100000111101001111101000000000000000000000000000000000000 <-caculado - - - // 105.539 - // 1100000001011010011000101000001101111000010110100111111011111001 <- memo - // c05a6283785a7ef9 - // 0100000001011010011000101000001101111000010110100111111011111001 <- calculado - // 405A6283785A7EF9 - //-143.74 - //3f9e08401080218f - //C061F7AE147AE148 - /* - 1100000001011010011000101000001101111000010110100111111011111001 -105.539 -biginteger =-105.5392742999792 -bytebufferBE=-105.5392742999792 -bytebufferLE=-105.5392742999792 - */ - - private String toBinaryString(byte[] bytes) { - StringBuilder sb = new StringBuilder(bytes.length * Byte.SIZE); - for (int i = 0; i < Byte.SIZE * bytes.length; i++) { - sb.append((bytes[i / Byte.SIZE] << i % Byte.SIZE & 0x80) == 0 ? '0' : '1'); + @Test + public void testDoublesDouble() throws Exception { + List list = new ArrayList(); + list.add(new Pair(new byte[] {-128,0,0,0,0,0,0,0}, 0.0)); + list.add(new Pair(new byte[] {0,0,0,0,0,0,0,0}, 0.0)); + list.add(new Pair(new byte[] {-65,-16,0,0,0,0,0,0}, 1.0)); + list.add(new Pair(new byte[] {-64,-73,122,80,-76,-95,104,-121}, 6010.315256202716)); + list.add(new Pair(new byte[] {63,-98,8,64,16,-128,33,-113}, -0.029328347212897617)); + list.add(new Pair(new byte[] {-65,15,-54,102,-98,53,-91,-17}, 6.063581147481764E-5)); + list.add(new Pair(new byte[] {-64,90,98,-125,120,90,126,-7}, 105.5392742999792)); + list.add(new Pair(new byte[] {-65,-59,-10,25,-76,122,28,-53}, 0.17157288849214178)); + list.add(new Pair(new byte[] {-64,89,0,0,0,0,0,0}, 100.0)); + list.add(new Pair(new byte[] {-63,7,-88,64,0,0,0,0}, 193800.0)); + list.add(new Pair(new byte[] {-64,117,-32,0,0,0,0,0}, 350.0)); + list.add(new Pair(new byte[] {63,5,6,118,-63,114,-45,-118}, -4.010248101719075E-5)); + list.add(new Pair(new byte[] {-66,-80,-109,-69,93,70,-61,1}, 9.880708279169888E-7)); + list.add(new Pair(new byte[] {-65,5,-121,107,-35,50,-104,55}, 4.1063288926765735E-5)); + list.add(new Pair(new byte[] {-64,-98,109,31,-5,-6,-36,115}, 1947.2812346646358)); + list.add(new Pair(new byte[] {-64,42,-90,-117,42,-118,-51,29}, 13.325280503695973)); + + for (Pair p : list) { + Assert.assertEquals(p.expected, DBFUtils.toDoubleBigEndian(p.data), 0.01); } - return sb.toString(); - } - private String toHexString(byte[] byteArray) { - StringBuffer hexStringBuffer = new StringBuffer(); - for (int i = 0; i < byteArray.length; i++) { - hexStringBuffer.append(byteToHex(byteArray[i])); - } - return hexStringBuffer.toString(); - } - private String byteToHex(byte num) { - char[] hexDigits = new char[2]; - hexDigits[0] = Character.forDigit((num >> 4) & 0xF, 16); - hexDigits[1] = Character.forDigit((num & 0xF), 16); - return new String(hexDigits); } }