Issue7281
This issue tracker has been migrated to GitHub,
and is currently read-only.
For more information,
see the GitHub FAQs in the Python's Developer Guide.
Created on 2009-11-07 20:41 by skrah, last changed 2022-04-11 14:56 by admin. This issue is now closed.
Messages (5) | |||
---|---|---|---|
msg95027 - (view) | Author: Stefan Krah (skrah) * | Date: 2009-11-07 20:41 | |
Sorry to report so many obscure corner cases. With the combination Opensolaris/suncc/Python3.x copysign() gives reversed results when the second argument is a NaN. The bug is in the C99 copysign() function (OpenSolaris/suncc), but Python2.6 seems to have a workaround: Python 3.2a0 (py3k:76144, Nov 7 2009, 18:50:00) [C] on sunos5 Type "help", "copyright", "credits" or "license" for more information. >>> from math import * >>> copysign(1.0, float("nan")) -1.0 >>> copysign(1.0, float("-nan")) 1.0 Python 2.6.2 (r262:71600, Nov 7 2009, 19:29:52) [C] on sunos5 Type "help", "copyright", "credits" or "license" for more information. >>> from math import copysign >>> copysign(1.0, float("nan")) 1.0 >>> copysign(1.0, float("-nan")) -1.0 >>> |
|||
msg95033 - (view) | Author: Mark Dickinson (mark.dickinson) * | Date: 2009-11-08 00:30 | |
You may have let yourself in for something here. :-) Can you tell me what: >>> import sys >>> print sys.float_repr_style gives for your Opensolaris/suncc/Python3.x combination? If it prints 'legacy', then I'd dearly like some help with making it read 'short' instead. That would then make treatment of nans on that combination consistent with other platforms. All I really need to know is how to set the x87 (I'm assuming you're on 32-bit x86 here) FPU control word using suncc. Oh, and a willing victim to test changes. Look for HAVE_PY_SET_53BIT_PRECISION in Include/pyport.h for details. Having said that, I don't really see this difference with nans as an actual bug. Is it possible that float("nan") is simply giving a nan with its sign bit set here, and that float("-nan") is giving a nan with no sign bit set? That would actually be quite unsurprising, since according to Intel's manuals, the 'default' NaN value returned by invalid operations has its sign bit set. It would also be (I think) quite legal: sign bits of NaNs don't make a lot of sense anyway, and I don't think Python should specify anything about the sign bit (or indeed the payload) of the NaN coming from float('nan'). In other words, I think it's not unreasonable to regard the sign of copysign(x, y) as undefined whenever y is a nan. (I'm fairly sure that MPFR takes this attitude, for example.) |
|||
msg95041 - (view) | Author: Stefan Krah (skrah) * | Date: 2009-11-08 13:49 | |
I hope this won't be getting too complex. :) Firstly, I agree that this is perhaps not a bug at all. I reported it because I seemed possible that Python2.x had a deliberate workaround for this issue which somehow got lost in 3.x. Secondly, I didn't mention that I'm running OpenSolaris on KVM since I can't get it to install on physical hardware. However, I don't think KVM plays a role here since gcc produces 'normal' results. So, the problem combination is: Ubuntu64bit -> KVM -> OpenSolaris32bit/suncc/Py3k On the C level, here's an example: #include <stdio.h> #include <math.h> int main(void) { double x = NAN; printf("%f %f\n", x, copysign(1.0, x)); return 0; } This gives -NaN, -1.000000 with suncc and NaN, 1.000000 with gcc. Back to Python: sys.float_repr_style is 'legacy'. It looks like the C99 fenv functions are pretty much supported, but I don't know since when. I found man pages from 2003 for fenv and from 2006 for the fe*() functions. This for example works: #include <stdio.h> #include <stdio.h> #include <fenv.h> #include <assert.h> int main(void) { #pragma STDC FENV_ACCESS ON int save_round; int setround_ok; save_round = fegetround(); setround_ok = fesetround(FE_DOWNWARD); assert(setround_ok == 0); fesetround(save_round); } I could test changes that you make (preferably in p3k head, so I could just pull them). But as I said: If the 'proper' behavior in 2.x was not a deliberate workaround, there's really no need to change anything. |
|||
msg95066 - (view) | Author: Mark Dickinson (mark.dickinson) * | Date: 2009-11-09 10:49 | |
Yes, I don't think Python 2.6 had a deliberate workaround. I suspect that it's just that one version of Python happened to use something like 0.0/0.0 to generate NaN, while another used some equivalent of strtod("nan", ...). I also remember noticing at some point that even on a single machine/OS, the sign bit of 0.0/0.0 depends on which version of gcc and which optimization flags are present. So I think we're in agreement that there's no need to change anything here; I'll close this issue. But: I really *would* like to get the short float repr working with suncc! Issue #5792 is already open for this, so discussion should move there. (This is about much more than consistent nan signs: implementing short float repr gives a whole bunch of benefits: correctly rounded float <-> string conversions (including all float formatting operations), a correctly rounded 'round' function, a prettier float repr, ...). |
|||
msg95067 - (view) | Author: Mark Dickinson (mark.dickinson) * | Date: 2009-11-09 11:31 | |
Just to confirm the above: In 2.6, PyFloat_FromString in Objects/floatobject.c ends up using the system strtod to parse "nan" and "-nan" (except that if the system strtod fails to recognise "nan" for some reason then it returns the result of 0.0 * Infinity instead, and in that case disregards the sign). In 2.7 and 3.x, it ends up calling _Py_parse_inf_or_nan in Python/pystrtod.c, and this returns 0.0 * Infinity for "nan" and -(0.0 * Infinity) for "-nan". And depending on compiler flags, 0.0 * Infinity ends up being either +nan (this usually seems to happen when optimization is on, so that the compiler itself evaluates 0.0 * Infinity), or -nan (which happens when there's no optimization and the FPU ends up doing the 0.0 * Infinity multiplication at runtime.) This should explain the results you're seeing. |
History | |||
---|---|---|---|
Date | User | Action | Args |
2022-04-11 14:56:54 | admin | set | github: 51530 |
2009-11-09 11:31:37 | mark.dickinson | set | messages: + msg95067 |
2009-11-09 10:49:29 | mark.dickinson | set | status: open -> closed resolution: not a bug messages: + msg95066 |
2009-11-08 13:49:12 | skrah | set | messages: + msg95041 |
2009-11-08 00:30:02 | mark.dickinson | set | messages: + msg95033 |
2009-11-07 20:41:38 | skrah | create |