Re: Re: cvs: php-src /ext/sybase_ct
| From: | Timm Friebe | Date: | Sun, 16 May 2004 15:57:00 +0000 |
| Subject: | Re: Re: cvs: php-src /ext/sybase_ct | ||
| References: | 1 2 3 4 5 6 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-9876@lists.php.net to get a copy of this message | ||
On Sun, 2004-05-16 at 17:17, Ard Biesheuvel wrote:
> Hi Timm,
>
> I have an old Alpha PWS433 running FreeBSD which I use for this kind of
> stuff.
>
> > If so, what does this print?
> > --------------------------------------------------------------------------
> > #define LONG_MAX 2147483647L
> > #define LONG_MIN (- LONG_MAX - 1)
>
> Use this for portability
>
> #define LONG_MIN (1L << 8*sizeof(long)-1)
> #define LONG_MAX ~LONG_MIN
Urm... yes:) LONG_MAX is definitely not 2147483647L on 64-bit:)
> > int main(int argc, char* argv)
> > {
> > printf("1) %s\n", (double)LONG_MAX + 1 > LONG_MAX ? "+OK" :
> > "-ERR");
> > printf("2) %s\n", (double)LONG_MIN - 1 < LONG_MIN ? "+OK" :
> > "-ERR");
> > }
>
> 1) -ERR
> 2) -ERR
OK, I found some discussion on this topic using Google. If I understand
correctly, double on 64-bit platforms isn't accurate enough to hold a
long, right?
> > I thought this code was OK by looking at the following:
> >
> > Zend/zend_operators.c:#define DVAL_TO_LVAL(d, l) (l) = (d) > LONG_MAX ?
> > (unsigned long) (d) : (long) (d)
>
> The problem in your code wasn't the comparison per se, but the
> conversion from long to double and back. You will lose accuracy by doing
> that. The value you're converting started out as a long, didn't it ?
Nope, before the first conversion it's actually a string (see
php_sybase_ct.c, lines 1131 to 1123).
To bring this discussion to an end: How does the portable solution look
like? Or, to be more specific, what would need to be done for this to
work portably:
-- snip --
Z_STRLEN(result->data[i][j]) = result->lengths[j]-1;
Z_STRVAL(result->data[i][j]) = estrndup(result->tmp_buffer[j],
result->lengths[j]);
Z_TYPE(result->data[i][j]) = IS_STRING;
/* Now I want to figure out whether this fits into a long,
* and if it does, make it one, a double otherwise
*/
-- snip --
Possible ideas would be to use strtol and check for ERANGE (sample
attached).
- Timm
Attachment: [text/x-c] long.c
Attachment: [text/x-c] long.c