Float with exponent - is "1e1" a number?

Hi There,

I’m creating a parser for numbers and I came across this:

11> string:to_float("1e1").
{error,no_float}
12> string:to_integer("1e1").
{1,"e1"}
13> 1.0e1.
10.0
14> 1e1.
* 1:2: syntax error before: e1

It appears that the string 1e1 isn’t an integer nor a float in Erlang :frowning:

The same in Python

# Python 2.7.16 (default, Aug 29 2022, 10:34:32)
>>> 1e1
10.0
>>> type(1e1)
<type 'float'>
>>> float("1e1")
10.0

The same in NodeJS:

// Welcome to Node.js v22.9.0.
// Type ".help" for more information.
> 1e1
10
> parseFloat("1e1")
10
> typeof 1e1
'number'

I’m not particularly concerned about 1e1 but the generalisation:

15> 12e21.
* 1:3: syntax error before: e21
15> 21e-12.
* 1:3: syntax error before: e
15> -12e-12.
* 1:4: syntax error before: e

all of which are perfectly legal encodings of integer values.

I was wondering - since I’m creating a parser anyway - what library in Erlang handles those values correctly? I could, in my parser, change the first value from ‘1’ to ‘1.0’ and then use string:to_float(..) but that would be changing what is actually an integer to a float … 1e1 is ten not 10.0 after all Correction: 1e1 is a float - so I can safely convert to 1.0

Cheers!

The issue is that Erlang’s syntax for numbers (both integers and floats) differs from many other languages. This means that to implement a tool processing or generating some other language you cannot in general rely on Erlang’s primitives to do the low-level number conversions – you need to implement those yourself.

For floats you also need to think about internal representation since Erlang rejects non-finite floats (i.e. NaNs and infinities).

1 Like

What does “correctly” mean? Programming languages in general disagree about whether 1e1 is a number, and if so, what kind of number it is. Should 1.0d1 also count as a number? It is in Fortran, Lisp, and ANSI Smalltalk, so why not? Do you think 7#23.4#e-9 should be accepted as a number? The Erlang 28 manual says it is. So the chances are that Erlang accepts forms you would like to reject, as well as the other way around.

Write your own parser, transform to a sign and a string of digits, paste .0eXXX on the end, and give that to Erlang to convert to a number.

What about alternative digits, group separators, etc?

1 Like

Thankfully we all seem to agree on what gravity does so there is a certain standardisation on where roads go. I assumed the humankind would have the ability to create the same standardisation when it comes to the representation of floating point numbers but even that, we - humankind - doesn’t seem to be able to agree upon.

Surprising to think that left and right are the same everywhere - I mean that my left thumb points to my right hand while my right thumb points to my left hand :wink:

Personally I don’t much care, as long as I have a place to sleep and roof over my head, I don’t really care whether thats a floating point number or not. However if I’m coding stuff and need to codify a representation of a floating point number, then yes, I would say that can be a decimal number if everyone else also agrees.

And yes, you are quite right, each to their own and if Erlang recognises 1.0e1 as a decimal and 1e1 not - who cares. It just surprising for me because I assumed that 1e1 isn’t much different to 1.0e1!

I did and it was super simple thanks to Erlangs yecc and leex integration. Also that parser does nothing else than transforming Node-RED float representation to Erlangs representation. Hence my need to know what is a float in Erlang …

groon :frowning: - I forgot those in my parser, thanks for headsup! But a quick check of Node-RED validations rules and no, there are no groups in NR float values, so no need for me to parse them - yeah!

I can now move on and implement MQTT protocol using my floating point parser! O Fortuna!

Human beings do not agree on what the digit shapes are.
Human beings have disagreed on whether floating-point numbers should be base 2, 8, 10, or 16,
and still disagree about whether they should be 2 or 10. (The programming languages REXX and
Misty insist on decimal floats, and the current version of the IEEE standard was carefully
crafted to allow COBOL to use decimal floats.)
Human beings disagree about whether the exponent symbol should be a subscript 10, an @ sign,
E or D (Fortran), E D or Q (Smalltalk), e or p (C), e s d f or l (Common Lisp), &c.
For that matter, even English-speaking human beings do not agree whether the decimal point
is to be written on the line or half-way up. (1.2 vs 1·2)
Human beings disagree about whether spaces or underscores or some other separator should
be allowed between digits in programming languages, and in data, whether commas or some
other characters should be allowed.

Any parsing of numbers has to be with reference to some specified convention.

Just as long as you allow 1_234·56 as a floating-point number I’ll be happy.

1 Like

Well that’s not supported because Node-RED doesn’t support it however I might just add the following to my tokenizer:

{1_234·56} : {token, {make_nzok_happy, TokenLine}}.

:wink: