On 2008-03-14 12:44:29 +0000, [EMAIL PROTECTED] wrote:
> Peter J. Holzer - [EMAIL PROTECTED] wrote:
> > On 2008-03-14 09:50:15 +0000, [EMAIL PROTECTED] wrote:
> >> This is more for the archives than anything as there is a workaround.
> >>
> >> When inserting 1234567890.123456 into a decimal(16,6) column, the value 
> >> stored is 1234567890.123460
> >
> > The value 1234567890.123456 is not exactly representable in a perl
> > numeric scalar (assuming 64 bit double, which is a reasonable
> 
> perl -V gives doublesize=8
> 
> > assumption). The nearest representable approximation is
> > 1234567890.12345600128173828125.
> >
> > However, rounding that to 6 digits after the comma is 1234567890.123456,
> > so I don't see a reason for the wrong rounding. It looks more like if
> > it's rounded to 5 digits instead of 6.
> 
> Time::HiRes docs say
> "What is going on is that the default floating point
>            format of Perl only outputs 15 digits.  In this case
>            that means ten digits before the decimal separator and
>            five after"

Ah, yes. I should have checked that as I've run into this issue before
(although not in a DBI context). My fault. That's a bug in perl itself,
not in DBD::mysql. Under some conditions the number to string conversion
stops one or even two digits too soon. I looked at that code a few
months ago and I know where it happens and why it happens but I didn't
get around to prepare a patch and send it to p5p. (floating point
arithmetic is tricky - I'd feel more comfortable reusing a well-known
implementation of a known well-behaved algorithm than implementing one
of my own).


> >> Is this expected behaviour or should DBD::mysql automagically do the right 
> >> thing?
> >
> > I would expect rounding errors when passing numeric scalars to "decimal"
> > types in general, but not in this case - that should be handled
> > correctly (because it can).
> 
> I wasn't sure it could be or not. Unless the driver knows the precision of 
> course.

Since perl itself gets the conversion wrong, that would be a necessary
condition. If DBD::mysql knows that the type is decimal(X,Y), it can
invoke an sprintf("%.Ys",...) itself. But I don't know how easily DBD::mysql
can get that info - if it means a round-trip to the database you might
want to avoid that.

> It's probably a good idea to put something in the docs, a la 
> Time::HiRes.

ACK.

        hp

-- 
   _  | Peter J. Holzer    | If I wanted to be "academically correct",
|_|_) | Sysadmin WSR       | I'd be programming in Java.
| |   | [EMAIL PROTECTED]      | I don't, and I'm not.
__/   | http://www.hjp.at/ |   -- Jesse Erlbaum on dbi-users

Attachment: pgpuyNiyxSMDg.pgp
Description: PGP signature

Reply via email to