【问题标题】:How do I perform this calculation and output it to standard out?如何执行此计算并将其输出到标准输出?
【发布时间】:2018-04-25 00:17:18
【问题描述】:

我正在尝试在 Bash 中执行此操作:

read n

echo int(math.ceil((math.sqrt(1 + 8 * n) - 1) / 2))

当然,这不是有效的语法,但我只是把它放在那里,这样你就可以知道我在做什么。

有没有一种简单的方法可以把它变成有效的 Bash?

【问题讨论】:

  • bash 中肯定没有 sqrt 运算符。
  • 我必须自己写sqrt函数吗?
  • 不确定是否有帮助,但由于(8n + 1) 是奇数,那么如果sqrt(8n + 1) 是整数值,它也一定是奇数。因此,减去(1) 并除以(2) 将始终是整数。所以如果(n)对于任何整数(k)可以表示为k(k + 1)/2,那么结果就是一个整数。否则,在整数部分加一。
  • @BrettHale 是的,绝对是一种解决方法;想概括一下,如果我想在未来计算 sqrt,我就可以
  • 我的评论并没有真正帮助,因为发现 (k) 值与您原来的问题基本相同!

标签: bash math syntax echo stdout


【解决方案1】:

尽管您要求在 Bash 中执行此操作,但对平方根或天花板等函数没有原生支持。委托给 Perl 会更简单:

perl -wmPOSIX -e "print POSIX::ceil((sqrt(1 + 8 * $n) - 1) / 2)"

或者,您可以使用bc 来计算平方根,并使用一些 Bash 来计算上限。

让我们定义一个函数,用sqrt of bc 打印公式的结果:

formula() {
    local n=$1
    bc -l <<< "(sqrt(1 + 8 * $n) - 1) / 2"
}

-l 标志将scale 从默认的 0 更改为 20。 这会影响浮点结果的显示比例。 例如,使用默认零,10 / 3 将只打印 3。 下一步我们需要浮点细节来计算上限。

ceil() {
    local n=$1
    local intpart=${n%%.*}
    if [[ $n =~ \.00*$ ]]; then
        echo $intpart
    else
        echo $((intpart + 1))
    fi
}

这里的想法是提取整数部分, 如果小数部分全为零,那么我们只打印整数部分, 否则整数部分 + 1,因为那是上限。

以及最后一个简单的函数,结合以上函数得到你想要的结果:

compute() {
    local n=$1
    ceil $(formula $n)
}

还有一个检查器功能来测试它:

check() {
    local n num
    for n; do
        num=$(formula $n)
        echo $n $num $(compute $n)
    done
}

让我们试试吧:

check 1 2 3 4 7 11 12 16 17

它产生:

1 1.00000000000000000000 1
2 1.56155281280883027491 2
3 2.00000000000000000000 2
4 2.37228132326901432992 3
7 3.27491721763537484861 4
11 4.21699056602830190566 5
12 4.42442890089805236087 5
16 5.17890834580027361089 6
17 5.35234995535981255455 6

【讨论】:

    【解决方案2】:

    你可以使用bcsqrt函数。

    echo "(sqrt(1 + 8 * 3) - 1) / 2" | bc
    

    Ceil 函数可以使用此答案中描述的任何方法来实现。

    Getting Ceil integer

    例如:

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

    【讨论】:

    • 如果我正确地实现了你写的内容,你的公式对于 n 的值(如 4、7、11、12、16、17...
    【解决方案3】:

    您可以将 bc 用于所有工作

    $>cat filebc
    
    print "Enter a number\n";
    scale=20
    a=read()
    b=((sqrt(1 + 8 * a) - 1) / 2)
    scale=0
    print "ceil = ";
    ((b/1)+((b%1)>0))
    quit
    

    这样称呼

    bc -q filebc
    

    【讨论】:

      猜你喜欢
      • 2022-11-04
      • 1970-01-01
      • 2014-05-06
      • 1970-01-01
      • 1970-01-01
      • 2019-12-18
      • 1970-01-01
      • 2013-05-01
      • 1970-01-01
      相关资源
      最近更新 更多