From:             [EMAIL PROTECTED]
Operating system: LINUX
PHP version:      4.0.6
PHP Bug Type:     InterBase related
Bug description:  $105.04 becomes $105.4!!!

AAAARRRRGGG!! Interbase module has this orrible bug. It 
transforms any BIG INTEGER (ISC_INT64) type with decimal 
points are stripped of it's zeroes between decimal point 
and the first non-zero decimal cipher

I.E. 150.0045 becomes 150.45.

This bug is very fast to find in the code, because the 
transformation from Interbase to PHP data is done with an 
instruction like

sprintf (buffer, "%f.%f", [find integer part], [find 
fractional part]); and no control over the zeroes in the 
fractional part. Even wrose, this calculus are done with 2 
heavy double "pow" calls, divisions and modules (with an 
horrible waste of time...

Now, if I had done an error like that in a programming 
execice, my teacher would have given "2" to me, (that is, 
F), even if I have studied Economics, not IT. How could 
this error have survived since now? It could cost a very 
high price for users, if you think that all the 
transactions in dollars, euros, punds and any currency 
with a fractional part IS WRONG!

Now, I have patced the source; find the static int 
_php_ibase_var_pval function in the interbase.c file, ad 
substitute what is inside the #ifdef SQL_INT64 with the 
following code:

#ifdef SQL_INT64
        case SQL_INT64:
                /* Experimental section by Giancarlo 
Niccolai */
                if (scale) {
                        int i, len;
                        sprintf (string_data, "%Ld", 
(ISC_INT64) (*((ISC_INT64 *)data)));
                        len = strlen(string_data);
                        for (i = 0; i <= -scale; i ++) 
                        string_data[len-i+1] = 
string_data[len-i]; 
                        string_data[len-i+1] = '.';
                        val->value.str.len = len+1;
                        val->value.str.val = 
estrdup(string_data);
                }
                else {
                        val->value.str.len = sprintf 
(string_data, "%Ld", (ISC_INT64) (*((ISC_INT64 *)data)));
                        val->type = IS_STRING;
                        val->value.str.val = 
estrdup(string_data);
                        }
                        /* End of experimental section */
                   val->type = IS_STRING;
                
                /* OLD CODE */          
                /*val->value.str.len =                  
                sprintf(string_data, "%Ld.%Ld",
                                                        
                         (ISC_INT64) (*((ISC_INT64 *)data) 
/ (int) pow(10.0, (double) -scale)),
                                                        
                         (ISC_INT64) abs((int) 
(*((ISC_INT64 *)data) % (int) pow(10.0, (double) 
-scale))));
                        val->value.str.val = 
estrdup(string_data);*/
        break;
#endif

The code is faster (you'll have in the wrost case of all 
about 18 iterations on a char array), cleaner and work 
always.

Now, I hope you'll put this code in the PHP dists as soon 
as possible, and give a STRONG evidence of this problem in 
your site, possibily warining all PHP-INTERBASE users, 
that, as I know, are a LOT.

P.S. I found the same error in the PERL DBD::Interbase 
module; I will soon track it down and send a remark to the 
perl community.

Thanks in advance, 
Giancarlo Niccolai.



-- 
Edit bug report at: http://bugs.php.net/?id=12383&edit=1


-- 
PHP Development Mailing List <http://www.php.net/>
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
To contact the list administrators, e-mail: [EMAIL PROTECTED]

Reply via email to