Opened 10 years ago

Closed 10 years ago

#691 closed defect (fixed)

number/string-conversion tests fail on Windows (mingw-msys)

Reported by: felix winkelmann Owned by: sjamaan
Priority: major Milestone:
Component: core libraries Version: 4.7.x
Keywords: number-string conversion Cc:
Estimated difficulty:

Description

The tests fail in the following places:

-> Fractions
-----------------------------------------------------
OK                  ("1/2" (/ 1 2) "0.5" ".5" "500.0e-3")
SERIALIZATION ERROR ("10/2" 5. "5.0") => "5."
OK                  ("-1/2" (- (/ 1 2)) "-0.5" "-.5" "-500.0e-3")
OK                  ("1/-2" #f)
OK                  ("1.0/2" #f)
OK                  ("1/2.0" #f)
OK                  ("1/2e2" #f)
OK                  ("1/2e2" #f)
OK                  ("1#/2" 5. 7.5 "5.0" "5." "7.5")
SERIALIZATION ERROR ("1/2#" 5.e-002 "0.05" ".05" "50.0e-3") => "5.e-002"
OK                  ("1#/#" #f)
OK                  ("1/" #f)
OK                  ("1/+" #f)
OK                  ("+/1" #f)
OK                  ("/1" #f)
OK                  ("/" #f)

Attachments (1)

windows-floating-point-workaround.patch (503 bytes) - added by sjamaan 10 years ago.
Patch to instruct Windows not to add extra leading zeroes to the exponent when printing floating-point numbers

Download all attachments as: .zip

Change History (14)

comment:1 Changed 10 years ago by sjamaan

Strictly speaking, "5.e-002" is correct, but it looks like a bug so I don't just want to blindly add it to the test as valid syntax. Do you have any idea why it doesn't just print "5.e-2"?

I've fixed the "5." which was just something I've overlooked. (directly in master since it's a trivial bugfix. Changeset b159af007d01e8801144267924c37f8852448bea)

comment:2 Changed 10 years ago by Jim Ursetto

It has to be down to the libc print functions. E.g. in %e mode, sprintf will print 2 digits in the exponent on UNIX, and 3 digits on Windows (maybe only mingw?).

Indeed on UNIX at the REPL you will get 5e-06 for .000005, not 5e-6 and not 5.e-6 either. On Windows you get 5.e-006. Furthermore, on UNIX you get 5.0 for 5.0, whereas on MinGW 5.0 prints as "5." (five point).

%e itself will print 5.000000e-06 on UNIX and 5.000000e-006 on Windows. Apparently %g will trim the trailing zeros when possible, *however*, %g will also avoid printing the exponent when it is small enough (for example, it'll print .05 on windows). So, I'm not sure how it outputs 5.e-002 at all on Windows.

I'm just speculating without even looking at the chicken printer, or the mingw source. Idly speculating, it is splitting up the integer and fractional parts and printing them separately, and the output is subject to the vagaries of the system libraries.

comment:3 Changed 10 years ago by sjamaan

Found this in the most unlikely place you'd expect it, the Wikipedia page for printf()

The exponent always contains at least two digits; if the value is zero, the exponent is 00. In Windows, the exponent contains three digits by default, e.g. 1.5e002, but this can be altered by Microsoft-specific _set_output_format function.

I guess we can include a call to this weird _set_output_format thing. I don't have a Windows box to test on, but can someone try the attached patch?

Changed 10 years ago by sjamaan

Patch to instruct Windows not to add extra leading zeroes to the exponent when printing floating-point numbers

comment:4 in reply to:  3 Changed 10 years ago by felix winkelmann

Owner: changed from sjamaan to felix winkelmann
Status: newassigned

Replying to sjamaan:

I guess we can include a call to this weird _set_output_format thing. I don't have a Windows box to test on, but can someone try the attached patch?

I can test this patch in the next few days. Thanks for figuring this out.

comment:5 Changed 10 years ago by felix winkelmann

Unfortunately _set_output_format seems not to be available under mingw, or at least my version of it.

comment:6 Changed 10 years ago by sjamaan

Which version is that? According to http://sourceforge.net/project/shownotes.php?release_id=24832 mingw 3.15 should include this function, "for users of MSVCR80.DLL", whatever that means... (this changelog is from 2008)

comment:7 Changed 10 years ago by sjamaan

I found some info about mingw's support for these functions. They say msvcr80.dll comes from Visual Studio 2005 or later. If you're using something older it doesn't work. I guess that means Windows XP doesn't include it?

Apparently adding "PRINTF_EXPONENT_DIGITS=2" to the environment also works. Maybe we can just put a setenv() call to the initialization function instead (hopefully that's picked up anytime and not just at the start of the program....).

comment:8 Changed 10 years ago by sjamaan

Eh, make that PRINTF_EXPONENT_DIGITS=0

Stupid copy/paste mistake...

comment:9 in reply to:  7 ; Changed 10 years ago by felix winkelmann

Replying to sjamaan:

I found some info about mingw's support for these functions. They say msvcr80.dll comes from Visual Studio 2005 or later. If you're using something older it doesn't work. I guess that means Windows XP doesn't include it?

Right, MSVCRT60/70 would not support it.

Apparently adding "PRINTF_EXPONENT_DIGITS=2" to the environment also works. Maybe we can just put a setenv() call to the initialization function instead (hopefully that's picked up anytime and not just at the start of the program....).

Ugh. That's ugly. Can't we just accept that Windows is a piece-of-shit operating system and simply skip these tests on that platform?

comment:10 in reply to:  9 Changed 10 years ago by sjamaan

Replying to felix:

Ugh. That's ugly. Can't we just accept that Windows is a piece-of-shit operating system and simply skip these tests on that platform?

It's just one failing test now, right? Then we can just add the way Windows serializes it to the strings. We shouldn't be skipping tests, if at all possible.

comment:11 Changed 10 years ago by felix winkelmann

Owner: changed from felix winkelmann to sjamaan

comment:12 Changed 10 years ago by felix winkelmann

Milestone: 4.8.0

comment:13 Changed 10 years ago by sjamaan

Resolution: fixed
Status: assignedclosed

OK, this was added. Closing ticket.

Note: See TracTickets for help on using tickets.