我试图在Bash脚本中划分两个图像宽度,但Bash给我0作为结果:

RESULT=$(($IMG_WIDTH/$IMG2_WIDTH))

我确实研究了Bash指南,我知道我应该使用bc,在互联网上的所有例子中,他们都使用bc。在echo中,我试图把同样的东西放在我的SCALE中,但它不起作用。

以下是我在教程中找到的例子:

echo "scale=2; ${userinput}" | bc 

我怎么能让巴斯给我0.5这样的浮点数呢?


当前回答

bash

正如其他人指出的那样,bash不支持浮点运算,尽管您可以使用一些固定的小数技巧来伪造它,例如使用两个小数:

echo $(( 100 * 1 / 3 )) | sed -e 's/..$/.&/;t' -e 's/.$/.0&/'

输出:

.33

请参阅Nilfred的回答,了解类似但更简洁的方法。

选择

除了提到的bc和awk的替代品,还有以下:

clisp

clisp -x '(/ 1.0 3)'

清理输出:

clisp --quiet -x '(/ 1.0 3)'

或者通过stdin:

echo '(/ 1.0 3)' | clisp --quiet | tail -n1

dc

echo 2k 1 3 /p | dc

天才cli计算器

echo 1/3.0 | genius

ghostscript

echo 1 3 div = | gs -dNODISPLAY -dQUIET | sed -n '1s/.*>//p' 

gnuplot

echo 'pr 1/3.' | gnuplot

Imagemagick

convert xc: -format '%[fx:1/3]' info:

或者通过stdin:

echo 1/3 | { convert xc: -format "%[fx:$(cat)]" info:; }

jq

jq -n 1/3

或者通过stdin:

echo 1/3 | jq -nf /dev/stdin

ksh

echo 'print $(( 1/3. ))' | ksh

lua

lua -e 'print(1/3)'

或者通过stdin:

echo 'print(1/3)' | lua

maxima

echo '1/3,numer;' | maxima

清理输出:

echo '1/3,numer;' | maxima --quiet | sed -En '2s/[^ ]+ [^ ]+ +//p'

node

echo 1/3 | node -p

倍频程

echo 1/3 | octave

perl

echo print 1/3 | perl

python2

echo print 1/3. | python2

python3

echo 'print(1/3)' | python3

R

echo 1/3 | R --no-save

清理输出:

echo 1/3 | R --vanilla --quiet | sed -n '2s/.* //p'

ruby

echo puts 1/3.0 | ruby

单位

units 1/3

输出紧凑:

units --com 1/3

水垢

echo 1/3 | wcalc

清理输出:

echo 1/3 | wcalc | tr -d ' ' | cut -d= -f2

zsh

print $(( 1/3. ))

或者通过stdin:

echo 'print $(( 1/3. ))' | zsh

其他来源

Stéphane Chazelas在UL上回答了类似的问题。

其他回答

现在是尝试zsh的最佳时机,它是一个(几乎)bash超集,具有许多其他不错的特性,包括浮点数学。下面是你的例子在zsh中的样子:

% IMG_WIDTH=1080
% IMG2_WIDTH=640
% result=$((IMG_WIDTH*1.0/IMG2_WIDTH))
% echo $result
1.6875

这篇文章可能会帮助你:bash -值得切换到zsh随意使用?

你可以这样做:

bc <<< 'scale=2; 100/3'
33.33

更新20130926:你可以使用:

bc -l <<< '100/3' # saves a few hits
33.33333333333333333333

bash

正如其他人指出的那样,bash不支持浮点运算,尽管您可以使用一些固定的小数技巧来伪造它,例如使用两个小数:

echo $(( 100 * 1 / 3 )) | sed -e 's/..$/.&/;t' -e 's/.$/.0&/'

输出:

.33

请参阅Nilfred的回答,了解类似但更简洁的方法。

选择

除了提到的bc和awk的替代品,还有以下:

clisp

clisp -x '(/ 1.0 3)'

清理输出:

clisp --quiet -x '(/ 1.0 3)'

或者通过stdin:

echo '(/ 1.0 3)' | clisp --quiet | tail -n1

dc

echo 2k 1 3 /p | dc

天才cli计算器

echo 1/3.0 | genius

ghostscript

echo 1 3 div = | gs -dNODISPLAY -dQUIET | sed -n '1s/.*>//p' 

gnuplot

echo 'pr 1/3.' | gnuplot

Imagemagick

convert xc: -format '%[fx:1/3]' info:

或者通过stdin:

echo 1/3 | { convert xc: -format "%[fx:$(cat)]" info:; }

jq

jq -n 1/3

或者通过stdin:

echo 1/3 | jq -nf /dev/stdin

ksh

echo 'print $(( 1/3. ))' | ksh

lua

lua -e 'print(1/3)'

或者通过stdin:

echo 'print(1/3)' | lua

maxima

echo '1/3,numer;' | maxima

清理输出:

echo '1/3,numer;' | maxima --quiet | sed -En '2s/[^ ]+ [^ ]+ +//p'

node

echo 1/3 | node -p

倍频程

echo 1/3 | octave

perl

echo print 1/3 | perl

python2

echo print 1/3. | python2

python3

echo 'print(1/3)' | python3

R

echo 1/3 | R --no-save

清理输出:

echo 1/3 | R --vanilla --quiet | sed -n '2s/.* //p'

ruby

echo puts 1/3.0 | ruby

单位

units 1/3

输出紧凑:

units --com 1/3

水垢

echo 1/3 | wcalc

清理输出:

echo 1/3 | wcalc | tr -d ' ' | cut -d= -f2

zsh

print $(( 1/3. ))

或者通过stdin:

echo 'print $(( 1/3. ))' | zsh

其他来源

Stéphane Chazelas在UL上回答了类似的问题。

它不是真正的浮点数,但如果你想在一次调用bc时设置多个结果…

source /dev/stdin <<<$(bc <<< '
d='$1'*3.1415926535897932384626433832795*2
print "d=",d,"\n"
a='$1'*'$1'*3.1415926535897932384626433832795
print "a=",a,"\n"
')

echo bc radius:$1 area:$a diameter:$d

计算半径为$1的圆的面积和直径

红利=除数×商+余数

我们来计算商和余数。 以及将这些字符串连接到一个变量中。

新方法只对log_decimal除数有效:

function main() {
  bar=10030
  divisor=100
  # divisor=50

  quotient=$((bar / divisor))
  # remainder=$((bar - v_int * divisor))
  remainder=$((bar % divisor))
  remainder_init=$remainder

  printf "%-15s --> %s\n" "quotient" "$quotient"
  printf "%-15s --> %s\n" "remainder" "$remainder"

  cnt=0
  while :; do
    remainder=$((remainder * 10))
    aux=$((remainder / divisor))
    printf "%-15s --> %s\n" "aux" "$aux"
    [[ aux -ne 0 ]] && break
    ((cnt += 1))
    printf "%-15s --> %s\n" "remainder" "$remainder"
  done
  printf "%-15s --> %s\n" "cnt" "$cnt"
  printf "%-15s --> %s\n" "aux" "$aux"

  printf $quotient
  printf "."
  for i in $(seq 1 $cnt); do printf "0"; done
  printf $remainder_init
}
clear
main

旧的错误方式:

bar=1234 \
&& divisor=1000 \
    && foo=$(printf "%s.%s" $(( bar / divisor )) $(( bar % divisor ))) \
    && printf "bar is %d miliseconds or %s seconds\n" $bar $foo

输出:bar为1234毫秒或1.234秒