echo -n "ШЛЕП! " # попадание в озеро
((splashes++))
else
echo -n "БУХ! " # попадание на твердую почву
((thuds++))
fi
Pi=$(echo "scale=9; $PMULTIPLIER*$splashes/$shots" | bc)
# Умножение на коэффициент 4.0.
echo -n "PI ~ $Pi"
echo
done
echo
echo "После $shots выстрела, примерное значение числа \"пи\" равно $Pi."
# Имеет тенденцию к завышению...
# Вероятно из-за ошибок округления и несовершенства генератора случайных чисел.
echo
# }
exit 0
# Самое время задуматься над тем, является ли сценарий удобным средством
#+ для выполнения большого количества столь сложных вычислений.
#
# Тем не менее, этот пример может расцениваться как
# 1) Доказательство возможностей языка командной оболочки.
# 2) Прототип для "обкатки" алгоритма перед тем как перенести
#+ его на высокоуровневые языки программирования компилирующего типа.
dc
Утилита dc (desk calculator) -- это калькулятор, использующий "Обратную Польскую Нотацию", и ориентированный на работу со стеком.
Многие стараются избегать испоьзования dc, из-за непривычной формы записи операндов и операций. Однако, dc имеет и своих сторонников.
Пример 12-36. Преобразование чисел из десятичной в шестнадцатиричную систему счисления
#!/bin/bash
# hexconvert.sh: Преобразование чисел из десятичной в шестнадцатиричную систему счисления.
BASE=16 # Шестнадцатиричная.
if [ -z "$1" ]
then
echo "Порядок использования: $0 number"
exit $E_NOARGS
# Необходим аргумент командной строки.
fi
# Упражнение: добавьте проверку корректности аргумента.
hexcvt ()
{
if [ -z "$1" ]
then
echo 0
return # "Return" 0, если функции не был передан аргумент.
fi
echo ""$1" "$BASE" o p" | dc
# "o" устанавливает основание системы счисления для вывода.
# "p" выводит число, находящееся на вершине стека.
# См. 'man dc'.
return
}
hexcvt "$1"
exit 0
Изучение страниц info dc позволит детальнее разобраться с утилитой. Однако, отряд "гуру", которые могут похвастать своим знанием этой мощной, но весьма запутанной утилиты, весьма немногочислен.
Пример 12-37. Разложение числа на простые множители
#!/bin/bash
# factr.sh: Разложение числа на простые множители
MIN=2 # Не работает с числами меньше 2.
E_NOARGS=65
E_TOOSMALL=66
if [ -z $1 ]
then
echo "Порядок использования: $0 number"
exit $E_NOARGS
fi
if [ "$1" -lt "$MIN" ]
then
echo "Исходное число должно быть больше или равно $MIN."
exit $E_TOOSMALL
fi
# Упражнение: Добавьте проверку типа числа (не целые числа должны отвергаться).
echo "Простые множители для числа $1:"
# ---------------------------------------------------------------------------------
echo "$1[p]s2[lip/dli%0=1dvsr]s12sid2%0=13sidvsr[dli%0=1lrli2+dsi!>.]ds.xd1<2" | dc
# ---------------------------------------------------------------------------------