How to add two hexadecimal numbers in a bash script

I would just simplify your script as:

printf "0x%X\n" $((0xA000 + 0x1000))

Yes, in bash, printf is the only builtin way to reformat a number in a different base and only bases 8, 10 and 16 are supported.

In bash (contrary to shells like ksh93 or fish), using command substitution implies forking a subshell. You can use printf -v here to avoid the subshell (also available in recent versions of zsh for print and printf (print -f) which also supports printing into arrays):

printf -v NEWBASE '%#X' "$((BASE + OFFSET))"

(in bash, contrary to zsh, $((...)) is subject to word splitting, so needs quoted to avoid the dependency on $IFS).

In zsh, you can specify the expansion base as part of the arithmetic expansion syntax (bases 2 to 36):

$ echo $(([#16] 0xff + 0xff))
16#1FE
$ echo $(([##16] 0xff + 0xff))
1FE
$ echo 0x$(([##16] 0xff + 0xff))
0x1FE
$ echo $(([##2] 0xff + 0xff))
111111110

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, zsh and mksh up to 36.

ksh93's printf builtin supports outputting number in arbitrary bases as well with or without the n# prefix:

$ printf '%..2d\n' 0x1FE
111111110
$ printf '%#..2d\n' 0x1FE
2#111111110

In ksh93, var=$(printf...) doesn't fork a subshell so is as efficient as bash's printf -v.


In GNU or modern BSD dc you can do this like so:

echo A000 1000 | dc -e '16o16i?+p'

16o sets the output base. 16i sets the input base. The ? reads in a line from standard input, which in this case pushes two numbers onto the stack. + adds them. p prints the top of the stack (the answer).