[patch] problem with floats
Nirgal Vourgère <[email protected]> Sun, 6 Feb 2011 17:47:21 +0000
| Newsgroups | gmane.comp.db.mdb-tools.devel |
|---|---|
| Message-ID | <[email protected]> |
Hello
I have a problem introduced by the fix of http://bugs.debian.org/220403
Here was a part of the patch:
Index: mdbtools-0.6pre1/src/libmdb/data.c
===================================================================
--- mdbtools-0.6pre1.orig/src/libmdb/data.c
+++ mdbtools-0.6pre1/src/libmdb/data.c
@@ -857,7 +857,7 @@
break;
case MDB_FLOAT:
tf = mdb_get_single(buf, start);
- text = g_strdup_printf("%.*e",
+ text = g_strdup_printf("%.*f",
FLT_DIG - floor_log10(tf,1) - 1, tf);
break;
case MDB_DOUBLE:
Rebuilding with MDB_DEBUG, I have this kind of output for prdata:
055b 00 24 64 46
column 1 is 1.5e+04
Python tells me the output should be
struct.unpack('f', '\x00\x24\x64\x46')
14601.0
When reverting the patch, I get from prdata:
055b 00 24 64 46
column 1 is 14601.0
I tried 1e-7 that was supposed not to work, and was the reason the patch was introduced. I have no problem:
column 1 is 0.000000100000
You'll notice the unusual syntax "%.*f" that takes 2 arguments: the precision then the value.
I don't feel confortable exporting floats such as 1e-37 as a very long string, so I suggest we keep the 'e' format.
The precision however is wrong.
I was about to use FLT_DIG, but it is repported buggy. :/
Here, I have FLT_MANT_DIG==24 bits, meaning the maximum number without the exponent is 2^24=16777216
The number of digits in a decimal representation is ceil(log10(16777216))=8
The number of characters before the dot is not taken into account when specifying the precision
printf("%.*e\n", 3, 1.23456789) -> 1.235e+00
So that leave us with an extra number character. I assume this is usefull going arround roundings.
Does that sound ok?
Attached is the patch.
I added some '-lm' for the linker to find the builtin math functions. I'm not very familiar with automake, you'd better check I did it right.
Or maybe the original patch should just be reverted (for both MDB_FLOAT and MDB_DOUBLE)...
------------------------------------------------------------------------------
The modern datacenter depends on network connectivity to access resources
and provide services. The best practices for maximizing a physical server's
connectivity to a physical network are well understood - see how these
rules translate into the virtual world?
http://p.sf.net/sfu/oracle-sfdevnlfb
_______________________________________________
mdbtools-dev mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/mdbtools-dev
floats.diff
(text/x-patch, 2.5 KB)
Index: mdbtools-0.6pre1/src/libmdb/data.c
===================================================================
--- mdbtools-0.6pre1.orig/src/libmdb/data.c
+++ mdbtools-0.6pre1/src/libmdb/data.c
@@ -803,6 +803,7 @@
return text;
}
+#if 0
int floor_log10(double f, int is_single)
{
unsigned int i;
@@ -831,6 +832,7 @@
return (int)i;
}
}
+#endif
char *mdb_col_to_string(MdbHandle *mdb, void *buf, int start, int datatype, int size)
{
@@ -857,12 +859,12 @@
case MDB_FLOAT:
tf = mdb_get_single(buf, start);
text = g_strdup_printf("%.*e",
- FLT_DIG - floor_log10(tf,1) - 1, tf);
+ (int)ceil(log10(1L<<FLT_MANT_DIG)), tf);
break;
case MDB_DOUBLE:
td = mdb_get_double(buf, start);
text = g_strdup_printf("%.*e",
- DBL_DIG - floor_log10(td,0) - 1, td);
+ (int)ceil(log10(1L<<DBL_MANT_DIG)), td);
break;
case MDB_BINARY:
case MDB_TEXT:
Index: mdbtools-0.6pre1/src/libmdb/Makefile.am
===================================================================
--- mdbtools-0.6pre1.orig/src/libmdb/Makefile.am
+++ mdbtools-0.6pre1/src/libmdb/Makefile.am
@@ -2,4 +2,4 @@
libmdb_la_SOURCES= catalog.c mem.c file.c kkd.c table.c data.c dump.c backend.c money.c sargs.c index.c like.c write.c stats.c map.c props.c worktable.c options.c iconv.c
libmdb_la_LDFLAGS = -version-info 1:0:0
AM_CPPFLAGS = -I$(top_srcdir)/include $(GLIB_CFLAGS)
-LIBS = $(GLIB_LIBS) @LIBS@
+LIBS = $(GLIB_LIBS) @LIBS@ -lm
Index: mdbtools-0.6pre1/src/odbc/Makefile.am
===================================================================
--- mdbtools-0.6pre1.orig/src/odbc/Makefile.am
+++ mdbtools-0.6pre1/src/odbc/Makefile.am
@@ -16,7 +16,7 @@
$(patsubst %, $(MDBDIR)/%, \
$(patsubst %.c, %.lo, $(MDBSOURCES))) \
../libmdb/libmdb.la
-LIBS = @LEXLIB@ $(GLIB_LIBS) $(ODBC_LIBS)
+LIBS = @LEXLIB@ $(GLIB_LIBS) $(ODBC_LIBS) -lm
unittest_LDADD = libmdbodbc.la ../libmdb/libmdb.la ../sql/libmdbsql.la
## Need blank statement to avoid compiling odbc.c
Index: mdbtools-0.6pre1/src/util/Makefile.am
===================================================================
--- mdbtools-0.6pre1.orig/src/util/Makefile.am
+++ mdbtools-0.6pre1/src/util/Makefile.am
@@ -1,6 +1,6 @@
bin_PROGRAMS = mdb-export mdb-array mdb-schema mdb-tables mdb-parsecsv mdb-header mdb-sql mdb-ver mdb-prop
noinst_PROGRAMS = mdb-import prtable prcat prdata prkkd prdump prole updrow prindex
-LIBS = $(GLIB_LIBS) @LIBS@ @LEXLIB@
+LIBS = $(GLIB_LIBS) @LIBS@ @LEXLIB@ -lm
DEFS = @DEFS@ -DLOCALEDIR=\"$(localedir)\"
AM_CPPFLAGS = -I$(top_srcdir)/include $(GLIB_CFLAGS)
LDADD = ../libmdb/libmdb.la