2

I'm using bc from a bash script to do some quick and dirty BigInteger math but, when I bump up the scale, it starts splitting lines on me:

pax> echo 'scale=200 ; 1 / 4' | bc
.2500000000000000000000000000000000000000000000000000000000000000000\
00000000000000000000000000000000000000000000000000000000000000000000\
00000000000000000000000000000000000000000000000000000000000000000

pax> num="$(echo 'scale=200 ; 1 / 4' | bc )" ; echo $num
.2500000000000000000000000000000000000000000000000000000000000000000\ 00000 ...

How do I stop this from happening so that I can just get the number without any splits? The man page documents this behaviour but doesn't seem to give any options for changing it.


Actually, I'll step back and tell you the source of the request in case anyone has a better solution. I need an array of strings in C equivalent to the values 2-n, along the lines of:

static char *str[] = {
    "1.00000000 ... 000",     // 1/1 to 150 fractional places.
    "0.50000000 ... 000",     // 1/2
    "0.25000000 ... 000",     // 1/4
    "0.12500000 ... 000",     // 1/8
    : : :
    "0.00000000 ... 004",     // 1/(2^256)
};

I don't care what language generates the array, I'm just going to take the output and plug it into my C code. I do need the accuracy however.

Celada
  • 21,627
  • 4
  • 64
  • 78
paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953
  • Wouldn't it be simpler to avoid using `bc` and `bash` in the first place? A simple Python program would probably be easier than this. Why are you sticking with `bc`? – S.Lott Nov 26 '10 at 03:04

3 Answers3

2

At least on my system, the BC_LINE_LENGTH environment variable controls how long the output lines are:

$ echo 'scale=200; 1/4' | BC_LINE_LENGTH=9999 bc
.25000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
Sean
  • 29,130
  • 4
  • 80
  • 105
  • Setting BC_LINE_LENGTH=0 disables the multi-line feature (according to the GNU bc man page). – camh Nov 26 '10 at 03:21
  • AArrgghh! Damn `less` and its case-sensitive search - I looked for `length` and found nothing. `LENGTH` would have taken me to _exactly_ the right section. – paxdiablo Nov 26 '10 at 03:22
  • I prefer to leave case-sensitive the default and type `-i` from inside `less` to go insensitive, but many use the `LESS` environment variable to set `-i` by default (on *systems* where that's the default I confuse the hell out of myself by toggling it back on). – Ben Jackson Nov 26 '10 at 08:35
1
localhost:~ slott$ python -c 'print "{0:.200f}".format( 1./4. )'
0.25000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000


localhost:~ slott$ python -c 'import decimal; print 1/decimal.Decimal( 2**256 )'
8.636168555094444625386351863E-78

import decimal
for i in range(256):
    print "{0:.150f}".format(1/decimal.Decimal(2**i))

That's the raw values.

If you want to create proper C syntax, use something like this.

def long_string_iter():
    for i in range(256):
        yield i, "{0:.150f}".format(1/decimal.Decimal(2**i))

def c_syntax( string_iter ):
   print "static char *str[] = {"
   for i, value in string_iter():
       print '    "{0}", // 1/{1}'.format( value, i )
   print "};"

That might do what you want.

S.Lott
  • 384,516
  • 81
  • 508
  • 779
  • I need this to go to about 150 fractional digits (probably only 100 but some for safety) - is Python capable of this (specifically `1/(2^256) = 8.6361685550944446253863518628004e-78`)? – paxdiablo Nov 26 '10 at 03:09
  • @paxdiablo: 150 fractional digits? You're doing the math wrong, then. Do some algebra and get rid of the division. Python can handle an indefinite number of digits. However, depending on a division operator introduces noise bits at the right-hand end of things. A bad, bad design. – S.Lott Nov 26 '10 at 14:45
0
% echo 'scale=200; 1/4' | bc | tr -d '\n' | tr -d '\\'
.25000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
Janus Troelsen
  • 20,267
  • 14
  • 135
  • 196