float.hex()
The lossless text form. Decimal output has to round somewhere; hex output shows the stored bits exactly, which makes round trips and bug reports reliable.
Common call
x.hex()
Returns
str like '0x1.8000000000000p+0' — mantissa, then a binary exponent
Replaces
repr(x) when you need an exact, portable round trip
Watch out
the p exponent is a power of TWO, not of sixteen
float.hex()
→ str
Demo
Live evaluation
Try:
Inputs
nfloata number, e.g. 255.0 or 0.5
Output
float(1).hex()
'0x1.0000000000000p+0'
The output reads as mantissa, then p, then a power of two. 0x1.8p+0 means 1.5 x 2**0, because the hex digits after the point are sixteenths: 8/16 is a half. 255.0 becomes 0x1.fe00000000000p+7, or 1.9921875 x 2**7. Zero is the special case, printing as 0x0.0p+0 with no leading one. Watch the 0.1 case — the long string of digits is exactly why 0.1 is not really a tenth.
Common patterns
Round-trip a float exactly
fromhex reverses hex with no rounding, on any platform.
text = x.hex() assert float.fromhex(text) == x
Report a float precisely in a bug report
Removes all doubt about which value is actually stored.
log.error("got %s (%s)", value, value.hex())
Compare two floats bit for bit
Equal hex means identical bits; the printed decimals can match while the values differ.
same_bits = a.hex() == b.hex()
Examples
1. One
(1.0).hex()
Returns
'0x1.0000000000000p+0'2. A half
(0.5).hex()
Returns
'0x1.0000000000000p-1'3. 255
(255.0).hex()
Returns
'0x1.fe00000000000p+7'4. Zero
(0.0).hex()
Returns
'0x0.0p+0'5. Negative
(-0.5).hex()
Returns
'-0x1.0000000000000p-1'6. Infinity
float('inf').hex()
Returns
'inf'Pitfalls
1. The p exponent counts powers of two
The digits are hexadecimal but the exponent is binary. p+7 means times 2**7, not 16**7 — misreading it puts you off by a factor of millions.
Read as base 16
(255.0).hex() # 0x1.fe...p+7
NOT 1.99 * 16**7
Read as base 2
1.9921875 * 2 ** 7
255.0
2. It is not the built-in hex()
hex() takes an integer and rejects floats outright. float.hex is a method on the value, and the two produce completely different text.
Builtin rejects floats
hex(255.0)
TypeError: 'float' object cannot be interpreted as an integer
Call the method
(255.0).hex()
'0x1.fe00000000000p+7'
3. Not meant to be human-readable
It is an exact interchange format, not a display format. Showing it to users trades a familiar number for one almost nobody can read at a glance.
Unreadable output
print(f"Total: {total.hex()}")
Total: 0x1.91eb851eb851fp+6
Format for humans
print(f"Total: {total:.2f}")
Total: 100.48
When to use
Use it
- Exact round trips through text, with fromhex
- Bug reports and test fixtures where the precise value matters
- Comparing floats bit for bit
- Storing floats in a text format without rounding
Reach for something else
- Anything a person will read → f-strings or format
- Integers → the built-in hex()
- Exact decimal arithmetic → decimal.Decimal
Notes
Complexity
O(1) — formats a fixed number of digits
Return
A new str; always 13 mantissa digits for normal values
CPython impl
Objects/floatobject.c :: float_hex
Memory
Allocates the result string
Thread-safe
Yes — floats are immutable
FAQ
The mantissa is 1 plus 8/16, so 1.5, and p+0 multiplies by 2**0. Hex digits after the point are sixteenths, then two-hundred-fifty-sixths, and so on — the same idea as decimal places, in base 16.
float.fromhex("0x1.8p+0") # 1.5
History
2.6
float.hex and float.fromhex added together for exact round trips.