从 linux (BASH) 中的数字获取上限整数

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2394988/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 19:00:43  来源:igfitidea点击:

Get ceiling integer from number in linux (BASH)

linuxbashshellceil

提问by Mint

How would I do something like:

我将如何做类似的事情:

ceiling(N/500)

N representing a number.

N 代表一个数字。

But in a linux Bash script

但是在 linux Bash 脚本中

采纳答案by Josh McFadden

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

使用 ceil 函数调用脚本语言。鉴于$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}"

回答by Kalle

Why use external script languages? You get floor by default. To get ceil, do

为什么要使用外部脚本语言?默认情况下,您获得发言权。要获得细胞,请执行

$ 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
....

To take negative numbers into account you can beef it up a bit. Probably cleaner ways out there but for starters

要考虑负数,您可以稍微加强一下。可能更清洁的方法,但对于初学者来说

$ 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

回答by Harvey

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

这是一个使用 bc 的解决方案(它应该安装在几乎所有地方):

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

Here's another purely in bash:

这是另一个纯粹的 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)/))
}

# Long drawn out form.
ceiling_divide() {
  # Normal integer divide.
  ceiling_result=$((/))
  # If there is any remainder...
  if [ $((%)) -gt 0 ]; then
    # rount up to the next integer
    ceiling_result=$((ceiling_result + 1))
  fi
  # debugging
  # echo $ceiling_result
}

回答by ghostdog74

You can use awk

你可以使用 awk

#!/bin/bash
number=""
divisor=""
ceiling() {
  awk -vnumber="$number" -vdiv="$divisor" '
  function ceiling(x){return x%1 ? int(x)+1 : x}
  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

或者,如果有选择,您可以使用更好的浮点外壳,例如 Zsh

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

ceiling_divide 1.234 500

回答by Frank R.

Mathematically, the function of ceiling can be define with floor, ceiling(x) = -floor(-x). And, floor is the default when converting a positive float to integer.

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

if [ $N -gt 0 ]; then expr 1 - $(expr $(expr 1 - $N) / 500); else expr $N / 500; fi

Ref. https://en.wikipedia.org/wiki/Floor_and_ceiling_functions

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

回答by bsaldivar

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

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

回答by MestreLion

Expanding a bit on Kalle's great answer, here's the algorithm nicely packed in a function:

扩展一下Kalle 的好答案,这是一个很好地打包在一个函数中的算法:

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

or as a one-liner:

或作为单线:

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

If you want to get fancy, you could use a more robust version validates input to check if they're numerical, also handles negative numbers:

如果你想花哨,你可以使用更强大的版本验证输入来检查它们是否是数字,也可以处理负数:

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
}

This uses a "fake" ceil for negative numbers, to the highest absoluteinteger, ie, -10 / 3 = -4 and not -3 as it should, as -3 > -4. If you want a "true" ceil, use $(( num / div ))instead after the else

这对负数使用“假”ceil 到最高绝对整数,即 -10 / 3 = -4 而不是 -3,因为 -3 > -4。如果你想要一个“真正的”ceil,请$(( num / div ))else

And then use it like:

然后像这样使用它:

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

回答by splaisan

Using the gorgeous 'printf' 1will round up to the next integer

使用华丽的 'printf' 1将四舍五入到下一个整数

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

ref: how to remove decimal from a variable?

ref:如何从变量中删除小数?

回答by Kemin Zhou

Without specifying any function, we can use the following awk script:

在不指定任何函数的情况下,我们可以使用以下 awk 脚本:

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

Not sure this one get any logical error or not. Please correct.

不确定这个是否有任何逻辑错误。请纠正。

回答by Leo

If you are already familiar with the Python library, then rather than learn bc, you might want to define this bash function:

如果您已经熟悉 Python 库,那么bc您可能想要定义这个 bash 函数而不是学习:

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

Then:

然后:

pc "ceil(3/4)"
1

but also any valid python expressionworks:

但任何有效的 python表达式也有效:

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