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.

classification
Title: Python/dtoa.c requires 53 bit hardware rounding unavalable on x64
Type: behavior Stage: resolved
Components: Interpreter Core Versions: Python 3.11, Python 3.10, Python 3.9, Python 3.8, Python 3.7, Python 3.6
process
Status: closed Resolution: not a bug
Dependencies: Superseder:
Assigned To: Nosy List: arhadthedev, mark.dickinson
Priority: normal Keywords:

Created on 2021-11-03 11:13 by arhadthedev, last changed 2022-04-11 14:59 by admin. This issue is now closed.

Messages (3)
msg405603 - (view) Author: Oleg Iarygin (arhadthedev) * Date: 2021-11-03 11:13
File configure.ac:4617 states the following:

> # The short float repr introduced in Python 3.1 requires the
> # correctly-rounded string <-> double conversion functions from
> # Python/dtoa.c, which in turn require that the FPU uses 53-bit
> # rounding; this is a problem on x86, where the x87 FPU has a default
> # rounding precision of 64 bits.  For gcc/x86, we can fix this by
> # using inline assembler to get and set the x87 FPU control word.

However, x64 programs use xmm0-7 SIMD registers instead of a FPU stack, so the requirement of hardware 56 bit rounding gets violated. _Py_SET_53BIT_PRECISION_* is unable to do anything here because SSE neither respects the FPU control word, nor provides its own.

Considering that SSE is supported since Pentium III (1999), we can safely enforce its usage for x32 code via compiler flags as well, getting consistent behavior across builds. However, it requires revision of the requirement.

We need to decide what to do with dtoa.c that supposedly relies on the requirement (providing short floats? It looks like _Py_dg_dtoa just stringifies as many digits as specified in ndigits argument. I didn't collect enough courage on this stage to analyze 484 uncommented lines (2370-2854) of bit manipulation over two-letter variables to find and fix the dependency). By the way, the only place that uses _Py_dg_dtoa is Objects/floatobject.c:949 doing it with an argument mode=3.

I can resolve the issue, but I need some educated opinion on this 13-years old stuff (see git blame for configure.ac:4617) to not break things.

Note: I initially added Mark Dickinson into the notifications as a person who created and maintained Python/dtoa.c until 2013.
msg405621 - (view) Author: Mark Dickinson (mark.dickinson) * (Python committer) Date: 2021-11-03 14:34
I'm not sure I understand the problem that you're reporting - what issues are you seeing in practice?

x64 should be fine here. In normal circumstances, the compiled version of dtoa.c will be using SSE2 instructions and will already be doing floating-point arithmetic at 53-bit precision (not 56-bit), following IEEE 754. It's mainly the ancient x86/x87 hardware that's problematic. This code has been working well on many different x64 platforms for around a decade now.

Can you describe the issue that you're seeing in more detail?
msg405623 - (view) Author: Oleg Iarygin (arhadthedev) * Date: 2021-11-03 15:15
When I first saw "default rounding precision of 64 bits", I've thought it's about "64 bit precision", aka binary64, aka double. So I suggested that the code expects some hardly known Intel FPU-specific binary56 instead. Now, after a second paragraph of your reply I see that in reality it's about significand precision (so rounding precision of 64 bits is for binary80, and 53 is for binary64).

> at 53-bit precision (not 56-bit)

You're right. That was a typo.

Thank you for clarification, I'm closing the issue as not-a-bug.
History
Date User Action Args
2022-04-11 14:59:52adminsetgithub: 89865
2021-11-03 15:15:05arhadthedevsetstatus: open -> closed
resolution: not a bug
messages: + msg405623

stage: resolved
2021-11-03 14:34:20mark.dickinsonsetmessages: + msg405621
2021-11-03 11:13:46arhadthedevcreate