Conversation
|
Thanks Davide. Realized that this branch is still based on the 2.20 (main) branch of PG, so I will probably merge this soon and then rebase. I have some other work done (@sfiedle1) and I have been working on adding some flags for "close" answers with correct and incorrect number of significant figures and giving messages. This is in another branch (https://github.com/pstaabp/pg/tree/sig-fig-updates), but I think merge these changes in first, and then start another PR off of this. I was working on some tests that you recommended with the It seems that if
I'm trying to figure out how the parsing of this is working. Is |
Because multiplication is done left to right, You need to do The only thing I can think of to help this would be to have multiplication produce a warning when |
|
PS, If you use |
|
I was thinking that it was doing the multiply of 2.0 and 3.2 first. I didn't think that then it was no longer a sigfig when multiplying by 10^2. I'll trying to add some documentation to explain how to navigate the waters with multiple operators. |
Here is an update to add the ability to enter numbers in exponential form, e.g.,
1.23x10^4. This took a bit of machinery to make it work, as one has to override most of the operators in order to be able to track when operands are simple numbers as opposed to when they are computations or had parentheses that were removed, etc. It also involves overriding several other Parser classes so that the markers can be properly maintained as the numbers move through the parse tree in various ways.This implementation allows
xto be used as both an operator for1.23x10^4as well as a variable (for when you eventually allow significant figures in formulas). The idea is that1.23x10^4is usually interpreted as1.23*x*10^4via implicit multiplication, so we override the implicit multiplication operator to look for1.23*x(with implicit multiplication) on the left and10^4on the right, and then it removes the*xon the left to get1.23*10^4and marks it as exponential form so that it stringifies as1.23x10^4and is treated as a single number.If
xgets removed as a variable, then thexoperator comes into play, and is treaded as *.That is the basic idea, but there are a bunch of subtleties, especially in tracking what is a pure number and what is a computed number. The processing of exponential form is strict about the left-hand operand being a simple number (not a computation) and the right-hand being a constant 10 raised to an integer power (again not computed). Having parentheses counts as being a computation, so
(1.23)x10^4would not produce an exponential form, nor would1.23x10^(4)or1.23x(10)^4, or1.23x10^--2. The only exception is that parentheses are allowed around a negative exponent:1.23x10^(-4). The left-hand number can be any number, so12.3x10^4is also allowed.The string and TeX output functions have been modified to allow printing of numbers in exponential form, so a number entered that was will always print in exponential form, and the string version will be
1.23x10^4rather than1.23E+04(though you can use either form to enter the number). There is also a new content flag,alwaysExponentialFormthat controls whether to print all reals in exponential form (off by default).I modified your
LimitedSignificantFigurescontext to use these new features to allow exponential form in the limited setting, and to handle the issue of negation that I mentioned earlier.I didn't add any tests, but there should be a lot more to test the new notation and the limited context. There should also be tests using
reduceConstants => 0, since that requires the parser to handlexand the other operators differently, so tests should be made for both settings ofreduceConstants.Finally, I didn't modify the POD documentation, so you will need to add the new exponential form there yourself.
As for the details of the changes, the modifications in
SignificantFigures::Real->new()are to move the check for an existing Real to after the coercion to a Value object byValue::makeValue(), so that if that produces a Real (say from passing a string that reduces to a number rather than a number itself), we handle it as we would have if it were passed tonew()directly. (This was a bug before, but I didn't catch it.) It also marks the result aspurewhen that is appropriate.The
string()andTeX()functions now add parentheses when the result contains exponential form and the number is being used in a larger expression (so that it is treated as a unit). That means that2^(1.2x10^-3)will not become2^1.2x10^3which would be interpreted as(2^3)x10^3, producing a error (the left-hand operand ofxmust be a simple number).The
format()was actually producing some incorrect results, which are addressed here. First, the wrong condition was being used to convert anfformat toE, which is fixed in (new) line 250. It also was adding a.too aggressively. It should only add it when the result is an integer having exactly the number of significant digits as total digits. That is fixed here.The computation functions are modified to mark the results as being computed values (so not pure numbers), which is part of the tracking of computations so that exponential form can be processed properly. A
power()method is added to handle exponentiation (mostly for10^n, but also allows other exponentials).The rest of the changes are basically just new code to handle the exponential form as described above. There are some comments indicating the most important parts, but mostly is not all that interesting.
In any case, I think this implements what you are trying to do in your #27 and #30 (and builds on your #25).