php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #15151 Decimals/Numerics stored as int64 always display as xxx.2
Submitted: 2002-01-21 13:10 UTC Modified: 2002-04-29 15:20 UTC
From: mitch at tropical dot co dot cr Assigned:
Status: Closed Package: InterBase related
PHP Version: 4.1.1 OS: Windows
Private report: No CVE-ID: None
 [2002-01-21 13:10 UTC] mitch at tropical dot co dot cr
Decimals/Numerics that are stored as 64-bit integers always display as xxx.2.

The following should fix the problem:

Original code (on or about line 1782):

val->value.str.len = sprintf(string_data, "%Ld.%0*Ld",
     (ISC_INT64) (*((ISC_INT64 *)data) /
     (int) pow(10.0, (double) -scale)),
     -scale,
     (ISC_INT64) abs((int) (*((ISC_INT64 *)data) %
     (int) pow(10.0, (double) -scale))));

Change to:
val->value.str.len = sprintf(string_data, "%Ld",
     (ISC_INT64) (*((ISC_INT64 *)data) /
     (int) pow(10.0, (double) -scale)));
val->value.str.len += sprintf(string_data +
     val->value.str.len, ".%0*Ld",
     -scale,
    (ISC_INT64) abs((int) (*((ISC_INT64 *)data) %
    (int) pow(10.0, (double) -scale))));



The problem is with MSVC++.  It doesn't seem to like two int64s in the same sprintf statement.  I don't yet have all the pieces to compile the extension so I have not fully tested it, but I have duplicated the problem in a test program and verified that the above code fixes the problem in the test program.

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2002-01-21 13:15 UTC] mitch at tropical dot co dot cr
This is also reported as #13807
 [2002-03-27 11:06 UTC] mitch at tropical dot co dot cr
The original fix I posted has its own bug (due to me not VC++) when the number is less than 0 but greater than -1 the negative sign does not appear.  This fixes it (and the original problem also):
case SQL_INT64:
tv64 = (ISC_INT64) *((ISC_INT64 *) data);
			iv64 = (tv64 / (int) pow(10.0, (double) -scale));
			fv64 = (ISC_INT64) abs((int) tv64 % (int) pow(10.0, (double) -scale));
			val->type = IS_STRING;
			if ( tv64 < 0  &&  iv64 == 0 ) 
				val->value.str.len = sprintf(string_data, "-0");
			else
				val->value.str.len = sprintf(string_data, "%Ld", iv64);
			val->value.str.len += sprintf(string_data + val->value.str.len, ".%0*Ld", -scale, fv64);
			val->value.str.val = estrdup(string_data);
			break;
 [2002-03-27 11:08 UTC] mitch at tropical dot co dot cr
The original fix I posted has its own bug (due to me not VC++) when the number is less than 0 but greater than -1 the negative sign does not appear.  This fixes it (and the original problem also):
Add these declarations:
 ISC_INT64	tv64;
 ISC_INT64	iv64;
 ISC_INT64	fv64;

then change the code:

case SQL_INT64:
 tv64 = (ISC_INT64) *((ISC_INT64 *) data);
 iv64 = (tv64 / (int) pow(10.0, (double) -scale));
 fv64 = (ISC_INT64) abs((int) tv64
       % (int) pow(10.0, (double) -scale));
 val->type = IS_STRING;
 if ( tv64 < 0  &&  iv64 == 0 ) 
  val->value.str.len = sprintf(string_data, "-0");
 else
  val->value.str.len = sprintf(string_data, "%Ld", iv64);
 val->value.str.len += sprintf(string_data +
           val->value.str.len, ".%0*Ld", -scale, fv64);
 val->value.str.val = estrdup(string_data);
 break;
 [2002-03-27 12:17 UTC] derick@php.net
please make a patch against the current CVS version.

Derick
 [2002-03-28 06:05 UTC] daniela@php.net
I think it must be already fixed in CVS.
Have a look at it and if you can try it on Win32.

Daniela
 [2002-04-29 00:00 UTC] php-bugs at lists dot php dot net
No feedback was provided for this bug for over a month, so it is
being suspended automatically. If you are able to provide the
information that was originally requested, please do so and change
the status of the bug back to "Open".
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Dec 26 11:01:30 2024 UTC