Issue 9980: str(float) failure - Python tracker (original) (raw)

Created on 2010-09-29 03:11 by Kiriakos.Vlahos, last changed 2022-04-11 14:57 by admin. This issue is now closed.

Messages (42)

msg117574 - (view)

Author: Kiriakos Vlahos (Kiriakos.Vlahos)

Date: 2010-09-29 03:11

I am the author of PyScripter a popular python IDE (pyscripter.googlecode.com). Following a user report I found out that str(float) occasionally produces wrong results with Python 2.7 and 3.1.

eg.

str(38210.0) //wrong '3820:.0' str(37210.0) // correct '37210.0' str(36210.0) //wrong '3620:.0'

This only happens with the embedded python engine which uses the pythonxx.dll of the official distribution. It does not happen using the stand alone interpreter of the PyScripter remote engine.

The recent changes in Python 3.2a2 fix this issue. Any ideas why the embedded Python would give different results from the stand alone interpreter?

msg117579 - (view)

Author: Mark Dickinson (mark.dickinson) * (Python committer)

Date: 2010-09-29 07:16

This sounds similar to issue 9215, which was due to a compiler optimization bug. Certainly it points to something going wrong in _Py_dg_dtoa.

What platform are these results from?

Do you have minimal code that can be used to reproduce?

I'm surprised that 3.2 fixes this: the float-to-string conversion code is pretty much identical in both 3.1 and 3.2.

msg117580 - (view)

Author: Mark Dickinson (mark.dickinson) * (Python committer)

Date: 2010-09-29 07:27

I'm surprised that 3.2 fixes this: the float-to-string conversion code > is pretty much identical in both 3.1 and 3.2.

Whoops---not quite. The conversion code is pretty much identical, but 3.2 now uses a different algorithm for str (it's equal to repr now). So I'd expect that you'll see the issue in 3.2 too if you try something like

'%.12g' % 38210.0

Kiriakos, can you explain a bit more what the difference is between the 'remote engine' and the 'stand along interpreter'? Is the core Python library compiled using different compilers for these two?

Eric, are you able to reproduce this at all? I don't have access to Windows at the moment.

msg117583 - (view)

Author: Eric V. Smith (eric.smith) * (Python committer)

Date: 2010-09-29 08:56

From their web page, it looks like PyScripter only runs on Windows, so I assume these results are generated there.

I won't be able to test on Windows until tonight.

Kiriakos: Does this only happen within PyScripter, or does it also happen when you use the python.exe using the same pythonxx.dll?

msg117584 - (view)

Author: Kiriakos Vlahos (Kiriakos.Vlahos)

Date: 2010-09-29 08:58

PyScripter is a Windows only IDE. I am using the official release *** Python 2.7 (r27:82525, Jul 4 2010, 09:01:59) [MSC v.1500 32 bit (Intel)] on win32. ***

Python 3.2a2 fixes this since, according to SVN, str is now using the same code (or at least the same parameters to the _Py_dg_dtoa call) as repr.

I am afraid I do not have a minimal code to reproduce this, since the error only occurs with the python.dll embedded to PyScripter. To reproduce with PyScripter you need to

a) Download and install the latest version of PyScripter from pyscripter.googlecode.com b) Set the python engine to the internal (embedded python) using the menu (Run, Python Engine, Internal) c) Execute in the interpreter window str(38210.0) etc.

The puzzling thing is that the same Python.dll when used by python.exe and not PyScripter produces correct results. PyScripter does not mess up with built-ins in any way or set any special flags and I see no reason why results would differ.

msg117585 - (view)

Author: Kiriakos Vlahos (Kiriakos.Vlahos)

Date: 2010-09-29 09:07

Answer to Mark's question:

*** Python 3.2a2 (r32a2:84522, Sep 5 2010, 22:35:34) [MSC v.1500 32 bit (Intel)] on win32. ***

'%.12g' % 38210.0 '3820:'

So indeed the error still exists in _Py_dg_dtoa.

The internal engine uses an embedded python.dll. The remote engine uses a stand-alone pythonw.exe in a separate process and communicates with it with rpyc (http://rpyc.wikidot.com/).

msg117619 - (view)

Author: Mark Dickinson (mark.dickinson) * (Python committer)

Date: 2010-09-29 15:15

The puzzling thing is that the same Python.dll when used by python.exe and not PyScripter produces correct results.

Yes, this is indeed puzzling. Are you absolutely sure that both python.exe and PyScripter are using the exact same Python.dll file? E.g., can you check that renaming/deleting/moving the Python.dll file to somewhere else causes both python.exe and PyScripter to fail to execute?

I really can't think of anything in the environment which might affect whether this bug occurs or not.

It's difficult to proceed here without a concrete way to reproduce the error. I can (and will) add the particular bad values you found as new testcases, so that if the error is present on any of the buildbots it'll show up.

msg117620 - (view)

Author: Eric V. Smith (eric.smith) * (Python committer)

Date: 2010-09-29 15:21

It's interesting to note that '9' is ascii 57, and ':' is 58. It's like the code is incrementing the wrong digit. If it's related to that, that indeed sounds like a compiler optimization bug to me, but of course I'm just guessing. And I'm not sure that conclusion matches the rest of the known facts.

msg117622 - (view)

Author: Brian Curtin (brian.curtin) * (Python committer)

Date: 2010-09-29 15:32

I get different results than Kiriakos' last example.

PCbuild\amd64\python_d.exe Python 3.2a2+ (py3k, Sep 29 2010, 09:43:42) [MSC v.1500 64 bit (AMD64)] on win32

Type "help", "copyright", "credits" or "license" for more information.

'%.12g' % 38210.0 '38210'

msg117623 - (view)

Author: Mark Dickinson (mark.dickinson) * (Python committer)

Date: 2010-09-29 15:43

It's interesting to note that '9' is ascii 57, and ':' is 58.

Right; it's that part that convinces me that the problem is somewhere deep in _Py_dg_dtoa, in the guts of the float to string conversion, where a xxx999999... result is rounded up to xx(x+1)000000... incorrectly. And it seems at least possible that there's a compiler bug somewhere, since it's happened before. It's also possible that there's a bug in _Py_dg_dtoa; this seems fairly unlikely (but certainly not out of the question), since this bit is pretty much exactly David Gay's original code.

msg117638 - (view)

Author: Mark Dickinson (mark.dickinson) * (Python committer)

Date: 2010-09-29 18:42

Added the extra test cases (for py3k only) in r85119.

msg117646 - (view)

Author: Stefan Krah (skrah) * (Python committer)

Date: 2010-09-29 19:18

I can reproduce this using the internal (embedded python) of PyScripter (nice work BTW!).

I can't reproduce it under any other circumstances. The test case from #9215 runs fine in VS, and also this produces the correct output:

#include <Python.h>

int main(int argc, char *argv[]) { Py_Initialize(); PyRun_SimpleString("print str(38210.0)"); Py_Finalize(); return 0; }

I ran all tests with the x86 release of 2.7.

msg117655 - (view)

Author: Kiriakos Vlahos (Kiriakos.Vlahos)

Date: 2010-09-29 21:04

Does _Py_dg_dtoa depend on FPU flags that affect rounding or exceptions? I failed to mention that python is embedded in a Delphi executable. Delphi uses the following code at initialization.

procedure _FpuInit; asm FNINIT FWAIT {$IFDEF PIC} CALL GetGOT MOV EAX,[EAX].OFFSET Default8087CW FLDCW [EAX] {$ELSE} FLDCW Default8087CW {$ENDIF} end;

Default8087CW: Word = $1332;{ Default 8087 control word. FPU control register is set to this value. CAUTION: Setting this to an invalid value could cause unpredictable behavior. }

msg117656 - (view)

Author: Kiriakos Vlahos (Kiriakos.Vlahos)

Date: 2010-09-29 21:13

Let me that add that it is impossible to fully unit test for the correctness of the str(float). I only found out by accident, because one of the users bumped into such a case. I tried to find a pattern in the misbehaved cased and it was rather difficult. Here is what I got but it is not conclusive

msg117659 - (view)

Author: Kiriakos Vlahos (Kiriakos.Vlahos)

Date: 2010-09-29 21:45

OK problem solved! If I set the FPU control word to $00xx I get the correct answers. Now I think that if _Py_dg_dtoa depends on specific values for the FPU control word that is bad design and likely to lead to such problems.

msg117662 - (view)

Author: Kiriakos Vlahos (Kiriakos.Vlahos)

Date: 2010-09-29 21:56

If _Py_dg_dtoa requires a specific FPU control word to work correctly, it should save its state, set it to the desired state and restore it after finishing.

msg117665 - (view)

Author: Eric V. Smith (eric.smith) * (Python committer)

Date: 2010-09-29 22:05

I agree that in an ideal world there would not be a dependency on global flags.

There's no doubt a performance issue with doing so, although someone would have to measure that. It may well be swamped by the memory allocation, etc. that is going on at the same time and so won't matter.

Mark will no doubt know this better than I do, but I also assume that there's an issue with thread safety when changing such global state.

msg117672 - (view)

Author: Kiriakos Vlahos (Kiriakos.Vlahos)

Date: 2010-09-29 22:56

Actually with control word 0032or0032 or 0032or3F I still do not get identical results to python.exe.

PyScripter

'%.12g' % 38210.0 '38210.0009918' str(38210.0) '38210.0009918'

Python

'%.12g' % 38210.0 '38210' str(38210.0) '38210.0'

Does anybody know what is the FPU control word should be to match the results of Python?

msg117674 - (view)

Author: Kiriakos Vlahos (Kiriakos.Vlahos)

Date: 2010-09-29 23:10

Also note that different compilers initialize the FPU control word with different values. This creates a problem with embedded python that behaves differently or even produces wrong results depending on which language/compiler is used to embed it. At least this is a documentation issue. The expected value of the FPU control word should be documented.

msg117675 - (view)

Author: Kiriakos Vlahos (Kiriakos.Vlahos)

Date: 2010-09-29 23:26

I found out that x2xx(testbothx2xx (test both x2xx(testboth12xx and $02xx) gives identical results to python. Here is what it means.

The PC field (bits 9 and 8) or Precision Control determines to what precision the FPU rounds results after each arithmetic instruction in one of three ways:

00 = 24 bits (REAL4) 01 = Not used 10 = 53 bits (REAL8) <- This is required by _Py_dg_dtoa 11 = 64 bits (REAL10) (this is the initialized state)

So contrary to my expectation it is not the rounding control bits but the Precision control bits that matter.

msg117701 - (view)

Author: Mark Dickinson (mark.dickinson) * (Python committer)

Date: 2010-09-30 07:09

Delphi uses the following code at initialization.

Yep. That would explain the problem. On x86 machines, Python's string-to-float and float-to-string conversions require that the x87 FPU has precision set to 53 bits rather than 64 bits (and also that the FPU rounding mode is round-half-to-even, but this rarely gets changed).

There's a configure-time check that works out whether resetting the precision is necessary; if so, the precision is changed before each conversion and reverted again afterwards (see the _Py_SET_53BIT_PRECISION_START and _Py_SET_53BIT_PRECISION_END macros used in Python/pystrtod.c ). It looks like you may need to override these macros for PyScripter.

Note that this isn't usually a problem on Windows: the default setting on Windows is 53 bit precision; I've no idea why Delphi changes it. The main problem platform is 32-bit Linux, which uses 64-bit precision by default. (And 64-bit Linux generally uses the appropriate SSE2 instructions instead of the x87; these are always 53-bit precision.)

So in general there's an issue if the runtime FPU settings don't match the configure-time FPU settings. I'm not sure what the best mechanism for solving this is. Checking the FPU state before every conversion would be possible, I guess, but it most cases that's unnecessary.

msg117702 - (view)

Author: Mark Dickinson (mark.dickinson) * (Python committer)

Date: 2010-09-30 07:15

[Eric]

There's no doubt a performance issue with doing so, although someone would have to measure that. It may well be swamped by the memory allocation, etc. that is going on at the same time and so won't matter.

Yes, I think changing the FPU state involves a pipeline flush, with potentially serious performance impact. But as you say, that may well be insignificant compared with everything else that's going on.

Mark will no doubt know this better than I do, but I also assume that there's an issue with thread safety when changing such global state.

I don't think there's an issue here: wouldn't FPU state be thread-local?

msg117703 - (view)

Author: Mark Dickinson (mark.dickinson) * (Python committer)

Date: 2010-09-30 07:35

It looks like you may need to override these macros for PyScripter.

Stupid. Of course, this isn't an option if you're using the existing Python dll directly.

For PyScripter, can you alter your Delphi layer to drop back to the normal default 53-bit precision before calling any Python stuff? (Isn't there a SetPrecisionMode function?)

msg117714 - (view)

Author: Stefan Krah (skrah) * (Python committer)

Date: 2010-09-30 09:54

I wonder if calling _Py_SET_53BIT_PRECISION_START/_Py_SET_53BIT_PRECISION_END every time will have any measurable effect on performance. First, string conversions have a lot of overhead already. Then, for compilers that already set the correct control word, only fnstcw is called.

Attached is a quick and dirty benchmark. The correct state is set at the start of the program. The first loop does not change the FPU state, the second one uses the macros, the third one always sets/restores.

time: 0.000000 result: 1.90013e+122 time (fnstcw): 0.570000 result: 1.90013e+122 time (fnstcw/fldcw): 2.560000 result: 1.90013e+122

I would feel more comfortable if the correct FPU state is guaranteed.

msg117720 - (view)

Author: Stefan Krah (skrah) * (Python committer)

Date: 2010-09-30 11:07

I benchmarked _PyOS_ascii_strtod without the macros, with the macros and with always calling both fnstcw/fldcw. There is no real difference:

import timeit

s = "str(38210.0)" t = timeit.Timer(stmt=s)

t.timeit(number=10000000) t.timeit(number=10000000) t.timeit(number=10000000)

None

t.timeit(number=10000000) 3.7519991397857666 t.timeit(number=10000000) 3.759944200515747 t.timeit(number=10000000) 3.7730538845062256

Macros

t.timeit(number=10000000) 3.780745029449463 t.timeit(number=10000000) 3.777444839477539 t.timeit(number=10000000) 3.7622230052948

fnstcw/fldcw

t.timeit(number=10000000) 3.765655994415283 t.timeit(number=10000000) 3.7517099380493164 t.timeit(number=10000000) 3.749257802963257

msg117721 - (view)

Author: Mark Dickinson (mark.dickinson) * (Python committer)

Date: 2010-09-30 11:11

Thanks for the numbers, Stefan.

What about in the reverse direction (string to float)? I don't expect any real difference there, either, but it would be good to check.

msg117722 - (view)

Author: Mark Dickinson (mark.dickinson) * (Python committer)

Date: 2010-09-30 11:12

Whoops; that was string to float. How about float to string?

msg117728 - (view)

Author: Mark Dickinson (mark.dickinson) * (Python committer)

Date: 2010-09-30 12:04

I would feel more comfortable if the correct FPU state is guaranteed.

I agree, in principle. In practice there are some thorny issues to deal with, and things to think about:

(1) The method for getting and setting the FPU precision varies from platform to platform

(2) Most modern x86 processors have two FPUs that might be used (the SSE unit, and the x87), each with their own control words.

(3) Depending on the platform and compiler flags, a Python executable / shared library might be using the x87 instructions, the SSE2 instructions, or a mixture of both.

(4) We need to bear in mind that an executable created on a modern 32-bit Linux machine (with SSE2) might still need to run on older machines that don't have SSE2.

msg117729 - (view)

Author: Stefan Krah (skrah) * (Python committer)

Date: 2010-09-30 12:11

Mark Dickinson <report@bugs.python.org> wrote:

Whoops; that was string to float. How about float to string?

These are the results for format_float_short. The first one is quite funny:

If the control word is left as is (64-bit prec on Linux), _Py_dg_dtoa apparently requires more iterations (but still produces the correct result in this case).

import timeit

s = "str(38210.0)" t = timeit.Timer(stmt=s)

4.266580820083618

t.timeit(number=10000000) 4.3112568855285645 t.timeit(number=10000000) 4.313380002975464

3.7413151264190674

t.timeit(number=10000000) 3.7296619415283203 t.timeit(number=10000000) 3.737776041030884

3.756165027618408

t.timeit(number=10000000) 3.775428056716919 t.timeit(number=10000000) 3.775447130203247

In general, execution times for _Py_dg_dtoa vary quite a bit depending on the number that is converted:

5.097490072250366

2.417008876800537

Judging from these numbers, I think the macros could be called by default without any real effect on performance. How about setting the rounding mode as well (you suggested that in #9009)?

msg117730 - (view)

Author: Stefan Krah (skrah) * (Python committer)

Date: 2010-09-30 12:14

The tracker swallowed some parts of my mail:

In general, execution times for _Py_dg_dtoa vary quite a bit depending on the number that is converted:

s = "str(1.00000000000000005e300)" t = timeit.Timer(stmt=s) t.timeit(number=10000000) 5.097490072250366

s = "str(1.00000000000000005e384)" t = timeit.Timer(stmt=s) t.timeit(number=10000000) 2.417008876800537

msg117734 - (view)

Author: Stefan Krah (skrah) * (Python committer)

Date: 2010-09-30 14:10

On an older Celeron platform the differences are up to 7%, but again, the number that is converted has a far greater impact:

None:

s = "str(38210.0)" t = timeit.Timer(stmt=s)

t.timeit(number=1000000) 3.277189016342163 t.timeit(number=1000000) 3.293405055999756 t.timeit(number=1000000) 3.302845001220703

s = "str(1.31232223e300)" t = timeit.Timer(stmt=s)

t.timeit(number=1000000) 5.678447008132935 t.timeit(number=1000000) 5.695156097412109 t.timeit(number=1000000) 5.690100193023682

fnstcw only:

s = "str(38210.0)" t = timeit.Timer(stmt=s)

t.timeit(number=1000000) 3.3676700592041016 t.timeit(number=1000000) 3.339860200881958 t.timeit(number=1000000) 3.365180015563965

s = "str(1.31232223e300)" t = timeit.Timer(stmt=s)

t.timeit(number=1000000) 5.869584798812866 t.timeit(number=1000000) 5.8620688915252686 t.timeit(number=1000000) 5.882143020629883

fnstcw/fldcw:

s = "str(38210.0)" t = timeit.Timer(stmt=s)

t.timeit(number=1000000) 3.5034677982330322 t.timeit(number=1000000) 3.496767044067383 t.timeit(number=1000000) 3.5118331909179688

s = "str(1.31232223e300)" t = timeit.Timer(stmt=s)

t.timeit(number=1000000) 5.808370113372803 t.timeit(number=1000000) 5.80784010887146 t.timeit(number=1000000) 5.837070941925049

msg117735 - (view)

Author: Tim Peters (tim.peters) * (Python committer)

Date: 2010-09-30 14:21

About thread state, the C standard is no help. That's an OS decision. All OSes I'm aware of do save/restore FPU state across thread switches. Doesn't mean all OSes do, just that I don't know of an exception.

msg117736 - (view)

Author: Antoine Pitrou (pitrou) * (Python committer)

Date: 2010-09-30 14:37

There's a configure-time check that works out whether resetting the precision is necessary; if so, the precision is changed before each conversion and reverted again afterwards

How about doing the check in Py_Initialize() instead? Then it will work for embedders too.

msg117737 - (view)

Author: Kiriakos Vlahos (Kiriakos.Vlahos)

Date: 2010-09-30 14:40

For PyScripter, can you alter your Delphi layer to drop back to the >>normal default 53-bit precision before calling any Python stuff?

Yes sure. That is how I traced the source of the problem.

msg117739 - (view)

Author: Kiriakos Vlahos (Kiriakos.Vlahos)

Date: 2010-09-30 14:56

How about doing the check in Py_Initialize() instead? Then it will >>work for embedders too. It is not good practice for DLLs to change the FPU control word when loaded, because the host application may have set it to a specific value for a good reason. Delphi provides a SafeLoadLibrary function that saves the the control word and restores it after loading the DLL.

If _Py_dg_dtoa can be made to work correctly independently of the value of the FPU control word that should be much better. If this means setting and restoring the control word, then this sounds like a good way forward.

By the way the reason Delphi sets the precision to 64bits is that by design all floating calculations are done in 64 bit presision and then truncated back if needed. A native 10 byte floating type called Extended is also provided.

msg117741 - (view)

Author: Kiriakos Vlahos (Kiriakos.Vlahos)

Date: 2010-09-30 14:56

How about doing the check in Py_Initialize() instead? Then it will >>work for embedders too. It is not good practice for DLLs to change the FPU control word when loaded, because the host application may have set it to a specific value for a good reason. Delphi provides a SafeLoadLibrary function that saves the the control word and restores it after loading the DLL.

If _Py_dg_dtoa can be made to work correctly independently of the value of the FPU control word that should be much better. If this means setting and restoring the control word, then this sounds like a good way forward.

By the way the reason Delphi sets the precision to 64bits is that by design all floating calculations are done in 64 bit presision and then truncated back if needed. A native 10 byte floating type called Extended is also provided.

msg118738 - (view)

Author: Muhammad Alkarouri (Muhammad.Alkarouri)

Date: 2010-10-15 03:27

I cam across another issue that was triggered by the same problem. I am explaining it here though I am not sure if it is going to affect the solution one way or the other.

The issue is explained in the post http://stackoverflow.com/questions/3933851/nan-giving-an-error-depending-on-python-startup

Namely, running the command

float('nan')

on a Python (tested with version 2.6.4) embedded in a Delphi 2009 application gives a EInvalidOp Delphi exception.

The solution as given in the link is to change the FPY control word (and revert it back when done).

The issue is important because it may break unexpected Python code. In my case, it broke the command

import json

because of the line

NaN, PosInf, NegInf = float('nan'), float('inf'), float('-inf')

in json.decoder. I have no idea what else may break in the standard library.

The reason I bring this up here is because the problem with the mismatch in FPU control world expectations between Delphi and Python is not localised. Given that the behaviour of float('nan') is assumed to be guaranteed by library developers (see PEP 754), this may come up anywhere.

msg118740 - (view)

Author: Martin v. Löwis (loewis) * (Python committer)

Date: 2010-10-15 05:52

Interesting. I'd like to propose than that this is resolved as "won't fix", i.e. embedding Python into Delphi is declared as just not supported (or using floating-point operations in such an environment is not supported).

msg118760 - (view)

Author: Kiriakos Vlahos (Kiriakos.Vlahos)

Date: 2010-10-15 12:04

I would like to say that these are two separate issues. One is about the precision flag and the second about the exception masking flags of the FPU control words. Both issues affect a wider number of users than Python embedders using Delphi. For example C# uses 80 bit precision if I understand http://blogs.msdn.com/b/davidnotario/archive/2005/08/08/449092.aspx well.

Also both issues are primarily documentation issues. If Python libraries make certain assumptions about the state of the FPU control word, these assumptions should be documented and users can then accommodate them.

msg118766 - (view)

Author: Muhammad Alkarouri (malkarouri)

Date: 2010-10-15 13:07

On 15 October 2010 06:52, Martin v. Löwis <report@bugs.python.org> wrote:

Martin v. Löwis <martin@v.loewis.de> added the comment:

Interesting. I'd like to propose than that this is resolved as "won't fix", i.e. embedding Python into Delphi is declared as just not supported (or using floating-point operations in such an environment is not supported).

The problem is defining what does "such an environment" mean. It is not necessarily Delphi, as this can happen whenever the FPU control word is changed by an embedding application. Kiriakos makes a good point. The underlying issue is that Python make certain assumptions about the FPU control words, and there are probably other global assumptions lurking elsewhere. As I see it, the easiest solution is to document these assumptions as and when they are found. Then it becomes the responsibility of the hosting application to satisfy them. Delphi already has to accomodate Python C heritage, for example by defining functions used from Python with the C calling convention. This would be just one more thing to remember, and in fact can be done inside the Python4Delphi libraries once the Python behaviour is defined and documented.

Also, banning floating-point operations is not a solution in my opinion because Python libraries (standard and external) do not have such a distinction. So an unknown of unexpected libraries (like json) would break. And large parts of Python functionality wouldn't be available.

On 15 October 2010 13:04, Kiriakos Vlahos <report@bugs.python.org> wrote:

Kiriakos Vlahos <pyscripter@gmail.com> added the comment:

I would like to say that these are two separate issues.  One is about the precision flag and the second about the exception masking flags of the FPU control words. Both issues affect a wider number of users than Python embedders using Delphi. For example C# uses 80 bit precision if I understand http://blogs.msdn.com/b/davidnotario/archive/2005/08/08/449092.aspx well.

Technically they are, yes. But they are both affected by any solution that would incorporate preserving or documenting the FPU control word for embedding applications. May be I should have opened a new issue.

msg118773 - (view)

Author: Mark Dickinson (mark.dickinson) * (Python committer)

Date: 2010-10-15 13:50

For example C# uses 80 bit precision

No, I don't think that's true. It uses the x87, with its 64-bit internal precision, but I'm fairly sure that (as is almost always true in a Windows environment, except if you're using Delphi, apparently) the FPU precision is still set to 53-bit precision.

if I understand http://blogs.msdn.com/b/davidnotario/archive/2005/08/08/449092.aspx well.

And that article explicitly confirms the use of 53-bit precision:

"Precision is set by default in VC++ and CLR apps to ‘double precision’, which means that if you are operating with operands of type float, results of operations done with floats actually exist in the x87 stack as if there were of type double. In fact, it’s even weirder than that. They will have the mantissa of a double, but the range (exponent) of an extended double (80 bit)."

i.e., it's using the x87 FPU with precision set to 53 bits.

msg146249 - (view)

Author: Mark Dickinson (mark.dickinson) * (Python committer)

Date: 2011-10-23 19:11

Closing as "won't fix", for reasons given above.

History

Date

User

Action

Args

2022-04-11 14:57:07

admin

set

github: 54189

2011-10-23 19:11:13

mark.dickinson

set

status: open -> closed
resolution: wont fix
messages: +

2010-10-15 13:50:56

mark.dickinson

set

messages: +

2010-10-15 13:07:54

malkarouri

set

nosy: + malkarouri
messages: +

2010-10-15 12:04:44

Kiriakos.Vlahos

set

messages: +

2010-10-15 05:52:04

loewis

set

messages: +

2010-10-15 03:27:04

Muhammad.Alkarouri

set

nosy: + Muhammad.Alkarouri
messages: +

2010-10-05 07:23:25

mark.dickinson

set

assignee: mark.dickinson

2010-09-30 14:56:50

Kiriakos.Vlahos

set

messages: +

2010-09-30 14:56:30

Kiriakos.Vlahos

set

messages: +

2010-09-30 14:40:26

Kiriakos.Vlahos

set

messages: +

2010-09-30 14:37:45

pitrou

set

nosy: + pitrou
messages: +

2010-09-30 14:21:00

tim.peters

set

nosy: + tim.peters
messages: +

2010-09-30 14:10:38

skrah

set

messages: +

2010-09-30 12:14:27

skrah

set

messages: +

2010-09-30 12:11:35

skrah

set

messages: +

2010-09-30 12:04:13

mark.dickinson

set

messages: +

2010-09-30 11:12:17

mark.dickinson

set

messages: +

2010-09-30 11:11:51

mark.dickinson

set

messages: +

2010-09-30 11:07:05

skrah

set

messages: +

2010-09-30 09:54:26

skrah

set

files: + fpuspeed.c

messages: +

2010-09-30 07:35:04

mark.dickinson

set

messages: +

2010-09-30 07:15:58

mark.dickinson

set

messages: +

2010-09-30 07:09:25

mark.dickinson

set

messages: +

2010-09-29 23:26:39

Kiriakos.Vlahos

set

messages: +

2010-09-29 23:10:22

Kiriakos.Vlahos

set

messages: +

2010-09-29 22:56:33

Kiriakos.Vlahos

set

messages: +

2010-09-29 22:05:30

eric.smith

set

messages: +

2010-09-29 21:56:48

Kiriakos.Vlahos

set

messages: +

2010-09-29 21:45:42

Kiriakos.Vlahos

set

messages: +

2010-09-29 21:13:04

Kiriakos.Vlahos

set

messages: +

2010-09-29 21:04:13

Kiriakos.Vlahos

set

messages: +
versions: - Python 3.2

2010-09-29 20:20:51

loewis

set

nosy: + loewis

2010-09-29 19🔞29

skrah

set

nosy: + skrah
messages: +

2010-09-29 18:42:34

mark.dickinson

set

messages: +

2010-09-29 15:43:35

mark.dickinson

set

messages: +

2010-09-29 15:32:10

brian.curtin

set

nosy: + brian.curtin
messages: +

2010-09-29 15:21:56

eric.smith

set

messages: +

2010-09-29 15:17:04

mark.dickinson

set

versions: + Python 3.2

2010-09-29 15:15:03

mark.dickinson

set

messages: +

2010-09-29 09:07:54

Kiriakos.Vlahos

set

messages: +

2010-09-29 08:58:01

Kiriakos.Vlahos

set

messages: +

2010-09-29 08:56:24

eric.smith

set

messages: +

2010-09-29 07:27:24

mark.dickinson

set

messages: +

2010-09-29 07:16:57

mark.dickinson

set

messages: +

2010-09-29 07:04:45

r.david.murray

set

nosy: + mark.dickinson, eric.smith

2010-09-29 07:02:30

sjmachin

set

nosy: + sjmachin

2010-09-29 03:11:29

Kiriakos.Vlahos

create