473,574 Members | 2,690 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

IBM JDBC driver behaves differently on Linux than on Solaris

Hi. Below is a simple JDBC program to insert and extract
a numerical value. When ResultSet.getDo uble() is called,
the same program produces different output on solaris
than it does on Linux. I would be grateful for any
discussion of this!
thanks,
Joe Weinstein at BEA Systems

Results on Linux Box
-----------------------------------------------------------------------
-bash-2.05b$ java db2
08.02.0001
Database version is 08.02.0000
Testing value 1.001
native driver object is a class java.math.BigDe cimal
value is 1.001
as getDouble it's 1.0010000000000 001 <<<<<<<<<< SEE THIS!
native driver object is a class java.math.BigDe cimal
value is 1.001
as getDouble it's 1.0010000000000 001 <<<<<<<<<< SEE THIS!
double d = 1.001d gives 1.001
new Double("1.001") .doubleValue() gives 1.001
they are equal.
new BigDecimal(1.00 1d) gives 1.0009999999999 998898658759571 844711899757385 253906
25
new BigDecimal( new Double("1.001") .doubleValue() ) gives 1.0009999999999 998898658759571 844711899757385 25390625
Results on Solaris Box
---------------------------------------------------------------------------
bash-3.00$java db2
08.02.0002
Database version is 08.02.0000
Testing value 1.001
native driver object is a class java.math.BigDe cimal
value is 1.001
as getDouble it's 1.001 <<<<<<<<<< DIFFERENT!
native driver object is a class java.math.BigDe cimal
value is 1.001 <<<<<<<<<< DIFFERENT!
as getDouble it's 1.001
double d = 1.001d gives 1.001
new Double("1.001") .doubleValue() gives 1.001
they are equal.
new BigDecimal(1.00 1d) gives 1.0009999999999 998898658759571 844711899757385 25390625
new BigDecimal( new Double("1.001") .doubleValue() ) gives 1.0009999999999 998898658759571 844711899757385 25390625

The program:

------------------------------------------------------------------------------------------
import java.io.*;
import java.util.*;
import java.net.*;
import java.sql.*;

import weblogic.common .*;

public class db2
{
public static void main(String argv[])
throws Exception
{
Connection c = null;
try
{

java.util.Prope rties props = new java.util.Prope rties();
Driver d = (Driver)Class.f orName("COM.ibm .db2.jdbc.app.D B2Driver").newI nstance();
props.put("user ", "wls");
props.put("pass word", "wls");
props.put("Data baseName", "wls");
String URL = "jdbc:db2:wls1" ;

c = d.connect(URL, props);

DatabaseMetaDat a dm = c.getMetaData() ;
System.out.prin tln(dm.getDrive rVersion());
System.out.prin tln("Database version is " + dm.getDatabaseP roductVersion() );

Statement s = c.createStateme nt();
try{s.executeUp date("drop table joe");}catch (Exception ignore){}
s.executeUpdate ("create table joe (bar decimal(4,3))") ;
s.executeUpdate ("insert into joe values(1.001)") ;
PreparedStateme nt p = c.prepareStatem ent("insert into joe values(?)");
p.setDouble(1, new Double("1.001") .doubleValue()) ;
p.executeUpdate ();

System.out.prin tln("Testing value " + new Double("1.001") .doubleValue() );
ResultSet r = s.executeQuery( "select * from joe");
while (r.next())
{
System.out.prin tln("native driver object is a " + r.getObject(1). getClass() );
System.out.prin tln(" value is " + r.getObject(1) );
System.out.prin tln("as getDouble it's " + r.getDouble(1) );
}

double d = 1.001d;
double dd = new Double("1.001") .doubleValue();
System.out.prin tln("double d = 1.001d gives " + d );
System.out.prin tln("new Double(\"1.001\ ").doubleValue( ) gives " + dd );
if (d == dd)
System.out.prin tln("they are equal." );
else
System.out.prin tln("they are not equal." );

System.out.prin tln("new BigDecimal(1.00 1d) gives " + new BigDecimal(1.00 1d) );
System.out.prin tln("new BigDecimal( new Double(\"1.001\ ").doubleValue( ) ) gives "
+ new BigDecimal( new Double("1.001") .doubleValue() ) );

}
catch (Exception e)
{ e.printStackTra ce(); }
finally
{ try {c.close();}cat ch (Exception e){} }
}
}

Feb 16 '06 #1
15 2441
Joe Weinstein wrote:
Results on Linux Box
--------------------------------------------------------------
-bash-2.05b$ java db2
08.02.0001
Database version is 08.02.0000
Testing value 1.001
native driver object is a class java.math.BigDe cimal
value is 1.001
as getDouble it's 1.0010000000000 001 <<<<<<<<<< SEE
THIS! native driver object is a class java.math.BigDe cimal
value is 1.001
as getDouble it's 1.0010000000000 001 <<<<<<<<<< SEE
THIS! double d = 1.001d gives 1.001
new Double("1.001") .doubleValue() gives 1.001
they are equal.
new BigDecimal(1.00 1d) gives
1.0009999999999 998898658759571 844711899757385 253906 25
new BigDecimal( new Double("1.001") .doubleValue() ) gives
1.0009999999999 998898658759571 844711899757385 25390625
Results on Solaris Box
---------------------------------------------------------------
bash-3.00$java db2
08.02.0002
Database version is 08.02.0000
Testing value 1.001
native driver object is a class java.math.BigDe cimal
value is 1.001
as getDouble it's 1.001 <<<<<<<<<<
DIFFERENT! native driver object is a class java.math.BigDe cimal
value is 1.001 <<<<<<<<<<
DIFFERENT!
as getDouble it's 1.001
double d = 1.001d gives 1.001
new Double("1.001") .doubleValue() gives 1.001
they are equal.
new BigDecimal(1.00 1d) gives
1.0009999999999 998898658759571 844711899757385 25390625 new BigDecimal( new
Double("1.001") .doubleValue() ) gives
1.0009999999999 998898658759571 844711899757385 25390625
------------------------------------------------------------------


You should compare the binary representation of the double value. I assume
that _those_ are identical and what you are seeing is due to varying
implementations in your JVMs when the double value is converted to a
string.

--
Knut Stolze
DB2 Information Integration Development
IBM Germany
Feb 17 '06 #2
Joe Weinstein wrote:
Hi. Below is a simple JDBC program to insert and extract
a numerical value. When ResultSet.getDo uble() is called,
the same program produces different output on solaris
than it does on Linux.


String-Output of double/float values depends on the JVM.

But this isn't a problem of Java - its a problem we have since the
invention of floating point operations.

Thats why mercantile applications are using BCD, fixed point or simply
rounding every result to the precision needed.

Bernd
Feb 17 '06 #3
Thanks much. I think you're right. I'll do that.
thanks,
Joe

Knut Stolze wrote:
Joe Weinstein wrote:

Results on Linux Box
--------------------------------------------------------------
-bash-2.05b$ java db2
08.02.0001
Database version is 08.02.0000
Testing value 1.001
native driver object is a class java.math.BigDe cimal
value is 1.001
as getDouble it's 1.0010000000000 001 <<<<<<<<<< SEE
THIS! native driver object is a class java.math.BigDe cimal
value is 1.001
as getDouble it's 1.0010000000000 001 <<<<<<<<<< SEE
THIS! double d = 1.001d gives 1.001
new Double("1.001") .doubleValue() gives 1.001
they are equal.
new BigDecimal(1.00 1d) gives
1.00099999999 999988986587595 718447118997573 85253906 25
new BigDecimal( new Double("1.001") .doubleValue() ) gives
1.00099999999 999988986587595 718447118997573 8525390625
Results on Solaris Box
---------------------------------------------------------------
bash-3.00$java db2
08.02.0002
Database version is 08.02.0000
Testing value 1.001
native driver object is a class java.math.BigDe cimal
value is 1.001
as getDouble it's 1.001 <<<<<<<<<<
DIFFERENT! native driver object is a class java.math.BigDe cimal
value is 1.001 <<<<<<<<<<
DIFFERENT!
as getDouble it's 1.001
double d = 1.001d gives 1.001
new Double("1.001") .doubleValue() gives 1.001
they are equal.
new BigDecimal(1.00 1d) gives
1.00099999999 999988986587595 718447118997573 8525390625 new BigDecimal( new
Double("1.001 ").doubleValue( ) ) gives
1.00099999999 999988986587595 718447118997573 8525390625
------------------------------------------------------------------

You should compare the binary representation of the double value. I assume
that _those_ are identical and what you are seeing is due to varying
implementations in your JVMs when the double value is converted to a
string.


Feb 17 '06 #4


Bernd Hohmann wrote:
Joe Weinstein wrote:
Hi. Below is a simple JDBC program to insert and extract
a numerical value. When ResultSet.getDo uble() is called,
the same program produces different output on solaris
than it does on Linux.

String-Output of double/float values depends on the JVM.

But this isn't a problem of Java - its a problem we have since the
invention of floating point operations.

Thats why mercantile applications are using BCD, fixed point or simply
rounding every result to the precision needed.

Bernd


Thanks. I should have checked this out. I will.
Joe

Feb 17 '06 #5
Joe Weinstein wrote:
Thanks. I should have checked this out. I will.


Glad to help. If you need more or something else - DB2 JDBC bothers me
since years :-)

Bernd
Feb 17 '06 #6
Hi Knut. I just rechecked the code I sent, and it includes
some stuff to verify whether the JVM itself is printing
stuff differently, and it's not. It's just the driver's
getDouble() that behaves differently.
If you see anything I missed about checking the
JVM itself, let me know what to try. Thanks
Joe

Statement s = c.createStateme nt();
try{s.executeUp date("drop table joe");}catch (Exception ignore){}
s.executeUpdate ("create table joe (bar decimal(4,3))") ;
s.executeUpdate ("insert into joe values(1.001)") ;
PreparedStateme nt p = c.prepareStatem ent("insert into joe values(?)");
p.setDouble(1, new Double("1.001") .doubleValue()) ;
p.executeUpdate ();

System.out.prin tln("Testing value " + new Double("1.001") .doubleValue() );
ResultSet r = s.executeQuery( "select * from joe");
while (r.next())
{
System.out.prin tln("native driver object is a " + r.getObject(1). getClass() );
System.out.prin tln(" value is " + r.getObject(1) );
System.out.prin tln("as getDouble it's " + r.getDouble(1) );
}

double d = 1.001d;
double dd = new Double("1.001") .doubleValue();
System.out.prin tln("double d = 1.001d gives " + d );
System.out.prin tln("new Double(\"1.001\ ").doubleValue( ) gives " + dd );
if (d == dd)
System.out.prin tln("they are equal." );
else
System.out.prin tln("they are not equal." );

System.out.prin tln("new BigDecimal(1.00 1d) gives " + new BigDecimal(1.00 1d) );
System.out.prin tln("new BigDecimal( new Double(\"1.001\ ").doubleValue( ) ) gives "
+ new BigDecimal( new Double("1.001") .doubleValue() ) );

Knut Stolze wrote:
Joe Weinstein wrote:

Results on Linux Box
--------------------------------------------------------------
-bash-2.05b$ java db2
08.02.0001
Database version is 08.02.0000
Testing value 1.001
native driver object is a class java.math.BigDe cimal
value is 1.001
as getDouble it's 1.0010000000000 001 <<<<<<<<<< SEE
THIS! native driver object is a class java.math.BigDe cimal
value is 1.001
as getDouble it's 1.0010000000000 001 <<<<<<<<<< SEE
THIS! double d = 1.001d gives 1.001
new Double("1.001") .doubleValue() gives 1.001
they are equal.
new BigDecimal(1.00 1d) gives
1.00099999999 999988986587595 718447118997573 85253906 25
new BigDecimal( new Double("1.001") .doubleValue() ) gives
1.00099999999 999988986587595 718447118997573 8525390625
Results on Solaris Box
---------------------------------------------------------------
bash-3.00$java db2
08.02.0002
Database version is 08.02.0000
Testing value 1.001
native driver object is a class java.math.BigDe cimal
value is 1.001
as getDouble it's 1.001 <<<<<<<<<<
DIFFERENT! native driver object is a class java.math.BigDe cimal
value is 1.001 <<<<<<<<<<
DIFFERENT!
as getDouble it's 1.001
double d = 1.001d gives 1.001
new Double("1.001") .doubleValue() gives 1.001
they are equal.
new BigDecimal(1.00 1d) gives
1.00099999999 999988986587595 718447118997573 8525390625 new BigDecimal( new
Double("1.001 ").doubleValue( ) ) gives
1.00099999999 999988986587595 718447118997573 8525390625
------------------------------------------------------------------

You should compare the binary representation of the double value. I assume
that _those_ are identical and what you are seeing is due to varying
implementations in your JVMs when the double value is converted to a
string.


Feb 17 '06 #7
Joe Weinstein wrote:
Hi Knut. I just rechecked the code I sent, and it includes
some stuff to verify whether the JVM itself is printing
stuff differently, and it's not. It's just the driver's
getDouble() that behaves differently.
If you see anything I missed about checking the
JVM itself, let me know what to try. Thanks
Joe

Statement s = c.createStateme nt();
try{s.executeUp date("drop table joe");}catch (Exception ignore){}
s.executeUpdate ("create table joe (bar decimal(4,3))") ;
s.executeUpdate ("insert into joe values(1.001)") ;
PreparedStateme nt p = c.prepareStatem ent("insert into joe
values(?)"); p.setDouble(1, new Double("1.001") .doubleValue()) ;
p.executeUpdate ();

System.out.prin tln("Testing value " + new
Double("1.001") .doubleValue() ); ResultSet r =
s.executeQuery( "select * from joe"); while (r.next())
{
System.out.prin tln("native driver object is a " +
r.getObject(1). getClass() ); System.out.prin tln(" value is " +
r.getObject(1) ); System.out.prin tln("as getDouble it's " +
r.getDouble(1) );
}

double d = 1.001d;
double dd = new Double("1.001") .doubleValue();
System.out.prin tln("double d = 1.001d gives " + d );
System.out.prin tln("new Double(\"1.001\ ").doubleValue( ) gives " +
dd ); if (d == dd)
System.out.prin tln("they are equal." );
else
System.out.prin tln("they are not equal." );

System.out.prin tln("new BigDecimal(1.00 1d) gives " + new
BigDecimal(1.00 1d) ); System.out.prin tln("new BigDecimal( new
Double(\"1.001\ ").doubleValue( ) ) gives "
+ new BigDecimal( new Double("1.001") .doubleValue() ) );


You are not looking at the binary representation of the numbers. Everything
else are just the usual rounding issues related to the conversion between
the internal binary format and the external decimal format.

You should also read this article to understand how floating point numbers
are represented in today's computer systems:
http://cch.loria.fr/documentation/IE...M/goldberg.pdf

--
Knut Stolze
DB2 Information Integration Development
IBM Germany
Feb 17 '06 #8


Knut Stolze wrote:
Joe Weinstein wrote:

Hi Knut. I just rechecked the code I sent, and it includes
some stuff to verify whether the JVM itself is printing
stuff differently, and it's not. It's just the driver's
getDouble() that behaves differently.
If you see anything I missed about checking the
JVM itself, let me know what to try. Thanks
Joe

Statement s = c.createStateme nt();
try{s.executeUp date("drop table joe");}catch (Exception ignore){}
s.executeUpdate ("create table joe (bar decimal(4,3))") ;
s.executeUpdate ("insert into joe values(1.001)") ;
PreparedStateme nt p = c.prepareStatem ent("insert into joe
values(?)"); p.setDouble(1, new Double("1.001") .doubleValue()) ;
p.executeUpdate ();

System.out.prin tln("Testing value " + new
Double("1.001") .doubleValue() ); ResultSet r =
s.executeQuery( "select * from joe"); while (r.next())
{
System.out.prin tln("native driver object is a " +
r.getObject(1). getClass() ); System.out.prin tln(" value is " +
r.getObject(1) ); System.out.prin tln("as getDouble it's " +
r.getDouble(1) );
}

double d = 1.001d;
double dd = new Double("1.001") .doubleValue();
System.out.prin tln("double d = 1.001d gives " + d );
System.out.prin tln("new Double(\"1.001\ ").doubleValue( ) gives " +
dd ); if (d == dd)
System.out.prin tln("they are equal." );
else
System.out.prin tln("they are not equal." );

System.out.prin tln("new BigDecimal(1.00 1d) gives " + new
BigDecimal(1.00 1d) ); System.out.prin tln("new BigDecimal( new
Double(\"1.001\ ").doubleValue( ) ) gives "
+ new BigDecimal( new Double("1.001") .doubleValue() ) );

You are not looking at the binary representation of the numbers. Everything
else are just the usual rounding issues related to the conversion between
the internal binary format and the external decimal format.


Actually, yes I am. I am banking off the spec for BigDecimal:
"Translates a double into a BigDecimal which is the exact decimal
representation of the double's binary floating-point value."

I'll see if I can make some more additions to make it clearer to me.
thanks,
Joe

You should also read this article to understand how floating point numbers
are represented in today's computer systems:
http://cch.loria.fr/documentation/IE...M/goldberg.pdf


Feb 17 '06 #9
Joe Weinstein wrote:
Actually, yes I am. I am banking off the spec for BigDecimal:
"Translates a double into a BigDecimal which is the exact decimal
representation of the double's binary floating-point value."


The issue I still have with this is that you are dealing with different
representations of floating point numbers and that you are still not
comparing the internal binary IEEE754 representation.

The Java manual (http://java.sun.com/j2se/1.4.2/docs/api/index.html) gives a
nice example, which most probably applies to your question:
-----------------------------------------------------
public BigDecimal(doub le val)

Translates a double into a BigDecimal. The scale of the BigDecimal is
the smallest value such that (10scale * val) is an integer.

Note: the results of this constructor can be somewhat unpredictable. One
might assume that new BigDecimal(.1) is exactly equal to .1, but it is
actually equal to .10000000000000 000555111512312 578270211815834 04541015625.
This is so because .1 cannot be represented exactly as a double (or, for
that matter, as a binary fraction of any finite length). Thus, the long
value that is being passed in to the constructor is not exactly equal
to .1, appearances notwithstanding .

The (String) constructor, on the other hand, is perfectly predictable:
new BigDecimal(".1" ) is exactly equal to .1, as one would expect.
Therefore, it is generally recommended that the (String) constructor be
used in preference to this one.
-----------------------------------------------------

I would recommend that you try "Double.compare " or
"Double.doubleT oRawLongBits" instead.

--
Knut Stolze
DB2 Information Integration Development
IBM Germany
Feb 20 '06 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
7069
by: Axel Dachtler | last post by:
Hello, my Java-program can't load the JDBC driver. I always get a java.lang.NoClassDefFoundError when I run it. The JDBC Driver is in the directory: C:\programs\ora92\jdbc\lib I think I have to set ORACLE_HOME environment variable and CLASSPATH, but I have no idea how ?????????
0
1861
by: Priya | last post by:
Hi, I am having some problem with DB2 Universal JDBC driver. 1. The method getColumnType(columnNumber)of ResultSetMetaData always returns zero. 2. The method getColumnDisplaySize(ColumnNum) raises an exception, with exception message - not supported. Version of DB2 - 7.1
4
6330
by: Dani | last post by:
Hi everyone Description of the problem: Using a PreparedStatement to write down an integer (int) plus a timestamp for testing purposes. When read out again the integer looks very different. We found that it was shifted three Bytes to the left, i.e. 4 becomes hex 4000000 which is 67108864 in decimal base. This means that the value written...
0
3075
by: Bing | last post by:
Hi, I am configuring the same DB2 v8.1 JDBC universal driver (db2jcc.jar and db2jcc_license_cisuz.jar) from DB2 SP5 fix pack under WSAD 5.1.x environment and WebSphere application Server 5.0.2 on Windows 2000 machines. I configured a connection pool data source using type 4 for a local test environment in WSAD 5.1.x, and a connection pool...
2
3747
by: Raquel | last post by:
Read this about the Universal JDBC Driver.... "In a Type 2 mode, the Universal JDBC driver provides local application performance gains (because it avoids using TCP/IP protocol to communicate to the DB2 server). " Wht does it mean by "local" application performance? In type 2 mode, it is a pre-requisite that all the databases that the...
1
1788
by: eugene | last post by:
Happy Christmas to all (who celebrate)! It's still not clear to me... when in a java stored procedure it says: conn = DriverManager.getConnection("jdbc:default:connection"); what driver DB2 database manager loads? Is it configurable on the database server side so I could switch between different JDBC driver types, i.e. 2 and 4? I am on DB2...
3
4966
by: kavallin | last post by:
I wonder if anyone has compared the db2 universal jdbc driver type 2 and 4 with the legacy db2 driver. Which one is the best to use ? I'm working in a project where the envm looks like this Solaris 10 Websphere 6.1 with app db2 connect 9 ============================as/400 5.3 as/400 databases cataloged on db2 connect with auth...
1
1876
by: Marc Melancon | last post by:
hi, Does MS2005 JDBC Driver 1.1 support integrated security on Solaris and if so how? Thanks, MarcM
0
1397
by: dunleav1 | last post by:
How can I be sure that DB2_LINUXAIO is working properly in DB 9 FP3? The parameter db2_linuxaio was depreciated from the base version to FP3 and my performance tests have shown a decrease in performance between the versions. DB2 9 FP3 on windows compared to windows seems to be about 40% faster in my first test. I have a few more to run... ...
0
7732
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language...
0
8243
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that...
0
8101
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the...
0
6456
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then...
1
5626
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes...
0
5302
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert...
0
3754
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
1347
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
0
1062
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.