[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: expression evaluation problem

From: L A Walsh
Subject: Re: expression evaluation problem
Date: Wed, 24 Jul 2019 11:43:11 -0700
User-agent: Thunderbird

On 2019/07/24 10:51, Greg Wooledge wrote:
> On Wed, Jul 24, 2019 at 09:39:46AM -0700, L A Walsh wrote:
>> str='cf80'
>> v=960  uxtra=1  c=0
> Irrelevant alias shenanigans omitted.  These are your variables. 

Those aren't my variables.
If you assign the integer attribute to a variable it isn't the same
as when you don't.
>> # In evaluating this expression:
>>   ((v = v | ( uxtra>=++c ? ((0x${str:2*c:2}) & 63) << (6*(uxtra-c)) : 0 )))
>> I get 985 and not 960 as expected
>> Which only happens when 'c' is 0 in the middle 'str' expression,
>> but the ++c should increment 'c' to '1' before it is tested to be
>> less than or equal to 'uxtra'(=1).
> The ${str:2*c:2} part is performed first, while c is still 0, and it
> expands to "cf".
    Why?  It isn't even necessary when 'c' is greater than 'uxtra'

> Only then does the arithmetic evaluation begin.
    Perhaps that such evaluate happens outside of normal evaluation rules is
why shell is so slow?

> wooledg:~$ str='cf80'
> wooledg:~$ v=960  uxtra=1  c=0
> wooledg:~$ ((v = v | ( uxtra>=++c ? ((0xcf) & 63) << (6*(uxtra-c)) : 0 )))
> wooledg:~$ declare -p v
> declare -- v="975"
> Even with that parameter expansion out of the way, this arithmetic
> command is still ridiculously over-complicated.  I can't even guess
> what it's supposed to do.
    That's because it is a fragment from a program.  It was the minimum
from that program to reproduce the problem.  It's supposed to assign 960
to 'v'.
'v' is for 'value'. 'c' is an integer counter.  uxtra is a limit.
> Have you considered performing your calculation in steps, with
> intermediate values stored in temporary variables with clear names?
> That greatly improves readability.
    Does it improve execution time?  That's more of a concern here than
readability, since it is an expression fragment, it isn't meant to be
in isolation.

    More to the point, how do I get evaluation to occur in arithmetic order?
I.e. so the string operation is done in the order the expression is
> Isolating the ++c into its own step would also remove all questions
> about whether the increment is performed before or after other
> calculations (or in this case, parameter expansions).  In-lining ++c
> inside a larger calculation can be OK in very simple situations, but
> a nightmare to read/understand/debug in more complex cases.
    The important part for me is whether or not it is faster to perform
1 calculation, or 100.  So which would be faster?  In this case
execution speed
is more important than clarity.  I consider that a 'constraint'.

reply via email to

[Prev in Thread] Current Thread [Next in Thread]