help-glpk
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Help-glpk] Least significant digit error in "table" statement


From: glpk xypron
Subject: Re: [Help-glpk] Least significant digit error in "table" statement
Date: Mon, 21 Feb 2011 21:55:01 +0100

Hello Marc,

I was able to reproduce the error with Access 2010 and
GLPK 4.45. The string returned by the ODBC library is indead
'E-2'.

I set up the same table in MySQL

create table tbl (
  FromCode Text(10),
  ToCode Text(10),
  TransitTime Double,
  Primary Key (FromCode(10), ToCode(10))
  );
  
Insert into tbl values ("A", "B", 1.91176470588235E-02);

The error did not occur.

In the current implementation of glpk-4.45/src/glpsql.c
the ODBC driver is requested to convert all values to
string (SQL_CHAR). Afterwards the value is converted
to double in function db_iodbc_read if it is numeric.

There seems to be a bug in the Access implementation
for number conversion.

When requesting the Access driver to convert the value
in question to double (SQL_DOUBLE) your example works
correctly.

Please, find the patch below.

Could you, please, give me some feedback after a more
extensive testing.

Best regards

Xypron


--- c:\Program Files\GLPK\glpk-4.45\src\glpsql.c        2010-12-05 
10:00:00.000000000 +0100
+++ glpsql.c    2011-02-21 21:47:40.519123900 +0100
@@ -840,8 +840,13 @@
             &nullable);
          sql->isnumeric[i] = is_numeric(sql->coltype[i]);
          /* bind columns to program vars, converting all types to CHAR*/
-         dl_SQLBindCol(sql->hstmt, i, SQL_CHAR, sql->data[i],
-            SQL_FDLEN_MAX, &(sql->outlen[i]));
+         if (sql->isnumeric[i])
+         {  dl_SQLBindCol(sql->hstmt, i, SQL_DOUBLE, sql->data[i],
+               SQL_FDLEN_MAX, &(sql->outlen[i]));
+         } else 
+         {  dl_SQLBindCol(sql->hstmt, i, SQL_CHAR, sql->data[i],
+               SQL_FDLEN_MAX, &(sql->outlen[i]));
+         }
          for (j = sql->nf; j >= 1; j--)
          {  if (strcmp(mpl_tab_get_name(dca, j), sql->colname[i]) == 0)
             break;
@@ -893,23 +898,17 @@
          len = sql->outlen[i];
          if (len != SQL_NULL_DATA)
          {
-            if (len > SQL_FDLEN_MAX)
-               len = SQL_FDLEN_MAX;
-            else if (len < 0)
-               len = 0;
-            strncpy(buf, (const char *) sql->data[i], len);
-            buf[len] = 0x00;
-            if (0 != (sql->isnumeric[i]))
-            {  strspx(buf); /* remove spaces*/
-               if (str2num(buf, &num) != 0)
-               {  xprintf("'%s' cannot be converted to a number.\n",
-                     buf);
-                  return 1;
-               }
-               mpl_tab_set_num(dca, sql->ref[i], num);
+            if (sql->isnumeric[i])
+            {  mpl_tab_set_num(dca, sql->ref[i], *((const double *) 
sql->data[i]));
             }
             else
-            {  mpl_tab_set_str(dca, sql->ref[i], strtrim(buf));
+            {  if (len > SQL_FDLEN_MAX)
+                  len = SQL_FDLEN_MAX;
+               else if (len < 0)
+                  len = 0;
+               strncpy(buf, (const char *) sql->data[i], len);
+               buf[len] = 0x00;
+               mpl_tab_set_str(dca, sql->ref[i], strtrim(buf));
             }
          }
       }


-------- Original-Nachricht --------
> Datum: Mon, 21 Feb 2011 03:15:10 -0600
> Betreff: [Help-glpk] Least significant digit error in "table" statement

> I have a simple "table" statement that fails with the message: 'E-2'
> cannot be converted to a number.
> 
> One of the input numbers (for the field TransitTime) is
> 0.0191176470588235.  When I strip away the least significant digit to make it
> 0.019117647058823, the "table" statement works fine.
> 
> The test code is below; the Access database and model file are attached.
> 
> param DB_LOCATION symbolic := "C:\TestOfTable.mdb";
> #param ACCESS_DRIVER symbolic := "Driver={Microsoft Access Driver
> (*.mdb)}";
> param ACCESS_DRIVER symbolic := "Driver={Microsoft Access Driver (*.mdb,
> *.accdb)}";
> 
> set OD_R dimen 2;
> param TransitTimeHours     {OD_R};
> 
> table R IN 'ODBC'
>    ACCESS_DRIVER & ';DBQ=' & DB_LOCATION & ';'
>   'SELECT FromCode, ToCode, TransitTime '
>   'FROM tbl'  :
>   OD_R                 <- [FromCode,ToCode],
>   TransitTimeHours      ~ TransitTime;
> 
> display card(OD_R);
> 
> end;
> 
> ________________________________
> This e-mail and any attachments may be confidential or legally privileged.
> If you received this message in error or are not the intended recipient,
> you should destroy the e-mail message and any attachments or copies, and you
> are prohibited from retaining, distributing, disclosing or using any
> information contained herein. Please inform us of the erroneous delivery by
> return e-mail. Thank you for your cooperation.

-- 
Empfehlen Sie GMX DSL Ihren Freunden und Bekannten und wir
belohnen Sie mit bis zu 50,- Euro! https://freundschaftswerbung.gmx.de



reply via email to

[Prev in Thread] Current Thread [Next in Thread]