4

I want to calculate this:

0x0404cb * 2**(8*(0x1b - 3))

which in decimal is:

263371*2^^(8*(27-3))

using | bc.

I tried with

echo 263371*2^^(8*(27-3)) | bc
expr 263371*2^^(8*(27-3)) | bc
zsh: no matches found: 263371*2^^(8*(27-3))

or try to resolve this

238348 * 2^176^

Can I resolve in one shot?

Benjamin W.
  • 46,058
  • 19
  • 106
  • 116
monkeyUser
  • 4,301
  • 7
  • 46
  • 95
  • Quote the string?? – hek2mgl Jan 09 '19 at 14:57
  • echo "263371*2^^(8^(27-3))" | bc (standard_in) 1: parse error – monkeyUser Jan 09 '19 at 14:58
  • 1
    `bc` doesn't understand `^^`. What does it mean? – hek2mgl Jan 09 '19 at 14:59
  • 0x0404cb * 2**(8*(0x1b - 3)) => `263371*2^^(8^(27-3))` – monkeyUser Jan 09 '19 at 15:04
  • why do you convert the first `*` to `*` but the second one to `^`? – phuclv Jan 09 '19 at 15:04
  • my fault sorry you are right – monkeyUser Jan 09 '19 at 15:05
  • @monkeyUser I'm not good at math. Dunno what you mean with `**` but it is not supported as an operator by `bc`. Check `man bc` to learn which operators are supported – hek2mgl Jan 09 '19 at 15:06
  • PS: I have the feeling that even if you find the right syntax, the numbers you are dealing with are too large for bc – hek2mgl Jan 09 '19 at 15:07
  • @hek2mgl bc supports arbitrarily long numbers. – Benjamin W. Jan 09 '19 at 15:25
  • 1
    Why is it a "power of a power"? There is only when power involved, isn't there? – Benjamin W. Jan 09 '19 at 15:26
  • 1
    @hek2mgl bc is an arbitrary precision calculator, which means there's no limit except the limit of memory – phuclv Jan 09 '19 at 15:42
  • @phuclv thanks, didn't know that – hek2mgl Jan 09 '19 at 16:05
  • @phuclv FYI I tried `echo "263371*2^(8^(27-3))" | bc -l` which gave me `Runtime error (func=(main), adr=24): exponent too large in raise` – hek2mgl Jan 09 '19 at 17:11
  • @hek2mgl do you know how big that is? 2^8^24 = 2^2^72 = 2⁴⁷²²³⁶⁶⁴⁸²⁸⁶⁹⁶⁴⁵²¹³⁶⁹⁶ which needs 2^2^72 bits to store (and a 2⁷²-bit computer to address that memory). To give you some perspective, it's 1777*10¹⁶ times bigger than the total number of particles in the universe (10⁸⁰). Also from `man bc` you can see that it's a little bit crippled compared to other [arbitrary precision calculators](https://en.wikipedia.org/wiki/Arbitrary-precision_arithmetic): `The value of the exponent in the raise operation (^) is limited to LONG_MAX.` – phuclv Jan 10 '19 at 03:03
  • Yeah, that's what I meant with the numbers are too big. (well, since I was thinking we are limited to 64 bit those numbers would be quite a lot toooooo large). But looks like misinterpreted the OP's intention. And yes, I have no idea how large that is :) – hek2mgl Jan 10 '19 at 03:12

1 Answers1

8

The bc "power of" operator is ^. You also have to quote everything to prevent the shell from trying to do things like history substitution and pathname expansion or interpreting parentheses as subhells:

$ bc <<< '263371*2^(8*(27-3))'
1653206561150525499452195696179626311675293455763937233695932416

If you want to process your initial expression from scratch, you can use the ibase special variable to set input to hexadecimal and do some extra processing:

eqn='0x0404cb * 2**(8*(0x1b - 3))'

# Replace "**" with "^"
eqn=${eqn//\*\*/^}

# Remove all "0x" prefixes
eqn=${eqn//0x}

# Set ibase to 16 and uppercase the equation
bc <<< "ibase = 16; ${eqn^^}"

or, instead of with parameter expansion, more compact and less legible with (GNU) sed:

sed 's/\*\*/^/g;s/0x//g;s/.*/\U&/;s/^/ibase = 16; /' <<< "$eqn" | bc
Benjamin W.
  • 46,058
  • 19
  • 106
  • 116
  • 2
    also hex numbers can be converted to decimal `bc <<< 'ibase=16;x=404CB;y=1B;ibase=10;x*2^(8*(y-3))'` – Nahuel Fouilleul Jan 09 '19 at 15:38
  • 2
    @NahuelFouilleul Good point. Since `8` is the same in binary and decimal, we can just set `ibase` to 16 and leave output to decimal, I'll add that. – Benjamin W. Jan 09 '19 at 15:40