I'm pretty sure we should change the behavior of %e in the presence of numer, whether or not the current behavior is intentional. Reopening this report accordingly.
I've been bitten by this inconsistency repeatedly.
%e, numer;
=> 2.718281828459045
%e + 1, numer;
=> %e + 1
%e^%pi, numer;
=> 23.14069263277927
%e^%e, numer;
=> %e^%e
Preserving %e in %e^foo, numer when foo is non-numeric is OK by me. I suppose that's the original intent of %enumer but for whatever reason it is not the sole effect.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
What is by design is that %e^x,numer does not become 2.718^x (unless %enumer is true). The other cases are because the original coder either didn't care about cases like %e+1 or thought it would be too computationally expensive to handle them differently, since they can't be handled bottom-up.
After all, all of %e^2, %e^%pi, %e^(2/3) with ,numer *do* evaluate to floats.
If we fix %e+1,numer we should also fix sin(%pi+x),numer. Currently, that gives sin(3.14+x); it should give -sin(x) (that is, the %pi should not simplify to 3.14; the regular simplifier should take over).
There is a special hack so that *at the top level*, %e,numer => 2.718. This is really ugly:
The correct intuition is this: with numer=true, if simplifying a constant (like %e or %pi or for that matter %i and inf) to a float would cause the expression it is contained in (and not just the constant itself) to become a float/complex float, then do it. Otherwise don't. For the purposes of this definition, consider that a top-level constant is "contained in" some sort of expression. This design would give
numer:true
%e^x => %e^x
sin(%pi+x) => -sin(x)
inf => <<IEEE positive infinity>> but of course we don't currently handle that
%e^2 => 7.4
2^%e => 6.6
atan(1) => .78
atan(inf) => 1.57
sin(2/3*%pi + x) => sin(x+2.1)
%e^%i => .5+.8*%i
%i^%i => .27
sin(1+%pi) => -0.84
I don't think we can easily fix all these cases, but we should start. The current behavior is incoherent and not very useful.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
We have the flag %enumer which should prevent the evaluation of %e to its numerical value when the flag $numer is true. The evaluation occurs only when $%enumer is true too.
But we have the following code in the function $ev:
(if (and (cdr l)
(null (cddr l))
(eq (car l) '$%e)
(eq (cadr l) '$numer))
(setq l (append l '($%enumer))))
This code is responsible for some of the inconsistent behaviors as reported in this bug report:
%e is evaluated because of the above special handling:
A further complication is the simplifier. If we have an exponent, simplification and not evaluation causes the numerical evaluation.
(%i5) %e^1,numer,noeval;
(%o5) 2.718281828459045
First I tried to get this all more consistent by removing the hack in $ev which causes evaluation of %e in certain expressions. But because of the simplifier, as shown in the last example, this does not help completely.
So, I think it would be most consistent to cut out the special handling of the flag %enumer in the code of meval1.
((and $numer
(setq val (safe-mget form '$numer))
;(or (not (eq form '$%e)) $%enumer)
)
(return (meval1 val)))
There are two further pieces of code we can cut out. With this changes %enumer has no longer a function and we would get:
The flag %enumer has not been cut out as suggested in the last posting, but code has been added to simp.lisp with revision 1.77 to simplify %e in expressions, when $numer is true.
The examples 1+%e, %e^%e give the expected numerical values. Furhtermore functions with %e as an argument simplify accordingly.
Closing this bug report as fixed.
Dieter Kaiser
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Logged In: YES
user_id=588346
1+%e,numer also fails
These examples work with bfloat, e.g.
1+%e,bfloat;
%e^%e,bfloat;
Logged In: YES
user_id=588346
cf. bug 531466 re float(exp(exp(2)))
Logged In: YES
user_id=501686
Still present in 5.9.3.
Logged In: YES
user_id=1797506
Originator: NO
This seems to be by design.
(%i5) %e^%e,numer,%enumer;
(%o5) 15.15426224147926
(%i6) %e^%e,numer;
(%o6) %e^%e
(%i7) %e+1,numer,%enumer;
(%o7) 3.718281828459045
(%i8) %e+1,numer;
(%o8) %e+1
Logged In: YES
user_id=501686
Originator: NO
I'm pretty sure we should change the behavior of %e in the presence of numer, whether or not the current behavior is intentional. Reopening this report accordingly.
I've been bitten by this inconsistency repeatedly.
%e, numer;
=> 2.718281828459045
%e + 1, numer;
=> %e + 1
%e^%pi, numer;
=> 23.14069263277927
%e^%e, numer;
=> %e^%e
Preserving %e in %e^foo, numer when foo is non-numeric is OK by me. I suppose that's the original intent of %enumer but for whatever reason it is not the sole effect.
Logged In: YES
user_id=588346
Originator: YES
What is by design is that %e^x,numer does not become 2.718^x (unless %enumer is true). The other cases are because the original coder either didn't care about cases like %e+1 or thought it would be too computationally expensive to handle them differently, since they can't be handled bottom-up.
After all, all of %e^2, %e^%pi, %e^(2/3) with ,numer *do* evaluate to floats.
If we fix %e+1,numer we should also fix sin(%pi+x),numer. Currently, that gives sin(3.14+x); it should give -sin(x) (that is, the %pi should not simplify to 3.14; the regular simplifier should take over).
There is a special hack so that *at the top level*, %e,numer => 2.718. This is really ugly:
%e,numer => 2.7
%e+1,numer => %e+1
[%e],numer => [%e]
The correct intuition is this: with numer=true, if simplifying a constant (like %e or %pi or for that matter %i and inf) to a float would cause the expression it is contained in (and not just the constant itself) to become a float/complex float, then do it. Otherwise don't. For the purposes of this definition, consider that a top-level constant is "contained in" some sort of expression. This design would give
numer:true
%e^x => %e^x
sin(%pi+x) => -sin(x)
inf => <<IEEE positive infinity>> but of course we don't currently handle that
%e^2 => 7.4
2^%e => 6.6
atan(1) => .78
atan(inf) => 1.57
sin(2/3*%pi + x) => sin(x+2.1)
%e^%i => .5+.8*%i
%i^%i => .27
sin(1+%pi) => -0.84
I don't think we can easily fix all these cases, but we should start. The current behavior is incoherent and not very useful.
We have the flag %enumer which should prevent the evaluation of %e to its numerical value when the flag $numer is true. The evaluation occurs only when $%enumer is true too.
But we have the following code in the function $ev:
(if (and (cdr l)
(null (cddr l))
(eq (car l) '$%e)
(eq (cadr l) '$numer))
(setq l (append l '($%enumer))))
This code is responsible for some of the inconsistent behaviors as reported in this bug report:
%e is evaluated because of the above special handling:
(%i5) %e,numer;
(%o5) 2.718281828459045
Partially evaluation with a multiplication:
(%i7) %e*(%e+1)^2,numer;
(%o7) 2.7182817*(%e+1)^2
All examples are evaluated with %enumer true:
(%i10) %e*(%e+1)^2,numer,%enumer;
(%o10) 37.581930949508
We can prevent evaluation:
(%i4) %e,numer,noeval;
(%o4) %e
A further complication is the simplifier. If we have an exponent, simplification and not evaluation causes the numerical evaluation.
(%i5) %e^1,numer,noeval;
(%o5) 2.718281828459045
First I tried to get this all more consistent by removing the hack in $ev which causes evaluation of %e in certain expressions. But because of the simplifier, as shown in the last example, this does not help completely.
So, I think it would be most consistent to cut out the special handling of the flag %enumer in the code of meval1.
((and $numer
(setq val (safe-mget form '$numer))
;(or (not (eq form '$%e)) $%enumer)
)
(return (meval1 val)))
There are two further pieces of code we can cut out. With this changes %enumer has no longer a function and we would get:
(%i8) %e,numer;
(%o8) 2.718281828459045
(%i9) %e+1,numer;
(%o9) 3.718281828459045
(%i10) sin(%e),numer;
(%o10) .4107812905029088
(%i11) (%e+1)^2,numer;
(%o11) 13.82561975584874
When we cut out %enumer, the flag %numer would be more consistent with the results of he flag bfloat and the functions float and bfloat, too.
The testsuite and the share_testsuite would have no problem.
Is there a reason not to cut out the flag %enumer?
Dieter Kaiser
The flag %enumer has not been cut out as suggested in the last posting, but code has been added to simp.lisp with revision 1.77 to simplify %e in expressions, when $numer is true.
The examples 1+%e, %e^%e give the expected numerical values. Furhtermore functions with %e as an argument simplify accordingly.
Closing this bug report as fixed.
Dieter Kaiser