printf is the only builtin way to reformat a number in a different base and only bases 8, 10 and 16 are supported.
bash (contrary to shells like
fish), using command substitution implies forking a subshell. You can use
printf -v here to avoid the subshell (also available in recent versions of
print -f) which also supports printing into arrays):
printf -v NEWBASE '%#X' "$((BASE + OFFSET))"
bash, contrary to
$((...)) is subject to word splitting, so needs quoted to avoid the dependency on
zsh, you can specify the expansion base as part of the arithmetic expansion syntax (bases 2 to 36):
$ echo $(([#16] 0xff + 0xff))
$ echo $(([##16] 0xff + 0xff))
$ echo 0x$(([##16] 0xff + 0xff))
$ echo $(([##2] 0xff + 0xff))
With ksh and zsh, you can also force the expansion of an integer variable to be in a specific base with:
typeset -i 16 NEWBASE
The expansion will be in the
16#1FE form. ksh93 supports bases up to 64,
mksh up to 36.
printf builtin supports outputting number in arbitrary bases as well with or without the
$ printf '%..2d\n' 0x1FE
$ printf '%#..2d\n' 0x1FE
var=$(printf...) doesn't fork a subshell so is as efficient as