sharkdp / insect

High precision scientific calculator with support for physical units
https://numbat.dev/
MIT License
3.17k stars 126 forks source link

Strange behavior with exponents and decimal powers #341

Closed triallax closed 1 year ago

triallax commented 2 years ago

Here's a demonstration:

>>> 2e1.5

  20 × 0.5

   = 10

(Run on current master)

I believe 2e1.5 here gets parsed as 2e1 .5, equivalent to 2e1 * 0.5. On 5.7.0 however, an error is printed (albeit a somewhat unclear one):

>>> 2e1.5

  Parse error at position 4: Expected end of input

This is most likely a result of my PR https://github.com/sharkdp/insect/pull/296.

Thoughts on the best solution here?

sharkdp commented 2 years ago

Oh, good catch!

Thoughts on the best solution here?

In my opinion, it should clearly be parsed as 2e1.5 = 2 × 10^(1.5).

triallax commented 2 years ago

In my opinion, it should clearly be parsed as 2e1.5 = 2 × 10^(1.5).

decimal.js doesn't support decimal exponents though (I just tested).

sharkdp commented 2 years ago

Ah okay. Should we parse it as BinOp Mul (Scalar 2.0) (BinOp Pow (Scalar 10.0) (Scalar 1.5)) and compute the result ourselves? That would probably be a bit of a challenge for the parser.

I'm also completely fine with disallowing it entirely.

triallax commented 2 years ago

Unless somebody specifically asks for it, let's just disallow it.

gunvirranu commented 1 year ago

Only integer exponents seems fine, but I think implicit multiplication between constants and variables w/o a delimiter is confusing imo. Perhaps you disagree, but I think a space should always be required, or at most with one constant followed by one variable. For example, all of the following parse but I'd argue they should be disallowed due to the potential for confusion.

triallax commented 1 year ago

I don't agree that a space should always be required. For instance, I would definitely hate to have to type 3 x instead of 3x; it just looks plain wrong. Also, whoever types anything like those examples into Insect deserves whatever happens to them. :P

or at most with one constant followed by one variable.

I'm not sure what that means exactly, could you elaborate?

gunvirranu commented 1 year ago

whoever types anything like those examples into Insect deserves whatever happens to them

hah fair, but given that no one should ever use anything like that except by mistake, wouldn't that be all the more reason to disallow it explicitly?

As you said, however, I do see the value in something like 3x. What I was attempting to suggest is that in general, a space is required between (so no .2.2 or x.2) with one key exception: a Scalar followed by a Variable w/o a space. This would eliminate all but the first of my above examples, while still allowing that desired behaviour. Not sure if that'd mess with parsing for other stuff, but just a thought.

It would also eliminate any confusion with the original issue above, cause 2e1.5 would throw an error as opposed to the currently confusing tokenization.

triallax commented 1 year ago

hah fair, but given that no one should ever use anything like that except by mistake, wouldn't that be all the more reason to disallow it explicitly?

Fair enough.

As you said, however, I do see the value in something like 3x. What I was attempting to suggest is that in general, a space is required between (so no .2.2 or x.2) with one key exception: a Scalar followed by a Variable w/o a space. This would eliminate all but the first of my above examples, while still allowing that desired behaviour. Not sure if that'd mess with parsing for other stuff, but just a thought.

It would also eliminate any confusion with the original issue above, cause 2e1.5 would throw an error as opposed to the currently confusing tokenization.

That makes sense to me, it's a solution worth exploring. We need to make sure though that the parse error messages are clear (not like the vague "Expected end of input" shown in the issue).

sharkdp commented 1 year ago

This is now all properly handled in Numbat, e.g.: https://numbat.dev/?q=2e1.5 (parse error)