Re: Arithmetic evaluation of negative numbers with base prefix

2019-06-14 Thread Ilkka Virta

On 14.6. 17:19, Jeremy Townshend wrote:

echo $((10#-1))   # -1 as expected


Earlier discussion about the same on bug-bash:
https://lists.gnu.org/archive/html/bug-bash/2018-07/msg00015.html

Bash doesn't support the minus (or plus) sign following the 10#.
I think the expression above seems to work in this case because 10# is 
treated as a constant number by itself (with a value of 0), and then the 
1 is subtracted.


try also e.g.:

  $ echo $((10#))
  0


echo $((0-10#-1)) # -1 UNEXPECTED. Would expect 1.


So this is 0-0-1 = -1

--
Ilkka Virta / itvi...@iki.fi



Re: Arithmetic evaluation of negative numbers with base prefix

2019-06-14 Thread Chet Ramey
On 6/14/19 10:19 AM, Jeremy Townshend wrote:

> Bash Version: 4.4
> Patch Level: 19
> Release Status: release
> 
> Description:
>   Unexpected and undocumented behaviour for arithmetic evaluation of 
> negative numbers when prefixed with the optional "base#" (e.g. 10#${i}). The 
> base prefix may be needed if the variable has a decimal integer value but 
> might be zero-padded, otherwise it is at risk of being misinterpreted as an 
> octal.  Where the variable holds a negative value, results are as you would 
> expect (e.g. i=-1; echo $((10#${i})), returns -1) until you subtract (or 
> unary minus) the variable.  This unexpected behaviour occurs even when 
> numbers are used directly (as in the first part of the Repeat-By section to 
> simplify) but in real world examples the number would be hidden in a variable 
> requiring the optional "base#" prefix to ensure correct interpretation of its 
> value. 

I think the issue is that unary minus is an operator, not part of an
integer constant. That affects how expressions are parsed.

Couple that with the shell's arithmetic evaluator being helpful and
treating 10# as identical to 10#0, you can see how the results you
mark as `unexpected' are straightforward results of operator parsing.


-- 
``The lyf so short, the craft so long to lerne.'' - Chaucer
 ``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, UTech, CWRUc...@case.eduhttp://tiswww.cwru.edu/~chet/



Arithmetic evaluation of negative numbers with base prefix

2019-06-14 Thread Jeremy Townshend
Configuration Information [Automatically generated, do not change]:
Machine: x86_64
OS: linux-gnu
Compiler: gcc
Compilation CFLAGS:  -DPROGRAM='bash' -DCONF_HOSTTYPE='x86_64' 
-DCONF_OSTYPE='linux-gnu' -DCONF_MACHTYPE='x86_64-pc-linux-gnu' 
-DCONF_VENDOR='pc' -DLOCALEDIR='/usr/share/locale' -DPACKAGE='bash' -DSHELL 
-DHAVE_CONFIG_H   -I.  -I../. -I.././include -I.././lib  -Wdate-time 
-D_FORTIFY_SOURCE=2 -g -O2 -fdebug-prefix-map=/build/bash-vEMnMR/bash-4.4.18=. 
-fstack-protector-strong -Wformat -Werror=format-security -Wall 
-Wno-parentheses -Wno-format-security
uname output: Linux tower 4.15.0-48-generic #51-Ubuntu SMP Wed Apr 3 08:28:49 
UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
Machine Type: x86_64-pc-linux-gnu

Bash Version: 4.4
Patch Level: 19
Release Status: release

Description:
Unexpected and undocumented behaviour for arithmetic evaluation of 
negative numbers when prefixed with the optional "base#" (e.g. 10#${i}). The 
base prefix may be needed if the variable has a decimal integer value but might 
be zero-padded, otherwise it is at risk of being misinterpreted as an octal.  
Where the variable holds a negative value, results are as you would expect 
(e.g. i=-1; echo $((10#${i})), returns -1) until you subtract (or unary minus) 
the variable.  This unexpected behaviour occurs even when numbers are used 
directly (as in the first part of the Repeat-By section to simplify) but in 
real world examples the number would be hidden in a variable requiring the 
optional "base#" prefix to ensure correct interpretation of its value. 

Repeat-By:
echo $((10#-1))   # -1 as expected
echo $((0-10#1))  # -1 as expected
echo $((0+10#-1)) # -1 as expected
echo $((0-10#-1)) # -1 UNEXPECTED. Would expect 1.
echo $((0--1))# 1 as expected

# Real world example:
i=001
echo $((3-10#${i})) # 2 as expected
i=$((10#${i}-2))# i's value decremented by 2 to -1
echo $((3-10#${i})) # 2 UNEXPECTED. Would expect 4.
echo $((3+10#${i})) # 2 as expected
# Certainly wouldn't expect the last two expressions to have the same
# result.