freetds AT lists.ibiblio.org
Subject: FreeTDS Development Group
List archive
Re: [freetds] problem with dbconvert from float to money
- From: Frediano Ziglio <freddy77 AT gmail.com>
- To: FreeTDS Development Group <freetds AT lists.ibiblio.org>
- Subject: Re: [freetds] problem with dbconvert from float to money
- Date: Tue, 29 Sep 2009 08:04:12 +0200
2009/9/29 Stenuit, Pascal <Pascal.Stenuit AT gtech.com>:
> Hi,
>
> We are happily using FreeTDS as a replacement for Sybase's dblib and
> noticed a difference between the two implementations.
>
> It turns out that for the following code snippet:
>
> double amt = 123456.78;
>
> dbconvert(0, SYBFLT8, (unsigned char *) &amt, (DBINT)-1,
> SYBMONEY, out, (DBINT)-1);
>
> Sybase will encode the SYBMONEY as 1234567800 (fixed point, 4 decimals)
> while freetds will encode the value as 1234560000, in effect losing the
> decimals. I believe Sybase is probably right (or at least consistent
> with the reverse operation) but what do I know !
>
> The following patch to src/tds/convert.c could be what's needed (I'm not
> too sure about the bound checks).
>
> Thanks for a great software,
> pascal
>
>
> ~> ident convert.c.orig
> convert.c.orig:
> $Id: convert.c,v 1.192 2009/06/12 08:53:49 freddy77 Exp $
> ~> diff -u convert.c.orig convert.c
> --- convert.c.orig 2009-09-29 07:41:00.670880900 +0200
> +++ convert.c 2009-09-29 07:47:05.144408900 +0200
> @@ -1428,7 +1428,7 @@
> case SYBMONEY:
> if (the_value > (TDS_REAL) (TDS_INT8_MAX / 10000) ||
> the_value < (TDS_REAL) (TDS_INT8_MIN / 10000))
> return TDS_CONVERT_OVERFLOW;
> - mymoney = ((TDS_INT8) the_value) * 10000;
> + mymoney = (TDS_INT8) (the_value * 10000);
> cr->m.mny = mymoney;
> return sizeof(TDS_MONEY);
> break;
> @@ -1436,7 +1436,7 @@
> case SYBMONEY4:
> if (the_value > (TDS_REAL) (TDS_INT_MAX / 10000) ||
> the_value < (TDS_REAL) (TDS_INT_MIN / 10000))
> return TDS_CONVERT_OVERFLOW;
> - mymoney4 = ((TDS_INT) the_value) * 10000;
> + mymoney4 = (TDS_INT) (the_value * 10000);
> cr->m4.mny4 = mymoney4;
> return sizeof(TDS_MONEY4);
> break;
> @@ -1512,14 +1512,14 @@
> case SYBMONEY:
> if (the_value > (TDS_FLOAT) (TDS_INT8_MAX / 10000) ||
> the_value < (TDS_FLOAT) (TDS_INT8_MIN / 10000))
> return TDS_CONVERT_OVERFLOW;
> - cr->m.mny = ((TDS_INT8) the_value) * 10000;
> + cr->m.mny = (TDS_INT8) (the_value * 10000);
>
> return sizeof(TDS_MONEY);
> break;
> case SYBMONEY4:
> if (the_value > (TDS_FLOAT) (TDS_INT_MAX / 10000) ||
> the_value < (TDS_FLOAT) (TDS_INT_MIN / 10000))
> return TDS_CONVERT_OVERFLOW;
> - cr->m4.mny4 = ((TDS_INT) the_value) * 10000;
> + cr->m4.mny4 = (TDS_INT) (the_value * 10000);
> return sizeof(TDS_MONEY4);
> break;
> case SYBREAL:
>
I perfectly agree with this patch
freddy77
-
[freetds] problem with dbconvert from float to money,
Stenuit, Pascal, 09/29/2009
- Re: [freetds] problem with dbconvert from float to money, Frediano Ziglio, 09/29/2009
Archive powered by MHonArc 2.6.24.