diff --git a/src/main/java/com/linuxense/javadbf/DBFReader.java b/src/main/java/com/linuxense/javadbf/DBFReader.java index 4c50bc7..57feccb 100644 --- a/src/main/java/com/linuxense/javadbf/DBFReader.java +++ b/src/main/java/com/linuxense/javadbf/DBFReader.java @@ -486,13 +486,13 @@ protected Object getFieldValue(DBFField field) throws IOException { return readMemoField(field); case BINARY: if (field.getLength() == 8) { - return readDoubleField(field); + return readDoubleField_B(field); } else { return readMemoField(field); } case DOUBLE: - return readDoubleField(field); + return readDoubleField_O(field); case NULL_FLAGS: byte [] data1 = new byte[field.getLength()]; this.dataInputStream.readFully(data1); @@ -503,11 +503,18 @@ protected Object getFieldValue(DBFField field) throws IOException { } } - private Object readDoubleField(DBFField field) throws IOException { + private Object readDoubleField_B(DBFField field) throws IOException { byte[] data = new byte[field.getLength()]; // return this.dataInputStream.readDouble(); this.dataInputStream.readFully(data); - return DBFUtils.toDouble(data); + return DBFUtils.toDoubleBinary(data); + } + + private Object readDoubleField_O(DBFField field) throws IOException { + byte[] data = new byte[field.getLength()]; +// return this.dataInputStream.readDouble(); + this.dataInputStream.readFully(data); + return DBFUtils.toDoubleDouble(data); } private Object readMemoField(DBFField field) throws IOException { diff --git a/src/main/java/com/linuxense/javadbf/DBFUtils.java b/src/main/java/com/linuxense/javadbf/DBFUtils.java index f17d98e..ff4c50f 100644 --- a/src/main/java/com/linuxense/javadbf/DBFUtils.java +++ b/src/main/java/com/linuxense/javadbf/DBFUtils.java @@ -415,12 +415,35 @@ protected static BitSet getBitSet(byte[] bytes) { return BitSet.valueOf(bytes); } + /* protected static double toDouble(byte[] data) { double d = ByteBuffer.wrap(data).order(ByteOrder.BIG_ENDIAN).getDouble(); if (d!= 0.0) { d = -d; } - return d; + return d; + }*/ + + protected static double toDoubleBinary(byte[] data) { + double d = ByteBuffer.wrap(data).order(ByteOrder.LITTLE_ENDIAN).getDouble(); + if (d == -0.0) { + d = 0.0; + } + return d; + } + + + protected static double toDoubleDouble(byte[] data) { + double d = ByteBuffer.wrap(data).order(ByteOrder.BIG_ENDIAN).getDouble(); + + if (d != 0.0) { + d = -d; + } + if (d == -0.0) { + d = 0.0; + } + return d; + } diff --git a/src/test/java/com/linuxense/javadbf/UtilsTest.java b/src/test/java/com/linuxense/javadbf/UtilsTest.java index 1bc314e..af17ec0 100644 --- a/src/test/java/com/linuxense/javadbf/UtilsTest.java +++ b/src/test/java/com/linuxense/javadbf/UtilsTest.java @@ -23,6 +23,7 @@ import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; +import java.io.File; import java.math.BigInteger; import java.nio.ByteBuffer; import java.nio.ByteOrder; @@ -36,6 +37,8 @@ import org.junit.Ignore; import org.junit.Test; +import com.linuxense.javadbf.testutils.DbfToTxtTest; + // TODO Rename to DBFUtilsTest @@ -166,195 +169,69 @@ 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}; + public void testConvertDoubleBinary_valueOne() { + double expected = 1.0; + byte[] data = {0,0,0,0,0,0, (byte) 0xF0, 0x3F}; System.out.println(toHexString(data)); System.out.println(toBinaryString(data)); - - - double calculated = convertBigInteger(data); + double calculated = DBFUtils.toDoubleBinary(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}; + public void testConvertDoubleDouble_valueOne() { + double expected = 1.0; + byte[] data = {(byte) 0xBF,(byte) 0xF0,0,0,0,0, 0, 0}; System.out.println(toHexString(data)); System.out.println(toBinaryString(data)); - - //405A6283785A7EF9 - //c05a6283785a7ef9 - double calculated = convertBigInteger(data); + double calculated = DBFUtils.toDoubleDouble(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); - - } - 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 class Pair { + byte[] data; + double expected; + + private Pair(byte[] data, double expected) { + this.data = data; + this.expected = expected; + } } - 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); - + @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.toDoubleDouble(p.data), 0.01); + } } - //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); @@ -377,4 +254,9 @@ private String byteToHex(byte num) { return new String(hexDigits); } + @Test + public void testPrintNumbers() throws Exception { + DbfToTxtTest.writeToConsole(new File("src/test/resources/numbers2.dbf") ); + } + } diff --git a/src/test/resources/numbers2.dbf b/src/test/resources/numbers2.dbf new file mode 100644 index 0000000..3057f43 Binary files /dev/null and b/src/test/resources/numbers2.dbf differ