Большой Воронежский Форум
» UNIX и дериваты>Округление вещественных чисел в bash?
Hip-Hop 22:40 12.11.2011
Есть такой фокус - printf "=%1.0f" $a; echo , но оно округляет до чётного числа.

То-есть, если нужно округлить 1.5, то округляется до 2, а если 2.5 - округлятся до 2, а должно до трёх? Какие есть идеи? [Ответ]
Катя. 22:51 12.11.2011
Hip-Hop, взять ответ и добавить к нему разницу между округлением от оригинала и оригинала увеличенного на 1 деленную на 2.

мое решение работает только если он все числа округляет до четных, а он мудрит только с x.5 [Ответ]
Hip-Hop 23:16 12.11.2011

Сообщение от Катя.:
Hip-Hop, взять ответ и добавить к нему разницу между округлением от оригинала и оригинала увеличенного на 1 деленную на 2.

Ну, да, а числа в цикле округляются и мне нужно получается проверять их на принадлежность к x.5 ?

А из коробки как? [Ответ]
Hip-Hop 23:31 12.11.2011
Катя., То-есть, вот как. Я беру вывод df -hP - и выниманию нужную колонку с занятым местом, должно как-то так size=`df -hP | awk '{print $4}' | sed 's/.$//'`Я хочу округлить это число (если надо), потом я сравниваю с lim и добавляю места с lvm + ресайз fs. Но что-то хочется из коробки округление. Может как-то через bc можно Катя.? [Ответ]
dm.tsvetkov 20:02 13.11.2011

Сообщение от Hip-Hop:
о-есть, если нужно округлить 1.5, то округляется до 2, а если 2.5 - округлятся до 2, а должно до трёх? Какие есть идеи?

использовать нормальные инструменты, написанные людьми, способными усвоить программу начальной школы? [Ответ]
silly 21:03 13.11.2011

Сообщение от dm.tsvetkov:
использовать нормальные инструменты, написанные людьми, способными усвоить программу начальной школы?

Вы зря иронизируете, округление, как и все операции с вещественными числами, простым не бывает.

Сообщение от Hip-Hop:
То-есть, если нужно округлить 1.5, то округляется до 2, а если 2.5 - округлятся до 2, а должно до трёх? Какие есть идеи?

Никто никому ничего не должен. Есть несколько равноправных способов округления. [Ответ]
Hip-Hop 21:45 13.11.2011

Сообщение от silly:
Никто никому ничего не должен. Есть несколько равноправных способов округления.

Да, это называется "беспристрастное" округление. (до чётного). Мне нужно "пристрастное". [Ответ]
silly 22:01 13.11.2011
Что-то вроде

Код:
echo '10.5' | awk '{ split($0, n, "."); print n[1] + (substr(n[2], 1, 1) >= 5 ? 1 : 0) }'
Но вообще, имхо, ключ h в команде df нужно заменить на ключ B, а результаты обрабатывать адекватными средствами написания скриптов, вроде python'а. [Ответ]
Hip-Hop 22:16 13.11.2011
silly, да. [Ответ]
Hip-Hop 22:17 13.11.2011

Сообщение от silly:
Но вообще, имхо, ключ h в команде df нужно заменить на ключ B, а результаты обрабатывать адекватными средствами написания скриптов, вроде python'а

Да, этот вариант рассматривался. [Ответ]
Hip-Hop 22:30 13.11.2011

Сообщение от Катя.:
мое решение работает только если он все числа округляет до четных, а он мудрит только с x.5

Почему? a=2.5, надо округлить до 3. По твоему - 2 + (2-1) = 3!

2.5+1 = 3.5 = 4\2 = 2

Imho, это всегда работает.


Ерунда получается.
[Ответ]
dm.tsvetkov 08:24 14.11.2011

Сообщение от silly:
Вы зря иронизируете, округление, как и все операции с вещественными числами, простым не бывает.

я иронизирую только по одному поводу - я не уверен, что округление это самоцель.
скорее всего, это всего лишь часть какой-либо задачи.
и что-то мне подсказывает, что человечество с этой задачей
1) сталкивалось.
2) решило ее.

а тут мы имеем игру в бисер. размышления ради размышлений.
[Ответ]
Hip-Hop 12:04 14.11.2011
dm.tsvetkov, а вот так без awk можно Код кривой, но понятный, imho.


Код:
 round()
{
let  sum="$1+5"       # является ли число целым? :)
if [ $? = 1 ]                #
then        
echo $1
else
b=`echo $1 | sed 's/[^,]*\,//'`  # берем дробную часть от $1, позиционная переменная - $1
if [ "$b" -ge 5 ]                           # если она >= 5
then                                          
b=`echo $1 | sed 's/[$,].//'`# отбрасываем дробную часть от $1
let "b % 2"
if [ $? = 1 ]                       # если целая часть чётная
then
let "b=b+1"                       # увеличиваем $b на 1
echo $b
else                                  # иначе используем printf :)
printf "%.0f" $1; echo
fi
else
printf "%.0f" $1; echo
fi
fi
}
[Ответ]
Spectator 13:00 14.11.2011
+0.5 не спасет отца русской демократии? если я правильно понял проблему, и с учетом того что в bash'е я не особо соображаю.
В C это делается примерно так:
float f = 0.3f;
int a = (int)(f+0.51f);//Это будет 0
f = 0.7f;
a = (int)(f+0.51f);//Это будет 1 [Ответ]
Hip-Hop 13:11 14.11.2011

Сообщение от Spectator:
+0.5 не спасет отца русской демократии?

Spectator, а баш умеет работать только с целыми числами? [Ответ]
Hip-Hop 14:05 14.11.2011
Вот так получается почти законченно.

Код:
round()
{
let  sum="$1+5"
if [ $? = 1 ]
then
echo $1
else
b=`echo $1 | sed 's/[^,]*\,//'` # берем дробную часть от $1, позиционная переменная - $1
if [ "$b" -ge 5 ]               # если она >= 5
then                            # отбрасываем дробную часть от $a
b=`echo $1 | sed 's/[$,].//'`
let "b % 2"
if [ $? = 1 ]                    # если целая часть чётная
then
let "b=b+1"                       # увеличиваем $b на 1
echo $b
else                                  # иначе используем printf :)
printf "%.0f" $1; echo
fi
else
printf "%.0f" $1; echo
fi
fi
}

lim=5
fs="backup sda6"
for i in $fs
do
size=`df -hP | grep $i | awk '{print $4}' | sed 's/.$//'`
round $size
#if ["$size" -lt "$lim"]
#then
#lvextend -L+10G $lvm
#resize_reiserfs -f $lvm
#else
#echo $size
done
Сделать проверку типа fs и соответственное увеличение. [Ответ]
Hip-Hop 14:29 14.11.2011
dm.tsvetkov, Кстати, советую перенести на своем media-server rootfs на lvm. Потом очень удобно делать backup'ы - затарировать или dd снопшоты. Да, я почти везде использую reiserfs и reiserfs4, для reiserfs4 нужно патчить ядро. Поддержки в ядре нету. Рейдер убил свою жену и gnu не хочет включать его программу в состав ядра,dm.tsvetkov. Однако, reiserfs остается быть одной из лучших файловых систем доступных в linux. (самой лучшей ) [Ответ]
dm.tsvetkov 16:14 14.11.2011

Сообщение от Hip-Hop:
Рейдер убил свою жену и gnu не хочет включать его программу в состав ядра,dm.tsvetkov

слышал-слышал. очередной колхозный маразм. [Ответ]
Вверх