The included patch adds a couple of scanf floating-point tests to expose a problem with the algorithm. It seems that it doesn't handle negative exponents very well, resulting in single-precision values being off-by-one in the last bit of significant compared to those obtained with the GNU C library or natively on Windows XP.
All five tests pass on my Windows XP SP2 system (using a self-compiled msvcrt_crosstest.exe tool). Test 3 and 4 fail with the current source in Git. I will send another patch to this list with a potential fix.
(I am not sending these to wine-patches because I'm not sure I should. "wine-devel" sounds about right.)
--- dlls/msvcrt/tests/scanf.c | 40 ++++++++++++++++++++++++++++++++++++---- 1 files changed, 36 insertions(+), 4 deletions(-)
diff --git a/dlls/msvcrt/tests/scanf.c b/dlls/msvcrt/tests/scanf.c index 65bea46..d5da3f6 100644 --- a/dlls/msvcrt/tests/scanf.c +++ b/dlls/msvcrt/tests/scanf.c @@ -28,7 +28,7 @@ static void test_sscanf( void ) char format[20]; int result, ret; char c; - float res1= -82.6267f, res2= 27.76f, res11, res12; + float orig, res; static const char pname[]=" St. Petersburg, Florida\n"; int hour=21,min=59,sec=20; int number,number_so_far; @@ -64,9 +64,41 @@ static void test_sscanf( void ) ok( result == 12, "sscanf reads %x instead of %x\n", result, 12 );
/* Check float */ - ret = sprintf(buffer,"%f %f",res1, res2); - ret = sscanf(buffer,"%f%f",&res11, &res12); - ok( (res11 == res1) && (res12 == res2), "Error reading floats\n"); + + orig = -82.6267f; + ret = sprintf(buffer, "%f", orig); + ret = sscanf(buffer, "%f", &res); + ok(ret == 1, "Expected 1 float, got %d\n", ret); + ok(res == orig, "Wrote %e (0x%x), but read %e (0x%x)\n", + orig, *(unsigned int *) &orig, res, *(unsigned int *) &res); + + orig = 27.76f; + ret = sprintf(buffer, "%f", orig); + ret = sscanf(buffer, "%f", &res); + ok(ret == 1, "Expected 1 float, got %d\n", ret); + ok(res == orig, "Wrote %e (0x%x), but read %e (0x%x)\n", + orig, *(unsigned int *) &orig, res, *(unsigned int *) &res); + + orig = -6.61589e-2f; + ret = sprintf(buffer, "%e", orig); + ret = sscanf(buffer, "%e", &res); + ok(ret == 1, "Expected 1 float, got %d\n", ret); + ok(res == orig, "Wrote %e (0x%x), but read %e (0x%x)\n", + orig, *(unsigned int *) &orig, res, *(unsigned int *) &res); + + orig = 1.72567e-7f; + ret = sprintf(buffer, "%e", orig); + ret = sscanf(buffer, "%e", &res); + ok(ret == 1, "Expected 1 float, got %d\n", ret); + ok(res == orig, "Wrote %e (0x%x), but read %e (0x%x)\n", + orig, *(unsigned int *) &orig, res, *(unsigned int *) &res); + + orig = 15.483e+3f; + ret = sprintf(buffer, "%e", orig); + ret = sscanf(buffer, "%e", &res); + ok(ret == 1, "Expected 1 float, got %d\n", ret); + ok(res == orig, "Wrote %e (0x%x), but read %e (0x%x)\n", + orig, *(unsigned int *) &orig, res, *(unsigned int *) &res);
/* check strings */ ret = sprintf(buffer," %s", pname);
On Fri, 15 Feb 2008, =?utf-8?q?J=C4=81nis=20R=C5=ABcis?= wrote: [...]
All five tests pass on my Windows XP SP2 system (using a self-compiled msvcrt_crosstest.exe tool). Test 3 and 4 fail with the current source in Git. I will send another patch to this list with a potential fix.
(I am not sending these to wine-patches because I'm not sure I should. "wine-devel" sounds about right.)
If you want the patch to be applied you do have to poast it to wine-patches. Before you post it there, though, you'll need to add todo_wine statements so they don't fail on Wine. You can then remove the todo_wines in the patch that fixes Wine's msvcrt.