在 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 )); ech...

问题描述:

我该怎么做呢:

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
相关推荐
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   601  
  华为IPD与传统研发模式的8大差异在快速变化的商业环境中,产品研发模式的选择直接决定了企业的市场响应速度和竞争力。华为作为全球领先的通信技术解决方案供应商,其成功在很大程度上得益于对产品研发模式的持续创新。华为引入并深度定制的集成产品开发(IPD)体系,相较于传统的研发模式,展现出了显著的差异和优势。本文将详细探讨华为...
IPD流程是谁发明的   7  
  如何通过IPD流程缩短产品上市时间?在快速变化的市场环境中,产品上市时间成为企业竞争力的关键因素之一。集成产品开发(IPD, Integrated Product Development)作为一种先进的产品研发管理方法,通过其结构化的流程设计和跨部门协作机制,显著缩短了产品上市时间,提高了市场响应速度。本文将深入探讨如...
华为IPD流程   9  
  在项目管理领域,IPD(Integrated Product Development,集成产品开发)流程图是连接创意、设计与市场成功的桥梁。它不仅是一个视觉工具,更是一种战略思维方式的体现,帮助团队高效协同,确保产品按时、按质、按量推向市场。尽管IPD流程图可能初看之下显得错综复杂,但只需掌握几个关键点,你便能轻松驾驭...
IPD开发流程管理   8  
  在项目管理领域,集成产品开发(IPD)流程被视为提升产品上市速度、增强团队协作与创新能力的重要工具。然而,尽管IPD流程拥有诸多优势,其实施过程中仍可能遭遇多种挑战,导致项目失败。本文旨在深入探讨八个常见的IPD流程失败原因,并提出相应的解决方法,以帮助项目管理者规避风险,确保项目成功。缺乏明确的项目目标与战略对齐IP...
IPD流程图   8  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用