classification
Title: test_float fails on Windows
Type: behavior Stage: resolved
Components: Tests, Windows Versions: Python 2.7
process
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: eric.smith Nosy List: abbeyj, eric.smith, mark.dickinson, tim.peters
Priority: normal Keywords:

Created on 2009-06-05 05:46 by abbeyj, last changed 2009-06-09 12:41 by eric.smith. This issue is now closed.

Messages (13)
msg88922 - (view) Author: James Abbatiello (abbeyj) Date: 2009-06-05 05:45
test_float fails on Windows with:
======================================================================
FAIL: test_format_testfile (test.test_float.IEEEFormatTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "C:\Projects\python-trunk\lib\test\test_float.py", line 319, in
test_format_testfile
    self.assertEqual(fmt % float(arg), rhs)
AssertionError: '3' != '2'

----------------------------------------------------------------------


The problematic line from formatfloat_testcases.txt is:
%.0f 2.5 -> 2


On some systems *printf() uses round-to-even.  But the Windows CRT uses
round-half-away-from-zero.  Consider the following C code:
	printf("%+.1f -> %+.0f\n", -2.5, -2.5);
	printf("%+.1f -> %+.0f\n", -1.5, -1.5);
	printf("%+.1f -> %+.0f\n", +1.5, +1.5);
	printf("%+.1f -> %+.0f\n", +2.5, +2.5);

On Linux this will produce:
-2.5 -> -2
-1.5 -> -2
+1.5 -> +2
+2.5 -> +2

And on Windows:
-2.5 -> -3
-1.5 -> -2
+1.5 -> +2
+2.5 -> +3
msg88927 - (view) Author: Eric V. Smith (eric.smith) * (Python committer) Date: 2009-06-05 08:54
I can duplicate this with Visual C++ 9.0 Express Edition on XP.
msg88930 - (view) Author: Mark Dickinson (mark.dickinson) * (Python committer) Date: 2009-06-05 10:43
Thanks for the report.  It sounds as though I might have backported
some tests from py3k to trunk that shouldn't have been backported.

abbeyj or eric, do you know whether py3k also has this failure on your 
machine?  I'm hoping not:  py3k doesn't use the CRT *printf functions for 
float formatting, so the test should pass there.
msg88931 - (view) Author: Eric V. Smith (eric.smith) * (Python committer) Date: 2009-06-05 10:50
Yes, this test passes on py3k on my Windows box. That would be a
nightmare if it didn't!

I agree that this is a test problem, not a code problem. I suggest we
just remove the offending line from formatfloat_testcases.txt in trunk.
I can do this and verify it works on Windows before checking in, if
you'd like.
msg88933 - (view) Author: Mark Dickinson (mark.dickinson) * (Python committer) Date: 2009-06-05 10:57
[Eric]
> I can do this and verify it works on Windows before checking in, if
> you'd like.

That would be great---yes, please!  My main computer died yesterday, 
taking my Windows access and my python svn access with it. :-(
msg88937 - (view) Author: Eric V. Smith (eric.smith) * (Python committer) Date: 2009-06-05 11:34
I had to remove a bunch of tests. Some were of the form
"<even-number>5", rounded to before the 5. Some were comparing a large
number of digits.

Then there's these:
%#.0g 0 -> 0.         Got '0.0'
%#.1g 0 -> 0.         Got '0.0'
%#.2g 0 -> 0.0        Got '0.00'
%#.3g 0 -> 0.00       Got '0.000'
%#.4g 0 -> 0.000      Got '0.0000'

I'm going to remove these, too, since they're all based on underlying
printf differences. But they seem like a bigger problem than the other
cases.
msg88940 - (view) Author: Eric V. Smith (eric.smith) * (Python committer) Date: 2009-06-05 12:35
Checked in to trunk in r73240.
msg88942 - (view) Author: Mark Dickinson (mark.dickinson) * (Python committer) Date: 2009-06-05 13:43
Thanks, Eric.  All those changes look good to me.

Out of interest, what does '%#.0f' % 1.5 produce on
Python 2.7/Windows?  I'd expect to get '2.' both for
round-half-to-even and round-half-away-from-zero.
Does Windows round this down to '1.' instead?

I'm surprised by the %#.ng results for 0;  this looks
like questionable behaviour (producing n+1 digits when
only n significant digits were requested).  Is the MS
implementation of printf directly responsible for this,
or is the CPython code somehow adding the extra 0?
If this is just the way that Windows behaves for formatting
of zeros, then I suppose we could add code to work around
this, but it's not clear that it's really worth it.

I suspect that we're in for some complaints when
Windows users discover that Python 3.1 string formatting
does round-half-to-even rather than the round-half-up
they're used to in Python 2.x.
msg88943 - (view) Author: Tim Peters (tim.peters) * (Python committer) Date: 2009-06-05 13:58
> Out of interest, what does '%#.0f' % 1.5 produce on
> Python 2.7/Windows?

Microsoft's float->string routines have always done "add a half and
chop" rounding.  So, yes, 1.5 rounds to 2 there.

> ...
> I suspect that we're in for some complaints when
> Windows users discover that Python 3.1 string
> formatting does round-half-to-even rather than
> the round-half-up they're used to in Python 2.x.

Historically, overall we've had more gripes from non-Windows users
complaining that, e.g., 2.5 does /not/ round up to 3 -- you can't win
here, so don't worry about it.  X-platform consistency is incompatible
with platform-specific behavior, and most users will agree consistency
is overwhelmingly more important.  Of course that won't deter them from
complaining ;-)
msg88944 - (view) Author: Eric V. Smith (eric.smith) * (Python committer) Date: 2009-06-05 14:03
Mark Dickinson wrote:
> Out of interest, what does '%#.0f' % 1.5 produce on
> Python 2.7/Windows?  I'd expect to get '2.' both for
> round-half-to-even and round-half-away-from-zero.
> Does Windows round this down to '1.' instead?

Windows in trunk gives '2.'.

> I'm surprised by the %#.ng results for 0;  this looks
> like questionable behaviour (producing n+1 digits when
> only n significant digits were requested).  Is the MS
> implementation of printf directly responsible for this,
> or is the CPython code somehow adding the extra 0?
> If this is just the way that Windows behaves for formatting
> of zeros, then I suppose we could add code to work around
> this, but it's not clear that it's really worth it.

This is from a C program on Windows, using printf:
%#.0g: 0.0
%#.1g: 0.0
%#.2g: 0.00
%#.3g: 0.000

Same program on Linux:
%#.0g: 0.
%#.1g: 0.
%#.2g: 0.0
%#.3g: 0.00

In 2.6 on Windows:
 >>> '%#.1g' % 0.0
'0.0'
 >>> '%#.2g' % 0.0
'0.00'

In 2.6 on Linux:
 >>> '%#.1g' % 0.0
'0.'
 >>> '%#.2g' % 0.0
'0.0'

So this isn't a problem we caused with the short repr work, it's 
pre-existing. I don't think it's worth working around, but that's me. 
%-formatting should just die.

> I suspect that we're in for some complaints when
> Windows users discover that Python 3.1 string formatting
> does round-half-to-even rather than the round-half-up
> they're used to in Python 2.x.

But at least in 3.1 it will now be consistent cross-platform. Can't have 
it both ways!
msg88971 - (view) Author: Mark Dickinson (mark.dickinson) * (Python committer) Date: 2009-06-05 20:10
[Mark]
> Out of interest, what does '%#.0f' % 1.5 produce on
> Python 2.7/Windows?  I'd expect to get '2.' both for
> round-half-to-even and round-half-away-from-zero.
> Does Windows round this down to '1.' instead?

[Eric]
> Windows in trunk gives '2.'.

Thanks.  I was mainly wondering why you'd commented out the
line "%#.0f 1.5 -> 2." in the formatfloat_testcases.txt
file.

[Eric, about zero formatting on Windows]
> So this isn't a problem we caused with the short repr work, it's 
> pre-existing. I don't think it's worth working around, but that's me.

I agree it doesn't seem worth working around.  Let's wait until
somebody complains. :-)
msg88980 - (view) Author: Eric V. Smith (eric.smith) * (Python committer) Date: 2009-06-05 22:44
> [Mark]
>> Out of interest, what does '%#.0f' % 1.5 produce on
>> Python 2.7/Windows?  I'd expect to get '2.' both for
>> round-half-to-even and round-half-away-from-zero.
>> Does Windows round this down to '1.' instead?
> 
> [Eric]
>> Windows in trunk gives '2.'.
> 
[Mark]
> Thanks.  I was mainly wondering why you'd commented out the
> line "%#.0f 1.5 -> 2." in the formatfloat_testcases.txt
> file.

Over-zealous commenting out on my part. I'm away from my Windows box,
but I'll correct this next week and check it back in with that line
re-enabled.

Thanks for catching that.
msg89145 - (view) Author: Eric V. Smith (eric.smith) * (Python committer) Date: 2009-06-09 12:41
In r73314, I restored the one test erroneously removed ("%#.0f 1.5 -> 2.").
History
Date User Action Args
2009-06-09 12:41:32eric.smithsetstatus: open -> closed
resolution: fixed
messages: + msg89145
2009-06-05 22:44:49eric.smithsetstatus: closed -> open
resolution: fixed -> (no value)
messages: + msg88980
2009-06-05 20:10:39mark.dickinsonsetmessages: + msg88971
2009-06-05 14:03:19eric.smithsetmessages: + msg88944
2009-06-05 13:58:49tim.peterssetnosy: + tim.peters
messages: + msg88943
2009-06-05 13:43:23mark.dickinsonsetmessages: + msg88942
2009-06-05 12:35:51eric.smithsetstatus: open -> closed
type: behavior
messages: + msg88940

assignee: mark.dickinson -> eric.smith
resolution: fixed
stage: resolved
2009-06-05 11:34:06eric.smithsetassignee: eric.smith -> mark.dickinson
messages: + msg88937
2009-06-05 10:57:55mark.dickinsonsetassignee: mark.dickinson -> eric.smith
messages: + msg88933
2009-06-05 10:50:11eric.smithsetmessages: + msg88931
2009-06-05 10:43:01mark.dickinsonsetassignee: mark.dickinson
messages: + msg88930
2009-06-05 08:54:52eric.smithsetmessages: + msg88927
2009-06-05 08:42:14eric.smithsetnosy: + eric.smith
2009-06-05 08:26:24pitrousetnosy: + mark.dickinson
2009-06-05 05:46:17abbeyjcreate