在 Linux 中从数字获取上限整数(BASH)
- 2024-11-07 08:55:00
- admin 原创
- 26
问题描述:
我该怎么做呢:
ceiling(N/500)
N 代表一个数字。
但是在 Linux Bash 脚本中
解决方案 1:
为什么要使用外部脚本语言?默认情况下,您会获得 floor。要获取 ceil,请执行
$ divide=8; by=3; (( result=(divide+by-1)/by )); echo $result
3
$ divide=9; by=3; (( result=(divide+by-1)/by )); echo $result
3
$ divide=10; by=3; (( result=(divide+by-1)/by )); echo $result
4
$ divide=11; by=3; (( result=(divide+by-1)/by )); echo $result
4
$ divide=12; by=3; (( result=(divide+by-1)/by )); echo $result
4
$ divide=13; by=3; (( result=(divide+by-1)/by )); echo $result
5
....
要考虑负数,你可以稍微加强一下。可能还有其他更简洁的方法,但对于初学者来说
$ divide=-10; by=10; neg=; if [ $divide -lt 0 ]; then (( divide=-divide )); neg=1; fi; (( result=(divide+by-1)/by )); if [ $neg ]; then (( result=-result )); fi; echo $result
-1
$ divide=10; by=10; neg=; if [ $divide -lt 0 ]; then (( divide=-divide )); neg=1; fi; (( result=(divide+by-1)/by )); if [ $neg ]; then (( result=-result )); fi; echo $result
1
(已编辑以切换let ...
为(( ... ))
。)
解决方案 2:
使用 ceil 函数调用脚本语言。给定$NUMBER
:
python -c "from math import ceil; print ceil($NUMBER/500.0)"
或者
perl -w -e "use POSIX; print ceil($NUMBER/500.0), qq{
}"
解决方案 3:
以下是使用 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
}
解决方案 4:
您可以使用 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
解决方案 5:
稍微扩展一下Kalle 的精彩答案,下面是一个很好地封装在函数中的算法:
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
}
这会使用“假”的上限来表示负数,即最高绝对整数,即 -10 / 3 = -4,而不是 -3,因为 -3 > -4。如果您想要“真”的上限,请$(( num / div ))
在else
然后像这样使用它:
$ ceildiv 10 3
4
$ ceildiv 501 500
2
$ ceildiv 0 3
0
$ ceildiv -10 1
-10
$ ceildiv -10 3
-4
解决方案 6:
从数学上来说,ceiling 函数可以用 floor 来定义,ceiling(x) = -floor(-x)。并且,将正浮点数转换为整数时,floor 是默认值。
if [ $N -gt 0 ]; then expr 1 - $(expr $(expr 1 - $N) / 500); else expr $N / 500; fi
参考https://en.wikipedia.org/wiki/Floor_and_ceiling_functions
解决方案 7:
如果安装了jq,则可以使用它。它是“用于 JSON 的 sed”,但我发现它对于像这样的简单任务也非常方便。
例子:
$ echo 10.001 | jq '.|ceil'
11
$ jq -n '-10.001 | ceil'
-10
解决方案 8:
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}
解决方案 9:
如果您有一个十进制数的字符串表示形式,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
解决方案 10:
这是一个使用 Awk 的简单解决方案:
如果你想要 ($a/$b) 的上限,请使用
echo "$a $b" | awk '{print int( ($1/$2) + 1 )}'
和地板使用
echo "$a $b" | awk '{print int($1/$2)}'
请注意,我只是将被除数“$a”作为该行的第一个字段回显到 awk,将除数“$b”作为第二个字段回显到 awk。
解决方案 11:
一些更简洁的 Awk 逻辑
awk '
function ceil(ip) {
print ip%1 ? int(ip)+1 : ip
}
BEGIN {
ceil(1000/500)
ceil(1001/500)
}
'
结果
2
3
解决方案 12:
如果除法返回非浮点数,则此函数不会加 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
解决方案 13:
一些更简洁的 Awk 逻辑
awk '
function ceil(ip) {
print ip%1 ? int(ip)+1 : ip
}
BEGIN {
ceil(1000/500)
ceil(1001/500)
}
'
结果
2
3
解决方案 14:
使用华丽的“printf” 1将四舍五入到下一个整数
printf %.0f $float
or
printf %.0f `your calculation formula`
or
printf %.0f $(your calculation formula)
参考:如何从变量中删除小数?
解决方案 15:
无需指定任何函数,我们可以使用以下 awk 脚本:
echo x y | awk '{ r=$1 % $2; q=$1/y; if (r != 0) q=int(q+1); print q}'
不确定这个是否有任何逻辑错误。请纠正。
解决方案 16:
如果你已经熟悉 Python 库,那么bc
你可能想要定义这个 bash 函数,而不是学习:
pc () { pyexpr="from math import *; print($@)"; python -c "$pyexpr"; }
然后:
pc "ceil(3/4)"
1
但任何有效的 Python表达式也可以起作用:
pc pi / 4
0.7853981633974483
pc "'
'.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
- 2024年20款好用的项目管理软件推荐,项目管理提效的20个工具和技巧
- 2024年开源项目管理软件有哪些?推荐5款好用的项目管理工具
- 项目管理软件有哪些?推荐7款超好用的项目管理工具
- 项目管理软件哪个最好用?盘点推荐5款好用的项目管理工具
- 项目管理软件有哪些最好用?推荐6款好用的项目管理工具
- 项目管理软件有哪些,盘点推荐国内外超好用的7款项目管理工具
- 2024项目管理软件排行榜(10类常用的项目管理工具全推荐)
- 项目管理软件排行榜:2024年项目经理必备5款开源项目管理软件汇总
- 2024年常用的项目管理软件有哪些?推荐这10款国内外好用的项目管理工具
- 项目管理必备:盘点2024年13款好用的项目管理软件