Problem with truncation of floating point values in DBSlayer.

12 views
Skip to first unread message

Chris Dew

unread,
Jun 8, 2010, 12:01:37 PM6/8/10
to dbslayer
When I run a query through DB slayer, the floating point results are
truncated to a total of six digits (plus decimal point and negative
sign when needed).

{ ... "lat":52.2228,"lng":-2.19906, ... }

When I run the same query in MySQL, the results are as expected.

| 52.22280884 | -2.19906425 |

Firstly, am I correct in identifying DBSlayer as the cause of this
effect? (Or the JSON library, etc.)

Secondly, is floating point precision configurable within DBSlayer?

Thanks,

Chris.

P.S. Ubuntu 9.10, x86_64
chris@chris-desktop:~/dbslayer$ svn info
Path: .
URL: http://dbslayer.googlecode.com/svn/trunk
Repository Root: http://dbslayer.googlecode.com/svn
Repository UUID: 5df2be84-4748-0410-afd4-f777a056bd0c
Revision: 65
Node Kind: directory
Schedule: normal
Last Changed Author: dgottfrid
Last Changed Rev: 65
Last Changed Date: 2008-03-28 22:52:46 +0000 (Fri, 28 Mar 2008)


Chris Dew

unread,
Jun 9, 2010, 9:02:13 AM6/9/10
to dbslayer
I eventually solved this problem.

There are several places where DBSlayer uses printf's %g to format
doubles.

This gives only 6 significant digits. Replacing all of these
occurrences with %.15g, and recompiling, has solved the problem.

I have also fixed a bug with the -d switch, which didn't work.

If anyone from DBSlayer would like a diff, please reply.

Regards,

Chris.

Derek Gottfrid

unread,
Jun 9, 2010, 9:03:04 AM6/9/10
to dbsl...@googlegroups.com
Look at line

http://code.google.com/p/dbslayer/source/browse/trunk/common/serializejson.c#78

We can change this if you need - or submit a patch.

thanks,

d

> --
> You received this message because you are subscribed to the Google Groups "dbslayer" group.
> To post to this group, send email to dbsl...@googlegroups.com.
> To unsubscribe from this group, send email to dbslayer+u...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/dbslayer?hl=en.
>
>

Chris Dew

unread,
Jun 9, 2010, 10:24:23 AM6/9/10
to dbslayer
It looks like I was using a version which was already old at the time
I started using dbslayer last November - I think I may have had issues
getting HEAD to compile at the time. It looks like you've already
fixed the precision bug :-)

(I may not know what I'm talking about here...) I chose %.15g because
the wikipedia page on doubles says they provide 15.95 significant
digits. I was concerned that using %.16g would occasionally produce
strings like '2.0000000000001' (number of zeros in the example is
probably wrong). Is this an issue?

The last bit of the diff (for -d) may still be worth looking at.

Thanks,

Chris.

diff -Naur dbslayer/common/json2xml.c dbslayer.fixed/common/json2xml.c
--- dbslayer/common/json2xml.c 2008-04-02 18:35:07.000000000 +0100
+++ dbslayer.fixed/common/json2xml.c 2010-06-09 10:43:24.000000000
+0100
@@ -73,7 +73,7 @@
return apr_brigade_printf(bbrigade,NULL,NULL,"%ld",json-
>value.lnumber);
} else {
char *buf = apr_palloc(mpool,sizeof(char)*512);
- snprintf(buf,512,"%g",json->value.dnumber);
+ snprintf(buf,512,"%.15g",json->value.dnumber);
//apr %g doesn't prepend leading 0 for values less than 1 -
violates json parsers
return apr_brigade_printf(bbrigade,NULL,NULL,buf);
}
diff -Naur dbslayer/common/serializejson.c dbslayer.fixed/common/
serializejson.c
--- dbslayer/common/serializejson.c 2008-04-02 18:35:07.000000000
+0100
+++ dbslayer.fixed/common/serializejson.c 2010-06-09
10:43:08.000000000 +0100
@@ -75,7 +75,7 @@
return apr_brigade_printf(bbrigade,NULL,NULL,"%ld",json-
>value.lnumber);
} else {
char *buf = apr_palloc(mpool,sizeof(char)*512);
- snprintf(buf,512,"%g",json->value.dnumber);
+ snprintf(buf,512,"%.15g",json->value.dnumber);
//apr %g doesn't prepend leading 0 for values less than 1 -
violates json parsers
return apr_brigade_printf(bbrigade,NULL,NULL,buf);
}
diff -Naur dbslayer/common/siworthmplejson.c dbslayer.fixed/common/
simplejson.c
--- dbslayer/common/simplejson.c 2008-04-02 18:35:07.000000000 +0100
+++ dbslayer.fixed/common/simplejson.c 2010-06-09 10:33:04.000000000
+0100
@@ -417,7 +417,7 @@
if(json->type == JSON_LONG) {
printf("%ld",json->value.lnumber);
} else {
- printf("%g",json->value.dnumber);
+ printf("%.15g",json->value.dnumber);
}
}
void encode_json_boolean(json_value *json) {
diff -Naur dbslayer/common/slayer_http_server.c dbslayer.fixed/common/
slayer_http_server.c
--- dbslayer/common/slayer_http_server.c 2008-04-02 18:35:07.000000000
+0100
+++ dbslayer.fixed/common/slayer_http_server.c 2010-06-09
12:09:54.000000000 +0100
@@ -375,6 +375,7 @@

static void slayer_server_parse_args(int argc, char
**argv,slayer_http_server_t *server) {
int i;
+
for(i = 1; i < argc; i++) {
if(argv[i][0] == '-' && strlen(argv[i]) == 2) {
char *extra_arg = i+1 < argc && argv[i+1][0] != '-' ? argv[i+1] :
NULL;
@@ -389,7 +390,9 @@
server->basedir = extra_arg;
break;
case 'd':
- server->debug = extra_arg;
+ // This is required for the -d flag to take effect when
+ // no (completely unneeded) argument is supplied.
+ server->debug = extra_arg == NULL ? 1 : extra_arg;
break;
case 'e':
server->elogfile = extra_arg;

On Jun 9, 2:03 pm, Derek Gottfrid <de...@codecubed.com> wrote:
> Look at line
>
> http://code.google.com/p/dbslayer/source/browse/trunk/common/serializ...

Derek Gottfrid

unread,
Jun 9, 2010, 10:36:28 AM6/9/10
to dbsl...@googlegroups.com
Cool, I will check out the patches and let you know. Thanks for the help.

d

Reply all
Reply to author
Forward
0 new messages