Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support formatting floats in hexadecimal (and binary?) notation #113804

Open
skirpichev opened this issue Jan 8, 2024 · 1 comment
Open

Support formatting floats in hexadecimal (and binary?) notation #113804

skirpichev opened this issue Jan 8, 2024 · 1 comment
Labels
type-feature A feature request or enhancement

Comments

@skirpichev
Copy link
Contributor

skirpichev commented Jan 8, 2024

Feature or enhancement

Proposal:

Currently there is the float.hex() method to get a representation of a floating-point number as a hexadecimal string.

We can also (instead?) add same formating option for the str.format(), f-strings and old-style ('%' operator) string formatting. The C printf() has a dedicated type fields for this: 'a' and 'A'. While it's possible to add such formatting types for the str.format() as well, for the old-style string formatting these letters will conflict (see this) with the ascii() conversion type. Lets instead reuse 'x' and 'X' type fields for this, currently supported only for integers.

This proposal introduce an incompatibility with C-style printf(), but some other languages also have such one. Notable example is the Go's fmt package.

New interface for formatting of floats will be more flexible and compact than the former float.hex():

>>> f'{-0.1:#x}'
'-0x1.999999999999ap-4'
>>> (-0.1).hex()
'-0x1.999999999999ap-4'
>>> f'{3.14159:+#X}'
'+0X1.921F9F01B866EP+1'
>>> f'{3.14159:.3x}'
'1.922p+1'

We may also consider to support printing floats as binary strings. Either in the base-2 scientific notation, or like the Go's strconv.FormatFloat.

Has this already been discussed elsewhere?

I have already discussed this feature proposal on Discourse

Links to previous discussion of this feature:

https://discuss.python.org/t/41848

Linked PRs

@skirpichev skirpichev added the type-feature A feature request or enhancement label Jan 8, 2024
skirpichev added a commit to skirpichev/cpython that referenced this issue Jan 8, 2024
_Py_dg_dtoa_hex() is based on float.hex() with additional support for
the precision setting and some format flags.

Examples:
```pycon
>>> f'{-0.1:x}'
'-0x1.999999999999ap-4'
>>> (-0.1).hex()
'-0x1.999999999999ap-4'
>>> f'{3.14159:+X}'
'+0X1.921F9F01B866EP+1'
>>> f'{3.14159:.3x}'
'0x1.922p+1'
```
skirpichev added a commit to skirpichev/cpython that referenced this issue Jan 8, 2024
_Py_dg_dtoa_hex() is based on float.hex() with additional support for
the precision setting and some format flags.

Examples:
```pycon
>>> f'{-0.1:x}'
'-0x1.999999999999ap-4'
>>> (-0.1).hex()
'-0x1.999999999999ap-4'
>>> f'{3.14159:+X}'
'+0X1.921F9F01B866EP+1'
>>> f'{3.14159:.3x}'
'0x1.922p+1'
```
skirpichev added a commit to skirpichev/cpython that referenced this issue Jan 12, 2024
_Py_dg_dtoa_hex() helper is based on float.hex() with additional support
for the precision setting and some format flags.  Note (c.f. ``'a'``
format type of the C stdlib), that ``'#'`` option is used to control the
prefix (off by default).

Trailing zeros (and the dot) in fractional part are excluded.

Examples:
```pycon
>>> f'{-0.1:#x}'
'-0x1.999999999999ap-4'
>>> (-0.1).hex()
'-0x1.999999999999ap-4'
>>> f'{3.14159:+#X}'
'+0X1.921F9F01B866EP+1'
>>> f'{3.14159:.3x}'
'1.922p+1'
```

Minor changes:
* added Py_hexdigits_upper constant
* tests for RaisingNumber are moved (to test also bytes)
@skirpichev
Copy link
Contributor Author

PR is ready for review: #113805

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type-feature A feature request or enhancement
Projects
None yet
Development

No branches or pull requests

1 participant