Hexadecimal literals with floating point exponents

185 views
Skip to first unread message

mikkelfj

unread,
May 8, 2015, 11:07:59 AM5/8/15
to juli...@googlegroups.com
I cannot really get my head around Julias hexadecimal notation for floats:

I am implementing a lexer that understand numbers from various languages. Thus, I am not particularly concerned about practial use cases as much as what the syntax and semantics really are.

Why is the exponent required to be decimal (0x1.1p1 is valid, but 0x1.1p0a is not, nor is 0x1.1p0x0a)
Why is p used instead of e for exponentation (0x1.1p0 is valid, but 0x1.1e0 is not)?
Why is p required if fractions are used (0x1.1 is invalid, but 0x1.1p0 is not), given that it is not required for base-10 floats (1.1 is valid, and so is 1.1e0)?

I am aware of the juxtapositional notation of 1k meaning 1 * k, and 0x0 takes precence as hex literal over 0 * x, but I don't see that would confuse any of the above, other than p is now also reserved for literals and for weird use cases, perhaps in some galois like field, someone would want to use hex or binary for polynomials?

Isn't it a bit confusing that 0X0 means 0 * X0 when 0x0 means 0, even if lack of ambiguity in literals is a nice concept.

mikkelfj

unread,
May 8, 2015, 12:01:52 PM5/8/15
to juli...@googlegroups.com
Well, I just had a doh moment:

Obviously the hex exponent cannot use 'e' as delimiter since it is a hex digit, so p means power.

Also observered the 0xa and 0xA are valid, but 0Xa (as mentioned) isn't, and also 0x1.1P2 and 0x1.1p2 are both valid. So the lower case requirement for 0x seems even more inconsistent.

The lack of fractions in binary and octal base is also slightly confusing, while not a big deal.

The other questions remain.

Simon Byrne

unread,
May 8, 2015, 4:09:02 PM5/8/15
to juli...@googlegroups.com
The hex float literal is not Julia invention: it is in both the C99 standard, and the IEE754-2008 floating point standard. It is specified in both of those, or Rick Regan gives a fairly thorough run down here:

Although not standard, I for one would be in favour of a bit float literal as well, in fact, I proposed one here:

Of course, we could define an oct float literal as well, but other than file permissions, are octal bases used for anything?

-simon

Patrick O'Leary

unread,
May 8, 2015, 4:34:37 PM5/8/15
to juli...@googlegroups.com
On Friday, May 8, 2015 at 3:09:02 PM UTC-5, Simon Byrne wrote:
Of course, we could define an oct float literal as well, but other than file permissions, are octal bases used for anything?

Confusing unsuspecting programmers who aren't used to seeing octal literals? :D

Patrick

Simon Byrne

unread,
May 9, 2015, 6:47:21 AM5/9/15
to juli...@googlegroups.com
To follow up, I don't know why we require the "0x" to be lowercase (the standard doesn't), but I would guess that it is to match the integer case (0x1 is valid, but 0X1 is not).

Mikkel Fahnøe Jørgensen

unread,
May 9, 2015, 8:10:24 AM5/9/15
to juli...@googlegroups.com
OK, thanks for explaining.
I suspected hexadecimal floating point is more for exact machine representation than for human consumption.

The exponent is neither hexadecimal nor decimal. It is a decimal power of 2, which makes perfect sense.

The standard requires the p or P and makes the hexadecimal point ‘.’ optional.

As Simon says, 0X is part of the standard notation, even if Julia does not support it.

For reference HFP is supposedly also present in C11 (which otherwise discards some C99 features), but only for printing in current C++ 14 drafts. Also, as is mentioned in the Julia issue raised by Simon, printf in C with %a does not yield full precision by default.

Python supports these floats, but make the exponent optional, contrary to the standard, and allows for uppercase 0X, even if not mentioning it:

[sign] ['0x'] integer ['.' fraction] ['p' exponent]


Not sure how authoritative the following page is, but it has a nice syntax diagram:

Kevin Squire

unread,
May 9, 2015, 10:19:24 AM5/9/15
to juli...@googlegroups.com
Hi Mikkel,

If you haven't yet, you could file an issue (or pull request) for adding "0X" as a valid prefix for hex literals (and/or for any other inconsistencies).

Cheers,
   Kevin 

Mikkel Fahnøe Jørgensen

unread,
May 9, 2015, 11:09:12 AM5/9/15
to juli...@googlegroups.com

Simon Byrne

unread,
May 9, 2015, 1:14:37 PM5/9/15
to juli...@googlegroups.com

On Saturday, 9 May 2015 13:10:24 UTC+1, mikkelfj wrote:
OK, thanks for explaining.
I suspected hexadecimal floating point is more for exact machine representation than for human consumption.

Yes, I think that is precisely the point  
 
As Simon says, 0X is part of the standard notation, even if Julia does not support it.

Well, it does via parse(Float64,...) (v0.4) or parsefloat(...) (v0.3), just not at the parser level (which is consistent with integers).
 
Also, as is mentioned in the Julia issue raised by Simon, printf in C with %a does not yield full precision by default.

As per the C spec, %a should give "the precision is sufficient for an exact representation of the value", which basically means get rid of any trailing zeros, i.e.:


julia> @printf "%a" 1.0
0x1p+0

julia> @printf "%a" 1.1
0x1.199999999999ap+0

Python supports these floats, but make the exponent optional, contrary to the standard, and allows for uppercase 0X, even if not mentioning it:

[sign] ['0x'] integer ['.' fraction] ['p' exponent]

This is not at the parser level, only via the float.fromhex function,  the same functionality as provided by the Julia parse/parsefloat functions.
 
Reply all
Reply to author
Forward
0 new messages