[Shell Unix] division, rounding

renaud -  
lami20j Posted messages 21506 Registration date   Status Moderator, Security Contributor Last intervention   -
Hello,

I'm writing a shell script and I'm using a division res=$(expr $a / $b). After some research, it seems that this corresponds to integer division.
However, res varies between 0 and 6. I'm losing a lot of precision: if $a/$b = 1.9, I get 1 as the result...
How can we handle floating points in a shell? In my specific case, rounding to the nearest integer would be fine for me, even though it's not perfect (0.5 returns 1, 0.7 returns 1, 0.3 returns 0...)

Is there a simple solution to achieve this?
Thank you

4 answers

  1. lami20j Posted messages 21506 Registration date   Status Moderator, Security Contributor Last intervention   3 571
     
    Hello,
    echo "scale=2; 5.7/3" | bc

    man bc
    man dc

    lami20j
    2
  2. jipicy Posted messages 40842 Registration date   Status Moderator Last intervention   4 898
     
    Hi,

    Can you post a concrete example please of what you get and what you would like to get.

    --

    Z'@+...che.
    JP : Zen, mes Nuggets ! ;-) Le savoir n'est bon que s'il est partagé.
    1
    1. reg
       
      Thank you for looking so quickly,
      What I want to do:
      write a number in scientific format to a .txt file
      I do:

      M=$((5/2));
      printf "%E" $M >> in

      with this I get: 2.000000E+00
      I want to get 2.500000E+00
      In addition, I am forced to divide integers while I would like to divide reals.

      I tried this command:

      echo "scale=2; 5.7/3" | bc >> in

      I get 1.90 but I can't write this number in scientific format.

      Well, I still don't know if I'm clear but feel free to ask me for more details if needed.
      Thank you in advance
      Reg
      0
      1. jipicy Posted messages 40842 Registration date   Status Moderator Last intervention   4 898 > reg
         
        [tmpfs]$ M=$(echo "scale=2; 5/2" | bc) [tmpfs]$ printf "%E\n" $M -l: printf: 2.50: invalid number 0,000000E+00 [tmpfs]$ printf "%E\n" ${M/\./,} 2,500000E+00 [tmpfs]$
        It's a matter of decimal value delimiter (the default is the point) that needs to be replaced by a comma...

        --

        Z'@+...che.
        JP : Zen, my Nuggets ! ;-) Knowledge is only valuable when shared.
        0
      2. Reg > jipicy Posted messages 40842 Registration date   Status Moderator Last intervention  
         
        Thank you very much for your response,
        It works well
        But I have another small issue now:
        I need to search for a max value in a txt file filled with values in a given column and a given range of lines.
        I can extract certain lines from the file into a temporary file using head and tail commands, but I can't extract a column.
        Do you have any ideas?
        0
  3. lami20j Posted messages 21506 Registration date   Status Moderator, Security Contributor Last intervention   3 571
     
    Hello,

    the file (the fields are space-separated)
    lami20j@debian:~/trash$ cat fic 0 8452 2844 180.88 22.81 0.09 1 8452 3137 180.62 2.28 0.14 2 8452 3430 149.66 -1.84 0.30 3 8452 3724 180.62 -28.81 0.15 4 8760 2942 118.56 -18.09 0.12 5 8760 3235 173.00 28.62 0.12 6 8760 3528 149.59 -1.97 0.17 7 8760 3821 149.75 -1.88 0.44 8 9067 3039 157.84 2.12 0.18 9 9067 3333 134.97 -5.31 0.17 10 9067 3626 149.50 -1.75 0.48 11 9375 2844 137.22 -0.03 0.13 12 9375 3137 179.19 9.19 0.14 13 9375 3430 149.38 -1.91 0.47 14 9375 3723 153.91 -19.97 0.10 15 9682 2942 125.97 26.34 0.17 

    let's take the case of column 5 (in bold),
    I want to display the max for column 5 only between lines numbered 3 to 10
    lami20j@debian:~/trash$ cat fic 0 8452 2844 180.88 22.81 0.09 1 8452 3137 180.62 2.28 0.14 2 8452 3430 149.66 -1.84 0.30 3 8452 3724 180.62 -28.81 0.15 4 8760 2942 118.56 -18.09 0.12 5 8760 3235 173.00 28.62 0.12 6 8760 3528 149.59 -1.97 0.17 7 8760 3821 149.75 -1.88 0.44 8 9067 3039 157.84 2.12 0.18 9 9067 3333 134.97 -5.31 0.17 10 9067 3626 149.50 -1.75 0.48 11 9375 2844 137.22 -0.03 0.13 12 9375 3137 179.19 9.19 0.14 13 9375 3430 149.38 -1.91 0.47 14 9375 3723 153.91 -19.97 0.10 15 9682 2942 125.97 26.34 0.17 lami20j@debian:~/trash$ sed '4,11!d' fic|cut -d"&" -f5|sort -n -28.81 -18.09 -5.31 -1.75 -1.88 -1.97 2.12 28.62 lami20j@debian:~/trash$ sed '4,11!d' fic|cut -d"&" -f5|sort -n|tail -1 28.62 lami20j@debian:~/trash$ 

    --

    lami20j
    1
    1. jipicy Posted messages 40842 Registration date   Status Moderator Last intervention   4 898
       
      Hi,

      With "awk" it might be more appropriate, right?
      awk ' NR==3,NR==10 { print $5 }' fic | sort -n | tail -1
      ;-))

      --
      Z'@+...che.
       Make a gesture for the environment, close your windows and adopt a penguin.
      0
      1. lami20j Posted messages 21506 Registration date   Status Moderator, Security Contributor Last intervention   3 571 > jipicy Posted messages 40842 Registration date   Status Moderator Last intervention  
         
        Yes, indeed ;-))
        --

        lami20j
        P.S. That's already good, don't forget that I didn't provide a solution in Perl ;-DDDD
        0
  4. reg
     
    Hello everyone,

    I have a problem similar to Renaud's.
    In my Shell script, I would like to divide two real or integer numbers and get a real number as a result.

    echo "scale=2; 5.7/3" | bc

    This command works, but I need to write the result to a .txt file.
    I usually use:

    printf "%E" $variable >> file.txt

    But I'm getting integer values.
    What should I do???

    Thanks in advance
    Reg
    0