在 Bash 中对被除数进行四舍五入

2024-10-29 08:34:00
admin
原创
44
摘要:问题描述:我该如何对两个数相除的结果进行舍入,例如3/2 就像我做的那样testOne=$((3/2)) $testOne 包含“1”,但它应该四舍五入为“2”,因为 3/2=1.5 的答案是解决方案 1:要在截断算术中进行四舍五入,只需将其添加(denom-1)到分子即可。例如,向下舍入:N/2 M/5 K...

问题描述:

我该如何对两个数相除的结果进行舍入,例如

3/2

就像我做的那样

testOne=$((3/2))

$testOne 包含“1”,但它应该四舍五入为“2”,因为 3/2=1.5 的答案是


解决方案 1:

要在截断算术中进行四舍五入,只需将其添加(denom-1)到分子即可。

例如,向下舍入:

N/2
M/5
K/16

例如,四舍五入:

(N+1)/2
(M+4)/5
(K+15)/16

要进行四舍五入,请添加(denom/2)到分子(一半将向上舍入):

(N+1)/2
(M+2)/5
(K+8)/16

解决方案 2:

好的解决方案是获取最近的整数

var=2.5
echo $var | awk '{print int($1+0.5)}'

逻辑很简单,如果 var 十进制值小于 .5,则取最接近的值为整数值。如果十进制值大于 .5,则添加下一个整数值,因为 awk 只取整数部分。问题解决了

解决方案 3:

bash 不会给出正确的结果 3/2,因为它不进行浮点运算。你可以使用 awk 之类的工具

$ awk  'BEGIN { rounded = sprintf("%.0f", 3/2); print rounded }'
2

或 bc

$ printf "%.0f" $(echo "scale=2;3/2" | bc)
2

解决方案 4:

如果对正数进行整数除法并将其四舍五入为零,则可以将除数减一添加到被除数上以使其向上舍入。

也就是说,X / Y用替换(X + Y - 1) / Y

证明:

  • 情况 1:X = k * Y(X 是 Y 的整数倍):在这种情况下,我们有(k * Y + Y - 1) / Y,它分解为(k * Y) / Y + (Y - 1) / Y(Y - 1)/Y部分四舍五入为零,我们得到 的商k这正是我们想要的:当输入可整除时,我们希望调整后的计算仍然产生正确的精确商。

  • 情况 2:X = k * Y + m其中0 < m < Y(X 不是 Y 的倍数)。在这种情况下,我们的分子为k * Y + m + Y - 1,或k * Y + Y + m - 1,我们可以将除法写为(k * Y)/Y + Y/Y + (m - 1)/Y。由于0 < m < Y0 <= m - 1 < Y - 1,因此最后一项(m - 1)/Y趋于零。我们剩下的是(k * Y)/Y + Y/Y,其结果为k + 1。这表明该行为向上舍入。如果我们有一个 ,X它是k的倍数Y,如果我们只向其添加 1,则除法将向上舍入为k + 1

但这种舍入方式恰恰相反;所有不精确的除法都会偏离零。介于两者之间的数字呢?

这可以通过用 来“启动”分子来实现Y/2。 而不是X/Y,计算(X+Y/2)/Y。 我们不去证明,而是用经验来说明这一点:

$ round()
> {
>   echo $((($1 + $2/2) / $2))
> }
$ round 4 10
0
$ round 5 10
1
$ round 6 10
1
$ round 9 10
1
$ round 10 10
1
$ round 14 10
1
$ round 15 10
2

每当除数为偶数正数时,如果分子等于该数的一半,则向上舍入,如果分子小于该数,则向下舍入。

例如,round 6 12趋向于1,所有等于 的值也一样6,模12,像18(趋向于 2)等等。 round 5 12趋向于0

对于奇数,此行为是正确的。没有一个精确的有理数位于两个连续倍数的中间。例如,对于分母为,11我们有5/11 < 5.5/11 (exact middle) < 6/11;并且round 5 11向下舍入,而round 6 11向上舍入。

解决方案 5:

要进行四舍五入,您可以使用模数。

如果有余数,等式的第二部分将加为 True。(True = 1;False = 0)

例如:3/2

answer=$(((3 / 2) + (3 % 2 > 0)))
echo $answer
2

例如:100 / 2

answer=$(((100 / 2) + (100 % 2 > 0)))
echo $answer
50

例如:100 / 3

answer=$(((100 / 3) + (100 % 3 > 0)))
echo $answer
34

解决方案 6:

给定一个浮点值,我们可以使用以下方法简单地对其进行舍入printf

# round $1 to $2 decimal places
round() {
    printf "%.${2:-0}f" "$1"
}

然后,

# do some math, bc style
math() {
    echo "$*" | bc -l
}

$ echo "Pi, to five decimal places, is $(round $(math "4*a(1)") 5)"
Pi, to five decimal places, is 3.14159

或者,使用原始请求:

$ echo "3/2, rounded to the nearest integer, is $(round $(math "3/2") 0)"
3/2, rounded to the nearest integer, is 2

解决方案 7:

如果小数分隔符是逗号(例如:LC_NUMERIC=fr_FR.UTF-8,请参见此处):

$ printf "%.0f" $(echo "scale=2;3/2" | bc) 
bash: printf: 1.50: nombre non valable
0

ghostdog74 解决方案需要替换:

$ printf "%.0f" $(echo "scale=2;3/2" | bc | sed 's/[.]/,/')
2

或者

$ printf "%.0f" $(echo "scale=2;3/2" | bc | tr '.' ',')
2

解决方案 8:

另一个解决方案是在 Python 命令中执行除法。例如:

$ numerator=90
$ denominator=7
$ python -c "print (round(${numerator}.0 / ${denominator}.0))"

对我来说这比使用 awk 更不古老。

解决方案 9:

我想这就足够了。

$ echo "3/2" | bc 

解决方案 10:

你可以使用这个函数r(x, p)

通过命令的手册页bc

r(x, p)

       : Returns x rounded to p decimal places

这是一个例子。

#!/bin/bash
read expression
echo "r($expression,3)" | bc -l

执行脚本的结果5+50*3/20 + (19*2)/717.929

注意:r(x, p)在扩展库中实现,为了使用它,您应该使用 -l 或 --mathlib 标志:

All of the functions below, including the functions in the extended
   math library (see the Extended Library subsection below), are available
   when the -l or --mathlib command-line flags are given, except that the
   extended math library is not available when the -s option, the -w
   option, or equivalents are given.

解决方案 11:

以下对我有用。

 #!/bin/bash
function float() {
bc << EOF
num = $1;
base = num / 1;
if (((num - base) * 10) > 1 )
    base += 1;
print base;
EOF
echo ""
}

float 3.2
相关推荐
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   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源码管理

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

免费试用