bash calc 返回 800(应该是 600): echo "$(( 800 / (4 / 3) ))"

Min*_*int 11 shell bash shell-script arithmetic

我正在根据数字计算长宽比高度x,在这个例子中我使用 4:3 的比例,宽度为 800,结果(高度)应该是 600,但 bash 返回 800,我不知道为什么。

我尝试过其他语言,大多数似乎也有问题,php 似乎是少数可以工作的语言之一。

PHP(返回 600)

php -r 'echo 800/(4/3);'
Run Code Online (Sandbox Code Playgroud)

Python(返回 800)

python -c "print(800/(4/3))"
Run Code Online (Sandbox Code Playgroud)

bc -l有点有效(返回 600.00000000000000000150)

-l是“定义标准数学库”,不确定这意味着什么,但它似乎让我更接近我的目标,但是额外的 0 和 150 来自哪里?

echo '800 / (4 / 3)' | bc -l
Run Code Online (Sandbox Code Playgroud)

我猜这与浮点处理或截断3/4.

现在我可以使用php, 就到此为止了,但对于相对简单的计算来说似乎有点矫枉过正。知道这里发生了什么吗?

Ste*_*ris 56

Bash 算术仅是整数。所以 4/3 返回 1。800/1 就是 800。

如果您可以控制输入,那么您可以重构并在除法之前进行乘法

$ echo $(( 800*3/4 ))
600
Run Code Online (Sandbox Code Playgroud)

你的其他例子也是“整数”。例如,如果您通过替换来强制 python 浮点4,那么4.0您会得到不同的答案(Python 3 不需要这个)

$ python -c "print(800/(4.0/3))"
600.0
Run Code Online (Sandbox Code Playgroud)

bc -l加载标准数学库(带有诸如s()正弦、l()自然对数等函数),但更重要的是,这里设置scale为 20。scale定义在除法中生成基数后有多少位小数,因此4/3将会有1.33333333333333333333(实际上133333333333333333333/1e+20),并且这解释了为什么你会得到600.00000000000000000150.

echo 'scale=1000; 800/(4/3)' | bc
Run Code Online (Sandbox Code Playgroud)

将为您提供更高的精度(无需加载数学库),但您永远无法达到目标,600因为4/3无法以十进制表示。

  • @Mint 800*3/4 首先计算 800*3,然后将其除以 4。 (9认同)
  • 如果没有任何 (...) 它将执行标准的从左到右评估;所以800*3=2400;2400/4=600。相比之下,800*(3/4) 将返回 0,因为 3/4 将为 0,而 800*0 为 0。 (4认同)
  • @Mint 不要忘记计算机数学并不总是与真实数学相同。请参阅 https://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html 和 /sf/ask/41160311/ (3认同)
  • 如果一个***真的***想要在bash中使用浮点数,可以使用带指数/电子符号的“printf”,例如如果一个人想要“9 / 4”,则可以使用“printf”%f\ n'“$(( 9 * 100 / 4 ))e-2”`:P, (2认同)