Похожий, но более надежный вариант подхода @RubberStamp mail
, при котором мы отправляем электронное письмо в формате HTML внутри , чтобы почтовые клиенты отображали его как -в фиксированном -ширина шрифта (требуется GNU
recode
):
#! /bin/sh -
PATH=$PATH:/usr/sbin:/usr/lib # adding common locations of sendmail
export PATH
{
printf '%s\n' \
'To: email' \
'Subject: test' \
'MIME-Version: 1.0' \
'Content-Type: text/html' \
'' \
''
/path/to/executable-script/executable-script.sh status |
recode..html
printf '
\n'
} | sendmail -t -oi
Если recode
не установлен и не может быть установлен, а в вашей системе есть perl-модуль HTML::Entities
, вы можете заменить recode..html
на:
perl -Mopen=locale -MHTML::Entities -pe '$_=encode_entities$_'
16/9 не 1,778. Это (до 50 мест):
1.777777777777777777777777777777777777777777777777
И наоборот, 16,002/9 на самом деле равно 1,778.
Таким образом, на самом деле не существует возможного числа, которое точно равно 16/9 (по крайней мере, не по основанию 10 и с конечным числом цифр ).
Вам необходимо определить приемлемый уровень точности вашего приближения.
Мой первый алгоритм грубой -силы состоял бы в том, чтобы попробовать двойной цикл в A и B, вычислить A / B и остановиться, когда он будет точен до (, может быть, )6 цифр.
Сценарий оболочки:
#! /bin/bash
function Ratio {
AWK='
function Ratio (min, max, Local, a, b, q) {
for (a = 1; a < 1e6; a++) {
for (b = 1; b <= a; b++) {
q = (a / b);
if (min < q && q < max) {
printf ("Ratio %d / %d is %.12f\n", a, b, q);
return;
}
}
}
}
{ Ratio( $1, $2); }
'
awk "${AWK}"
}
{
echo 2.8897 2.8899
echo 1.77777777777 1.77777777778
echo 3.14159292 3.14159293
} | Ratio
А вот приложение:
paul $ time./Ratio
Ratio 341 / 118 is 2.889830508475
Ratio 16 / 9 is 1.777777777778
Ratio 355 / 113 is 3.141592920354
real 0m0.085s
user 0m0.072s
sys 0m0.012s
Очевидно, что если вы начинаете с 1,778 (> 1 ), то нет смысла проверять случаи, когда A <= B. Это говорит о том, что существует семейство приближений, основанных на непрерывных дробях. Итак, мой второй алгоритм — найти общий метод построения бесконечного ряда, сходящегося к заданному значению. Но только если мне приходилось иметь дело с серьезным количеством дел.
Педантично это или нет, если наш человек смотрит только на 3 десятичных знака с точностью....
Разбивая старый добрый awk
молоток для одинаково доброго старомодного наименьшего знаменателя, а не алгоритма с высоким фалутином, просто найдите наименьшую ошибку и знаменатель
echo "1.778" | awk 'BEGIN{en=1; de=101; er=1}{
for (d=100; d>=1; d--) {n=int(d*$1); e=n/d-$1; e=e*e;
if (e<=er && d<de){er=e; de=d; en=n}}
print en":"de, en/de}'
Итак...
16:9 1.77778
Нечто подобное можно было бы сделать и в чистом виде bash
с соответствующим множителем для дроби.
Если у нас гонка
real 0m0.004s
user 0m0.001s
sys 0m0.003s