2

I'm trying to use the comparison operator of bc and I'm getting a "syntax error on line 1 stdin" error. I need to use the comparison functionality within a korn script because korn doesn't handle floating points well. Example usage below:

echo "scale=2; 3.2 > 3" | bc
Michael Mrozek
  • 93,103
  • 40
  • 240
  • 233
Ben
  • 205
  • 2
    Works for me, I'm afraid. – Paul Tomblin Oct 25 '11 at 15:15
  • 1
    What's your bc? I get a similar error using plan9port's bc while everything works fine with FreeBSD's. (My error, for comparison, is syntax error:1, <nil> and also happens when I don't redirect stdin (i.e., use bc directly) and when I don't use floats.) – sr_ Oct 25 '11 at 15:18
  • Is your locale set to US or EN? Maybe it is expecting continental floats (3,2)? But Gnu-bc on Linux does not, for example - it works for me with LC_ALL=....de – user unknown Jan 24 '12 at 10:02
  • The above appears to work for me too. bc version: bc 1.06.95 Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, Inc. – Barun Feb 23 '12 at 18:21

3 Answers3

2

What you did should have worked; it complies with bc as specified by POSIX. However, bc is a relatively little-used tool and some implementations may be buggy. If you're not using any mathematical functions more advanced than +-*/ and comparisons, you can use awk; even the original implementation by A, W and K supported floating point arithmetic.

echo 3.2 | awk '{exit !($0 > 3)}'
1

expr can handle float comparisons like that, just fine.

ksh -c '(( $(expr 3.2 \> 3) == 1 )) && echo 1 || echo 0'

or use it in a script, like:

#!/usr/bin/ksh

if [ $(expr $1 \> $2) == 1 ]; then
    echo "greater"
else 
    echo "lesser"  
fi

you may find that expr is more portable, because the bc line you're using above works on linux, but not on solaris. using expr should work the same on either of those OSes.

Tim Kennedy
  • 19,697
  • 5
    expr apparently does string comparison, as expr 3.0 \> 3 gives 1 (true) and expr 3.0 = 3 gives 0 (false). Beside that, there is no need to the outer check: if expr $1 \> $2 > /dev/null; then echo "greater"; else echo "lesser"; fi. – manatwork Oct 25 '11 at 16:14
  • 2
    keen observation. expr only does numerical comparison if both arguments are integers. that said, all the greater than comparisons that I've done have worked as expected. I suppose awk could do it too: echo 3.2 3 | awk '{if ($1 > $2) print "1"; else print "0";}' – Tim Kennedy Oct 25 '11 at 17:35
1

If available, try dc:

echo "2 k 3.2 3 [1p] sa <a" | dc

Note that the above will also use 2 decimal precision and will output 1 if the first number (3.2 in the above example) is greater than the second number (3 above). But otherwise will output nothing.

dc is bc's brother, in the GNU documentation described with the same “arbitrary precision calculator” words. In some distributions they are shipped in the same package, in other distributions they are packaged separately.

manatwork
  • 31,277