Re: Arithmetic evaluation of negative numbers with base prefix
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
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
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.