Подраздел в script и с плавающей запятой

Я хотел бы сделать следующую операцию в моем script:

1 - ((m - 20) / 34)

Я хотел бы присвоить результат этой операции другой переменной. Я хочу, чтобы мой script использовал математику с плавающей запятой. Например, для m = 34:

results = 1 - ((34 - 20) / 34) == 0.588

Ответ 1

Вы можете использовать калькулятор bc. Он будет выполнять произвольную математику точности с использованием десятичных знаков (не двоичной с плавающей запятой), если вы установите значение increease scale по умолчанию 0:

$ m=34
$ bc <<< "scale = 10; 1 - (($m - 20) / 34)"
.5882352942

Параметр -l загрузит стандартную математическую библиотеку и по умолчанию будет масштабироваться до 20:

$ bc -l <<< "1 - (($m - 20) / 34)"
.58823529411764705883

Затем вы можете использовать printf для форматирования вывода, если вы так решите:

printf "%.3f\n" "$(bc -l ...)"

Ответ 2

Bash не выполняет математику с плавающей запятой. Вы можете использовать awk или bc, чтобы справиться с этим. Вот пример awk:

$ m=34; awk -v m=$m 'BEGIN { print 1 - ((m - 20) / 34) }'
0.588235

Назначение вывода переменной:

var=$(awk -v m=$m 'BEGIN { print 1 - ((m - 20) / 34) }')

Ответ 3

Учить bash, например. целочисленное деление с результатами с плавающей запятой:

#!/bin/bash

div ()  # Arguments: dividend and divisor
{
        if [ $2 -eq 0 ]; then echo division by 0; exit; fi
        local p=12                            # precision
        local c=${c:-0}                       # precision counter
        local d=.                             # decimal separator
        local r=$(($1/$2)); echo -n $r        # result of division
        local m=$(($r*$2))
        [ $c -eq 0 ] && [ $m -ne $1 ] && echo -n $d
        [ $1 -eq $m ] || [ $c -eq $p ] && return
        local e=$(($1-$m))
        let c=c+1
        div $(($e*10)) $2
}  

    result=$(div 1080 633)                  # write to variable
    echo $result

    result=$(div 7 34)
    echo $result

    result=$(div 8 32)
    echo $result

    result=$(div 246891510 2)
    echo $result

    result=$(div 5000000 177)
    echo $result

Вывод:

    1.706161137440
    0.205882352941
    0.25
    123445755
    28248.587570621468

Ответ 4

echo $a/$b|bc -l

дает результат.

Пример:

read a b
echo $a/$b|bc -l

Введите значение a и b как 10 3, вы получите 3.3333333333

Если вы хотите сохранить значение в другой переменной, используйте код

read a b
c=`echo $a/$b|bc -l`
echo $c

Он также дает тот же результат, что и выше. Попробуйте...

Ответ 5

Я знаю, что это старый поток, но это казалось забавным проектом для решения без использования bc или вызова рекурсии. Я уверен, что его можно улучшить, но это укрепило мое мастерство.

numerator=5
denominator=7 # - 0 -> returns "undef"
decimal_places=4 # - 0 -> same as echo $(( $numerator / $denominator ))
_result_sign=""
let _dp_exp=10**decimal_places
if [ $denominator -eq 0 ]; then _div_result_int_large=0; else let _div_result_int_large=$((numerator * _dp_exp / denominator)); fi
if [ $_div_result_int_large -lt 0 ]; then let _div_result_int_large=$(( _div_result_int_large * -1 )); _result_sign="-"; fi
let _div_result_int=$((_div_result_int_large / _dp_exp))
let _div_result_mant=$((_div_result_int_large - _div_result_int * _dp_exp))
let _dp_lzeros=$((decimal_places - ${#_div_result_mant}))
printf -v _div_result_mant_padded "%.${_dp_lzeros}d$_div_result_mant"
div_result="$_result_sign$_div_result_int"
if [ $decimal_places -gt 0 ]; then div_result="$_result_sign$_div_result_int.$_div_result_mant_padded"; fi
if [ $denominator -eq 0 ]; then div_result="undef"; fi
echo $div_result

Пример вывода:

numerator=5
denominator=7
decimal_places=5
-> 0.71428

numerator=250
denominator=13
decimal_places=0
-> 19

numerator=-5
denominator=6
decimal_places=2
-> -0.83

numerator=3
denominator=0 # - uh-oh
decimal_places=2 # - can be anything, in this case
-> undef

Ответ 6

Используйте этот script, чтобы открыть этот файл с любимым редактором, например:

$ sudo vim /usr/bin/div

Затем вставьте этот код:

#!/bin/bash
# Author: Danial Rikhteh Garan ([email protected])

if [[ -z "$1" ]] || [[ -z "$2" ]]; then
    echo "Please input two number"
    echo "for 100/50 use: div 10 50"
    exit 1;
fi

div=$(echo "$1/$2" | bc -l);
echo 0$div | sed 's/[0]*$//g'

Теперь chmod до 755:

$ sudo chmod 755 /usr/bin/div

Теперь используйте его:

$ div 5 100
0.05

В script вы можете использовать это:

var=$(div 5 100);
echo "$var"