modelica / ModelicaSpecification

Specification of the Modelica Language
https://specification.modelica.org
Creative Commons Attribution Share Alike 4.0 International
102 stars 41 forks source link

Is 13 a floating point number literal? #2122

Closed modelica-trac-importer closed 4 years ago

modelica-trac-importer commented 6 years ago

Reported by henrikt on 28 Nov 2016 14:09 UTC Section 2.4.1, Floating Point Numbers, says that A floating point number is expressed as a decimal number in the form of a sequence of decimal digits optionally followed by a decimal point, optionally followed by an exponent. It doesn't say that at least one of the decimal point and the exponent needs to be present. Still, the examples at the end of the section does not include "13" as one of the possible ways of expressing the floating point number 13.0.

Isn't the intention to say that at least one of the decimal point and the exponent needs to be present, so that "13" is unambiguously an Integer literal (that can be implicitly cast to Real)?


Migrated-From: https://trac.modelica.org/Modelica/ticket/2122

modelica-trac-importer commented 6 years ago

Modified by beutlich on 28 Nov 2016 18:10 UTC

modelica-trac-importer commented 6 years ago

Comment by hansolsson on 29 Nov 2016 12:56 UTC Replying to [ticket:2122 henrikt]:

Isn't the intention to say that at least one of the decimal point and the exponent needs to be present, so that "13" is unambiguously an Integer literal (that can be implicitly cast to Real)?

I realized there's more missing.

I believe we could be closer to C and state: "A floating point number (Real literal) is expressed as a decimal number in the form of a sequence of decimal digits, a fractional part (a decimal point and optionally another set of decimal digits), followed by an exponent; either the fractional part or the exponent (not both) may be missing."

Note that I changed it so that "2." is allowed.

modelica-trac-importer commented 6 years ago

Comment by henrikt on 29 Nov 2016 13:33 UTC Right. I just prefer a wording that specifies what needs to be present, rather than one that specifies what may be missing (I don't like the phrase may be missing in a normative context like this).

modelica-trac-importer commented 6 years ago

Comment by hansolsson on 29 Nov 2016 13:41 UTC Replying to [comment:3 henrikt]:

Right. I just prefer a wording that specifies what needs to be present, rather than one that specifies what may be missing (I don't like the phrase may be missing in a normative context like this).

Something like: "A floating point number (Real literal) is expressed as a decimal number in the form of one or more decimal digits, optionally a fractional part, optionally followed by an exponent; it must have a fractional part or exponent (or both). The fractional part is a decimal comma, followed by zero or more decimal digits. The exponent is the letter e or E followed by an optional sign(+ or -), and one or more decimal digits."

modelica-trac-importer commented 6 years ago

Comment by stefanv on 29 Nov 2016 14:19 UTC Alternatively, we could use a BNF-like notation, or railroad diagrams, to be completely unambiguous about it.

By the way, is .13 a valid floating point number? It is in C, Maple, and MapleSim. Do other tools accept it?

Regarding the term, "decimal comma", I think "decimal point" might be a better choice because (a) English-only speakers might be confused by the use of "comma" here, and (b) Modelica floating point constants always require using the "." (point) character, never the "," (comma) character.

modelica-trac-importer commented 6 years ago

Comment by hansolsson on 29 Nov 2016 14:25 UTC Replying to [comment:5 stefanv]:

Alternatively, we could use a BNF-like notation, or railroad diagrams, to be completely unambiguous about it.

The grammar has:

UNSIGNED_NUMBER = UNSIGNED_INTEGER [ "." [ UNSIGNED_INTEGER ] ]
    [ ( "e" | "E" ) [ "+" | "-" ] UNSIGNED_INTEGER ]

so, floating point numbers are the ones that aren't integers:

UNSIGNED_NUMBER = 
   UNSIGNED_INTEGER  "." [ UNSIGNED_INTEGER ] |
   UNSIGNED_INTEGER  ( "e" | "E" ) [ "+" | "-" ] UNSIGNED_INTEGER |
   UNSIGNED_INTEGER  "." [ UNSIGNED_INTEGER ] ( "e" | "E" ) [ "+" | "-" ] UNSIGNED_INTEGER 

By the way, is .13 a valid floating point number?

No.

It is in C, Maple, and MapleSim. Do other tools accept it?

Dymola and 3D Experience Platform accept and correct it.

Regarding the term, "decimal comma", I think "decimal point" might be a better choice because (a) English-only speakers might be confused by the use of "comma" here, and (b) Modelica floating point constants always require using the "." (point) character, never the "," (comma) character.

True, it was a mistake that I changed from "decimal point" to "decimal comma".

modelica-trac-importer commented 6 years ago

Comment by stefanv on 29 Nov 2016 14:53 UTC Replying to [comment:6 hansolsson]:

Dymola and 3D Experience Platform accept it ...

Perhaps we should allow it, since I suspect other tools accept it too, and it's common in most programming languages (Pascal/Modula-2/Oberon being the exception, which always require at least one digit on each side of the decimal).

and correct it.

They modify your source file?!?

modelica-trac-importer commented 6 years ago

Comment by dag on 29 Nov 2016 15:17 UTC The great divider between European and American programming languages (the UK is internally divided). Modelica decided to go for the syntax both groups accept as correct, I have not heard that Americans think a leading 0. is wrong - only redundant.

Certain commercial tools accept both to support their communities. This is more of an issue for input of parameter data, especially if you copy from some other tool. In that case silently fixing the syntax is not controversial.

Dag

Replying to [comment:7 stefanv]:

Replying to [comment:6 hansolsson]:

Dymola and 3D Experience Platform accept it ...

Perhaps we should allow it, since I suspect other tools accept it too, and it's common in most programming languages (Pascal/Modula-2/Oberon being the exception, which always require at least one digit on each side of the decimal).

and correct it.

They modify your source file?!?

modelica-trac-importer commented 6 years ago

Comment by stefanv on 29 Nov 2016 15:41 UTC If some tools accept .13 and some do not, then we have a problem, since a model that works in one tool may then not be accepted by another tool. Quietly fixing the syntax is not an option for all tools, as it assumes that the tool is being used to edit the Modelica code, and that the file is writable when the tool decides it's going to change it.

If we're going to accept and correct .13, then we may as well just allow .13.

modelica-trac-importer commented 6 years ago

Comment by dag on 29 Nov 2016 16:08 UTC Dymola will quietly apply the "fix", but there is no need to write it out until the user does a save. Dymola will only write syntactically correct Modelica numbers. So you can claim that Dymola has a parser bug (lenient syntax checking), but at least we support Modelica portability when saving.

I think there are good readability reasons for writing numbers as 0.13 instead .13; if we can reduce the risk of silly mistakes let's continue to do so. Also note that in many European countries, .13 is really regarded as incorrect and we should not promote "incorrect" models being disseminated from the NA continent.

modelica-trac-importer commented 6 years ago

Comment by stefanv on 29 Nov 2016 16:31 UTC I guess that depends on whether you want to promote Modelica usage on the NA continent. We do.

As I said above, having a tool "fix" the code is not an option for all tools. It should either accept the code as written, or not. And for that, we have to agree on what is acceptable.

modelica-trac-importer commented 6 years ago

Comment by jmattsson on 30 Nov 2016 09:47 UTC I find it strange that we allow 13., but not .13, when the first one introduces an actual ambiguity (1.+2 could be interpreted as either 1. + 2 or 1 .+ 2) but the latter one doesn't lead to any such problems.

JModelica.org allows .13, but I don't think that is by design.

modelica-trac-importer commented 6 years ago

Comment by dag on 30 Nov 2016 11:57 UTC The discussion at the time focused on the readability of numbers, and because 13 and 13. are the same value there were no concerns. The .* et al. operators are a later addition.

Replying to [comment:12 jmattsson]:

I find it strange that we allow 13., but not .13, when the first one introduces an actual ambiguity (1.+2 could be interpreted as either 1. + 2 or 1 .+ 2) but the latter one doesn't lead to any such problems.

modelica-trac-importer commented 6 years ago

Comment by jmattsson on 30 Nov 2016 12:42 UTC Replying to [comment:13 dag]:

The discussion at the time focused on the readability of numbers, and because 13 and 13. are the same value there were no concerns. The .* et al. operators are a later addition.

I'd say that 13 and 13. are not the same value. For one thing, Integer x = 13.; is a type error, whereas Integer x = 13; is not.

As for the actual topic of the ticket, considering the prevalence of the .13 syntax in common programming languages, I'd say that it seems more reasonable to allow it.

modelica-trac-importer commented 6 years ago

Comment by hansolsson on 5 Dec 2016 11:35 UTC One thing I realized was missing from this discussion is whether 1000000000000000000000000 is a Real literal; currently that is recommended but not required.

3.3 Evaluation Order ... If a numeric operation overflows the result is undefined. For literals it is recommended to automatically convert the number to another type with greater precision. --

modelica-trac-importer commented 6 years ago

Comment by anonymous on 13 Dec 2016 10:23 UTC I find that recommendation very strange. I mean, should the type of the literal expression really depend on the current implementation's Integer range?

modelica-trac-importer commented 6 years ago

Comment by sjoelund.se on 13 Dec 2016 10:40 UTC Replying to [comment:16 anonymous]:

I find that recommendation very strange. I mean, should the type of the literal expression really depend on the current implementation's Integer range?

That's how it's done in C (and quite many other languages without specified storage space of variables).

modelica-trac-importer commented 6 years ago

Comment by anonymous on 13 Dec 2016 10:57 UTC I guess this is what you are thinking of? http://en.cppreference.com/w/c/language/integer_constant That only describes integer literals. Can you give a corresponding reference where the integer/floating point boundary is crossed?

(Sorry for not being logged in. I am henrikt.)

modelica-trac-importer commented 6 years ago

Comment by sjoelund.se on 13 Dec 2016 11:08 UTC Oh, C doesn't support converting from integer to floating point in the parser (gives an error for long integer constant literals). But it considers literals to be of a type that depends on how large the integer literal is (which is comment:16).

modelica-trac-importer commented 6 years ago

Comment by hansolsson on 13 Dec 2016 11:29 UTC A Real literal is expressed as a decimal number in the form of one or more decimal digits, optionally a fractional part, optionally followed by an exponent; it must have a fractional part or exponent (or both). The fractional part is a decimal point, followed by zero or more decimal digits. The exponent is the letter e or E followed by an optional sign(+ or -), and one or more decimal digits.

Grammar change:

UNSIGNED_NUMBER = UNSIGNED_INTEGER [ "." [ UNSIGNED_INTEGER ] ]
    [ ( "e" | "E" ) [ "+" | "-" ] UNSIGNED_INTEGER ]

->

UNSIGNED_NUMBER = UNSIGNED_INTEGER | REAL_UNSIGNED_NUMBER

REAL_UNSIGNED_NUMBER = UNSIGNED_INTEGER  "." [ UNSIGNED_INTEGER ] |
   UNSIGNED_INTEGER  ( "e" | "E" ) [ "+" | "-" ] UNSIGNED_INTEGER |
   UNSIGNED_INTEGER  "." [ UNSIGNED_INTEGER ] ( "e" | "E" ) [ "+" | "-" ]UNSIGNED_INTEGER 

Quick poll for above (delaying decision on .13 and 100000000000000): Favor: 6 Against: 1 (due to grammar - promised paper) Rest abstain

modelica-trac-importer commented 6 years ago

Comment by hansolsson on 13 Dec 2016 13:20 UTC Is .13 an error, or Real literal? atan2(.31,.13) Jesper: Allowing 13. is a bigger problem, due to problem with element-wise operators.

After grammar add (among notes): Whitespace and comments can be used between separate lexical units and/or symbols, and also separates them. Each lexical unit will consume the maximum number of characters from the input stream.

Poll about allowing .13 as Real literal: Favor: 9 Against: 1 Rest abstain.

Also .1e2 But not .e1 - since that is also a global reference to package e1.

REAL_UNSIGNED_NUMBER = ... | "." UNSIGNED_INTEGER [( "e" | "E" ) [ "+" | "-" ] UNSIGNED_INTEGER]

Is 100000000000000000000 is an error, unspecified, or Real literal (assuming it cannot be represented as integer literal)?

Specification: If a numeric operation overflows the result is undefined. For literals it is recommended to automatically convert the number to another type with greater precision. -- Poll: Current behavior (undefined and recommended): 2 Error if an integer literal overflows: 8 Make it mandatory to convert to a Real if overflow actual range: 6 It is an error if exceeds minimum recommended range for integers: 3

Not clear. Note that large numbers are normally generated by tools. -- Stefan V: should be "range" - not "precision". in 2.4.2 it says: The minimal recommended number range is from −2147483648 to +2147483647 for a two’s-complement 32-bit integer implementation -> The minimal recommended number range is from −2147483648 to +2147483647 corresponding to a two’s-complement 32-bit integer implementation