从linux中的数字中获取天花板整数(BASH)

时间:2010-03-07 03:04:17

标签: linux bash shell ceil ceiling

我该怎样做:

ceiling(N/500)

N代表一个数字。

但是在Linux Bash脚本中

15 个答案:

答案 0 :(得分:73)

为什么要使用外部脚本语言?你默认得到楼层。要获得ceil,请执行

$ divide=8; by=3; let result=($divide+$by-1)/$by; echo $result
3
$ divide=9; by=3; let result=($divide+$by-1)/$by; echo $result
3
$ divide=10; by=3; let result=($divide+$by-1)/$by; echo $result
4
$ divide=11; by=3; let result=($divide+$by-1)/$by; echo $result
4
$ divide=12; by=3; let result=($divide+$by-1)/$by; echo $result
4
$ divide=13; by=3; let result=($divide+$by-1)/$by; echo $result
5
....

考虑到负数,你可以加强一点。可能更干净的方式,但对于初学者

$ divide=-10; by=10; neg=; if [ $divide -lt 0 ]; then let divide=-$divide; neg=1; fi; let result=($divide+$by-1)/$by; if [ $neg ]; then let result=-$result; fi; echo $result
-1

$ divide=10; by=10; neg=; if [ $divide -lt 0 ]; then let divide=-$divide; neg=1; fi; let result=($divide+$by-1)/$by; if [ $neg ]; then let result=-$result; fi; echo $result
1

答案 1 :(得分:16)

使用ceil函数调用脚本语言。鉴于$NUMBER

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

perl -w -e "use POSIX; print ceil($NUMBER/500.0), qq{\n}"

答案 2 :(得分:6)

这是一个使用bc的解决方案(应该随处安装):

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

这是纯粹在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
}

答案 3 :(得分:5)

您可以使用awk

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

输出

$ ./shell.sh 1.234 500
1

或者如果有选择,你可以使用更好的shell 做浮点数,例如Zsh

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

ceiling_divide 1.234 500

答案 4 :(得分:4)

数学上,天花板的功能可以用floor,ceiling(x)= -floor(-x)来定义。并且,将正浮点数转换为整数时,floor是默认值。

public Boolean move(float x, float y, int delta) {
       this.setx(x);
}

参考。 https://en.wikipedia.org/wiki/Floor_and_ceiling_functions

答案 5 :(得分:2)

Floor () {
  DIVIDEND=${1}
  DIVISOR=${2}
  RESULT=$(( ( ${DIVIDEND} - ( ${DIVIDEND} % ${DIVISOR}) )/${DIVISOR} ))
  echo ${RESULT}
}
R=$( Floor 8 3 )
echo ${R}

Ceiling () {
  DIVIDEND=${1}
  DIVISOR=${2}
  $(( ( ( ${DIVIDEND} - ( ${DIVIDEND} % ${DIVISOR}) )/${DIVISOR} ) + 1 ))
  echo ${RESULT}
}
R=$( Ceiling 8 3 )
echo ${R}

答案 6 :(得分:2)

Kalle's great answer上扩展一下,这里的算法很好地包含在一个函数中:

ceildiv() {
    local num=$1
    local div=$2
    echo $(( (num + div - 1) / div ))
}

或作为单行:

ceildiv(){ echo $((($1+$2-1)/$2)); }

如果你想获得幻想,你可以使用更强大的版本验证输入来检查它们是否具有数字,还可以处理负数:

ceildiv() {
    local num=${1:-0}
    local div=${2:-1}
    if ! ((div)); then
        return 1
    fi
    if ((num >= 0)); then
        echo $(( (num + div - 1) / div ))
    else
        echo $(( -(-num + div - 1) / div ))
    fi
}

这使用"假的"对于负数,ceil为最高绝对整数,即,-10 / 3 = -4而不是-3,因为它应该为-3> -4。如果你想要一个真实的" ceil,请在$(( num / div ))

之后使用else

然后使用它:

$ ceildiv 10 3
4
$ ceildiv 501 500
2
$ ceildiv 0 3
0
$ ceildiv -10 1
-10
$ ceildiv -10 3
-4

答案 7 :(得分:1)

使用华丽的'printf'1会向上舍入到下一个整数

printf %.0f $float
or
printf %.0f `your calculation formula`
or
printf %.0f $(your calculation formula)

参考:how to remove decimal from a variable?

答案 8 :(得分:0)

这是一个使用Awk的简单解决方案:

如果你想要($ a / $ b)的ceil使用

echo "$a $b" | awk '{print int( ($1/$2) + 1 )}'

和场地使用

echo "$a $b" | awk '{print int($1/$2)}'

请注意,我只是将股息'$ a'作为第一行到awk,将除数'$ b'作为第二个。

答案 9 :(得分:0)

更简洁的Awk逻辑

awk '
function ceil(ip) {
  print ip%1 ? int(ip)+1 : ip
}  
BEGIN {
  ceil(1000/500)
  ceil(1001/500)
}
'

结果

2
3

答案 10 :(得分:0)

如果除法返回非浮点数,则此函数不会加1。

function ceiling {
    DIVIDEND=${1}
    DIVISOR=${2}
    if [ $(( DIVIDEND % DIVISOR )) -gt 0 ]; then
            RESULT=$(( ( ( $DIVIDEND - ( $DIVIDEND % $DIVISOR ) ) / $DIVISOR ) + 1 ))
    else
            RESULT=$(( $DIVIDEND / $DIVISOR ))
    fi
    echo $RESULT
}

像这样使用:

echo $( ceiling 100 33 )
> 4

答案 11 :(得分:0)

不指定任何功能,我们可以使用以下awk脚本:

echo x y | awk '{ r=$1 % $2; q=$1/y; if (r != 0) q=int(q+1); print q}'

不确定此错误是否出现逻辑错误。请更正。

答案 12 :(得分:0)

如果您已经熟悉Python库,那么可能不希望学习bc,而是想定义以下bash函数:

pc () { pyexpr="from math import *; print($@)"; python -c "$pyexpr"; }

然后:

pc "ceil(3/4)"
1

,但任何有效的python expression 均可:

pc pi / 4
0.7853981633974483

pc "'\n'.join(['Pythagoras said that %3.2f^2 + %3.2f^2 is always %3.2f'
    % (sin(ai), cos(ai), sin(ai)**2 + cos(ai)**2)
    for ai in [pi / 4 * k for k in range(8)]])"
Pythagoras said that 0.00^2 + 1.00^2 is always 1.00
Pythagoras said that 0.71^2 + 0.71^2 is always 1.00
Pythagoras said that 1.00^2 + 0.00^2 is always 1.00
Pythagoras said that 0.71^2 + -0.71^2 is always 1.00
Pythagoras said that 0.00^2 + -1.00^2 is always 1.00
Pythagoras said that -0.71^2 + -0.71^2 is always 1.00
Pythagoras said that -1.00^2 + -0.00^2 is always 1.00
Pythagoras said that -0.71^2 + 0.71^2 is always 1.00

答案 13 :(得分:0)

如果已安装,则可以使用 jq。它是“用于 JSON 的 sed”,但我发现它对于像这样的简单任务也非常方便。

示例:

$ echo 10.001 | jq '.|ceil'
11

$ jq -n '-10.001 | ceil'
-10

答案 14 :(得分:0)

如果您有一个十进制数的字符串表示,bash 确实支持使用 printf 函数的上限,如下所示:

$ printf %.4f 0.12345
0.1235

但如果您需要使用小数进行一些数学运算,您可以使用 bc -l,默认情况下会缩放到 20 位小数,然后使用 printf 的结果进行四舍五入。

printf %.3f $(echo '(5+50*3/20 + (19*2)/7 )' | bc -l)
17.929