msvcrt: Fix rounding of numbers smaller than minimal subnormal.
Signed-off-by: Piotr Caban <piotr@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
4fe481db95
commit
29288c0bc0
|
@ -413,25 +413,21 @@ int fpnum_double(struct fpnum *fp, double *d)
|
||||||
fp->m >>= 1;
|
fp->m >>= 1;
|
||||||
fp->exp++;
|
fp->exp++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* handle subnormal that falls into regular range due to rounding */
|
|
||||||
fp->exp += (1 << (EXP_BITS-1)) - 1;
|
fp->exp += (1 << (EXP_BITS-1)) - 1;
|
||||||
if (!fp->exp && (fp->mod == FP_ROUND_UP || (fp->mod == FP_ROUND_EVEN && fp->m & 1)))
|
|
||||||
{
|
|
||||||
if (fp->m + 1 >= (ULONGLONG)1 << MANT_BITS)
|
|
||||||
{
|
|
||||||
fp->m++;
|
|
||||||
fp->m >>= 1;
|
|
||||||
fp->exp++;
|
|
||||||
fp->mod = FP_ROUND_DOWN;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* handle subnormals */
|
/* handle subnormals */
|
||||||
if (fp->exp <= 0)
|
if (fp->exp <= 0)
|
||||||
|
{
|
||||||
|
if (fp->m & 1 && fp->mod == FP_ROUND_ZERO) fp->mod = FP_ROUND_EVEN;
|
||||||
|
else if (fp->m & 1) fp->mod = FP_ROUND_UP;
|
||||||
|
else if (fp->mod != FP_ROUND_ZERO) fp->mod = FP_ROUND_DOWN;
|
||||||
fp->m >>= 1;
|
fp->m >>= 1;
|
||||||
|
}
|
||||||
while(fp->m && fp->exp<0)
|
while(fp->m && fp->exp<0)
|
||||||
{
|
{
|
||||||
|
if (fp->m & 1 && fp->mod == FP_ROUND_ZERO) fp->mod = FP_ROUND_EVEN;
|
||||||
|
else if (fp->m & 1) fp->mod = FP_ROUND_UP;
|
||||||
|
else if (fp->mod != FP_ROUND_ZERO) fp->mod = FP_ROUND_DOWN;
|
||||||
fp->m >>= 1;
|
fp->m >>= 1;
|
||||||
fp->exp++;
|
fp->exp++;
|
||||||
}
|
}
|
||||||
|
@ -440,7 +436,13 @@ int fpnum_double(struct fpnum *fp, double *d)
|
||||||
if (fp->mod == FP_ROUND_UP || (fp->mod == FP_ROUND_EVEN && fp->m & 1))
|
if (fp->mod == FP_ROUND_UP || (fp->mod == FP_ROUND_EVEN && fp->m & 1))
|
||||||
{
|
{
|
||||||
fp->m++;
|
fp->m++;
|
||||||
if (fp->m >= (ULONGLONG)1 << MANT_BITS)
|
|
||||||
|
/* handle subnormal that falls into regular range due to rounding */
|
||||||
|
if (fp->m == (ULONGLONG)1 << (MANT_BITS - 1))
|
||||||
|
{
|
||||||
|
fp->exp++;
|
||||||
|
}
|
||||||
|
else if (fp->m >= (ULONGLONG)1 << MANT_BITS)
|
||||||
{
|
{
|
||||||
fp->exp++;
|
fp->exp++;
|
||||||
fp->m >>= 1;
|
fp->m >>= 1;
|
||||||
|
|
|
@ -148,6 +148,8 @@ static void test_strtod(void)
|
||||||
test_strtod_str("1.7976931348623158e+308", 1.7976931348623158e+308, 23);
|
test_strtod_str("1.7976931348623158e+308", 1.7976931348623158e+308, 23);
|
||||||
test_strtod_str("2.2250738585072014e-308", 2.2250738585072014e-308, 23);
|
test_strtod_str("2.2250738585072014e-308", 2.2250738585072014e-308, 23);
|
||||||
test_strtod_str("4.9406564584124654e-324", 4.9406564584124654e-324, 23);
|
test_strtod_str("4.9406564584124654e-324", 4.9406564584124654e-324, 23);
|
||||||
|
test_strtod_str("2.48e-324", 4.9406564584124654e-324, 9);
|
||||||
|
test_strtod_str_errno("2.47e-324", 0, 9, ERANGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test__memicmp(void)
|
static void test__memicmp(void)
|
||||||
|
|
Loading…
Reference in New Issue