Description:
Double.parseDouble(string) and Float.parseFloat(String) may give different results for a same string, as shown in this example :
String strMin = Float.toString(Float.MIN_VALUE);
String strMax = Float.toString(Float.MAX_VALUE);
System.out.println(Float.parseFloat(strMin) == Double.parseDouble(strMin));
System.out.println(Float.parseFloat(strMax) == Double.parseDouble(strMax));
The result of this for me is :
false
false
This simple example is equivalent to what is done is Resultset.getFloatFromString, which is called when using CallableStatement.getFloat().
How to repeat:
stmt = conn.createStatement();
stmt
.executeUpdate("create table Real_Tab (MAX_VAL REAL, MIN_VAL REAL,NULL_VAL REAL NULL) ");
stmt.executeUpdate("drop procedure if exists Real_Proc");
stmt.executeUpdate("create procedure Real_Proc (OUT MAX_PARAM REAL, OUT MIN_PARAM REAL, OUT NULL_PARAM REAL) select MAX_VAL, MIN_VAL, NULL_VAL into MAX_PARAM, MIN_PARAM, NULL_PARAM from Real_Tab;");
stmt.executeUpdate("insert into Real_Tab values(3.4E38,1.4E-45, null)");
cstmt = conn.prepareCall("{call Real_Proc(?,?,?)}");
cstmt.registerOutParameter(1, java.sql.Types.REAL);
cstmt.registerOutParameter(2, java.sql.Types.REAL);
cstmt.registerOutParameter(3, java.sql.Types.REAL);
cstmt.execute();
float fRetVal = cstmt.getFloat(2);
Suggested fix:
Simple fix is to take account of the precision loss, as shown below.
if (this.connection.getJdbcCompliantTruncation())
{
if (f == Float.MIN_VALUE || f == Float.MAX_VALUE)
{
double valAsDouble = Double.parseDouble(val);
// Get the string representations of float min and max values
String strMin = Float.toString(Float.MIN_VALUE);
String strMax = Float.toString(Float.MAX_VALUE);
// Check if there is a difference of precision between float and
// double representation of those strings
double minDiffPrec = Float.parseFloat(strMin)
- Double.parseDouble(strMin);
double maxDiffPrec = Float.parseFloat(strMax)
- Double.parseDouble(strMax);
// Now take into accounts these potential differences
if ((valAsDouble < Float.MIN_VALUE - minDiffPrec)
|| (valAsDouble > Float.MAX_VALUE - maxDiffPrec))
{
throwRangeException(String.valueOf(valAsDouble), columnIndex,
Types.FLOAT);
}
}
}