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
pgpuyNiyxSMDg.pgp
Description: PGP signature
