views:

478

answers:

3

How would I do something like:

ceiling(N/500)

N representing a number.

But in a linux bash script

+4  A: 

Call out to a scripting language with a ceil function. Given $NUMBER:

python -c "from math import ceil; print ceil($NUMBER/500.0)"

or

perl -w -e "use POSIX; print ceil($NUMBER/500.0), qq{\n}"
Josh McFadden
In Perl, wouldn't you use: `ceil($ARGV[0]/$ARGV[1])` to use the two script arguments? And then you'd use single quotes around the script. Or, using double quotes you can let the shell substitute its $1, $2.
Jonathan Leffler
Sure, yeah, <code>perl -w -e 'use POSIX; print ceil($ARGV[0]/$ARGV[1]), qq{\n}' $N 500</code> is fine too, etc. TMTOWTDI. The important bit is using a standards-based ceil implementation.
Josh McFadden
Code tag fail? I'm new here. :(
Josh McFadden
Haha, yeah you can't code code in the comments :( but doesn't matter, I prefer to use Python anyway :) Thanks for the code!
Mint
+1  A: 

Here's a solution using bc (which should be installed just about everywhere):

ceiling_divide() {
  ceiling_result=`echo "($1 + $2 - 1)/$2" | bc`
}

Here's another purely in bash:

# Call it with two numbers.
# It has no error checking.
# It places the result in a global since return() will sometimes truncate at 255.

# Short form from comments (thanks: Jonathan Leffler)
ceiling_divide() {
  ceiling_result=$((($1+$2-1)/$2))
}

# Long drawn out form.
ceiling_divide() {
  # Normal integer divide.
  ceiling_result=$(($1/$2))
  # If there is any remainder...
  if [ $(($1%$2)) -gt 0 ]; then
    # rount up to the next integer
    ceiling_result=$((ceiling_result + 1))
  fi
  # debugging
  # echo $ceiling_result
}
Harvey
and how are you going to divide if $1 is floating point?
You can simplify that to remove the conditional stuff: `ceiling_result=$((($1+$2-1)/$2))`
Jonathan Leffler
@1ch1g0 He said in Bash. There's no floating point in bash. His example showed integers as well and he wants an integer result. Anyway, I added a solution that uses bc. It'll handle the floating point numbers.
Harvey
+2  A: 

you can use awk

#!/bin/bash
number="$1"
divisor="$2"
ceiling() {
    awk -vnumber="$number" -vdiv="$divisor" '
    function ceiling(x){return (x == int(x)) ? x : int(x)+1 }
    BEGIN{ print ceiling(number/div) }'
}
ceiling

output

$ ./shell.sh 1.234 500
1

Or if there's a choice, you can use a better shell that does floating point, eg zsh

integer ceiling_result
ceiling_divide() {
  ceiling_result=$(($1/$2))
  echo $((ceiling_result+1))
}

ceiling_divide 1.234 500
ghostdog74