Corrected an off-by-one error (lib/6314 Torbjorn Granlund)
This commit is contained in:
parent
6ee909b24f
commit
8dab0300c3
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: fixunsdfdi.c,v 1.4 1997/07/13 20:01:45 christos Exp $ */
|
||||
/* $NetBSD: fixunsdfdi.c,v 1.5 1999/03/26 21:04:24 kristerw Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1992, 1993
|
||||
|
@ -42,7 +42,7 @@
|
|||
#if 0
|
||||
static char sccsid[] = "@(#)fixunsdfdi.c 8.1 (Berkeley) 6/4/93";
|
||||
#else
|
||||
__RCSID("$NetBSD: fixunsdfdi.c,v 1.4 1997/07/13 20:01:45 christos Exp $");
|
||||
__RCSID("$NetBSD: fixunsdfdi.c,v 1.5 1999/03/26 21:04:24 kristerw Exp $");
|
||||
#endif
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
|
@ -61,8 +61,8 @@ u_quad_t
|
|||
__fixunsdfdi(x)
|
||||
double x;
|
||||
{
|
||||
double toppart;
|
||||
union uu t;
|
||||
unsigned long tmp;
|
||||
|
||||
if (x < 0)
|
||||
return (UQUAD_MAX); /* ??? should be 0? ERANGE??? */
|
||||
|
@ -74,30 +74,14 @@ __fixunsdfdi(x)
|
|||
return (UQUAD_MAX);
|
||||
#endif
|
||||
/*
|
||||
* Get the upper part of the result. Note that the divide
|
||||
* may round up; we want to avoid this if possible, so we
|
||||
* subtract `1/2' first.
|
||||
* Now we know that 0 <= x <= 18446744073709549568. The upper
|
||||
* limit is one ulp less than 18446744073709551615 tested for above.
|
||||
* Dividing this by 2^32 will *not* round irrespective of any
|
||||
* rounding modes (except if the result is an IEEE denorm).
|
||||
* Furthermore, the quotient will fit into a 32-bit integer.
|
||||
*/
|
||||
toppart = (x - ONE_HALF) / ONE;
|
||||
/*
|
||||
* Now build a u_quad_t out of the top part. The difference
|
||||
* between x and this is the bottom part (this may introduce
|
||||
* a few fuzzy bits, but what the heck). With any luck this
|
||||
* difference will be nonnegative: x should wind up in the
|
||||
* range [0..ULONG_MAX]. For paranoia, we assume [LONG_MIN..
|
||||
* 2*ULONG_MAX] instead.
|
||||
*/
|
||||
t.ul[H] = (unsigned long)toppart;
|
||||
t.ul[L] = 0;
|
||||
x -= (double)t.uq;
|
||||
if (x < 0) {
|
||||
t.ul[H]--;
|
||||
x += ULONG_MAX;
|
||||
}
|
||||
if (x > ULONG_MAX) {
|
||||
t.ul[H]++;
|
||||
x -= ULONG_MAX;
|
||||
}
|
||||
t.ul[L] = (u_long)x;
|
||||
tmp = x / ONE;
|
||||
t.ul[L] = (unsigned long) (x - tmp * ONE);
|
||||
t.ul[H] = tmp;
|
||||
return (t.uq);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue