Bug #18880 Resultset.getFloatFromString does not work for Float min or max value

Submitted: 7 Apr 2006 9:02 Modified: 26 Jul 2006 18:17
Reporter: Stephane Giron Email Updates:
Status: Closed Impact on me:
None 
Category:Connector / J Severity:S2 (Serious)
Version:3.1.12 OS:Linux (Linux Ubuntu)
Assigned to: CPU Architecture:Any

[7 Apr 2006 9:02] Stephane Giron
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);
            }
          }
        }
[26 May 2006 9:01] Tonci Grgin
Hi Stephane. Thanks for your problem report and your input on this.
Verified as described by user.
[18 Jul 2006 18:01] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/9289

Portions of this website are copyright © 2001, 2002 The PHP Group

Page generated in 0.052 sec. using MySQL 8.4.7-u6-cloud

Timestamp references displayed by the system are UTC.
Content reproduced on this site is the property of the respective copyright holders.
It is not reviewed in advance by Oracle and does not necessarily represent the opinion of Oracle or any other party.