2008-09-26, 12:49
  #1
Medlem
bc verkar vara skräp. "scale" avrundar inte vid division utan kapar endast siffrorna (wtf?). Det verkar inte gå att avrunda/kapa efter multiplikation. Jag hittar inget om hur man använder matte med awk. expr klarar inte decimaler. Så man kan inte räkna med decimaler i Bourne på ett korrekt sätt?

Jag vill kunna räkna ut en procentsats och avgöra hur många decimaler det ska ha.
Citera
2008-09-26, 13:11
  #2
Medlem
Citat:
Ursprungligen postat av Lanix
bc verkar vara skräp. "scale" avrundar inte vid division utan kapar endast siffrorna (wtf?). Det verkar inte gå att avrunda/kapa efter multiplikation. Jag hittar inget om hur man använder matte med awk. expr klarar inte decimaler. Så man kan inte räkna med decimaler i Bourne på ett korrekt sätt?

Jag vill kunna räkna ut en procentsats och avgöra hur många decimaler det ska ha.

finns en applikation som heter "calc" kort å gott som klarar av all sån matematik... decimaler i bash är lite bökigt annars.

bc går annars ganska bra att fixa med.
echo "3/2" | bc -l

Den kommer ge dig decimaler, men den kommer ge dig 20 decimaler... Det gör ju dock att man kanske får gör en lite meckig lösning :P typ som:
echo "3/2" |bc -l| sed -e "s/^\([0-9]*\).\([0-9]\{2\}\).*/\1.\2/"

När jag skriptar och fixar så använder jag normalt sett alltid calc... det är den som funkar bäst eftersom den även stödjer saker som roten ur och har fördefinerade konstanter för typ pi osv
Citera
2008-09-26, 13:14
  #3
Medlem
Citat:
Ursprungligen postat av _sajko
finns en applikation som heter "calc" kort å gott som klarar av all sån matematik... decimaler i bash är lite bökigt annars.

bc går annars ganska bra att fixa med.
echo "3/2" | bc -l

Den kommer ge dig decimaler, men den kommer ge dig 20 decimaler... Det gör ju dock att man kanske får gör en lite meckig lösning :P typ som:
echo "3/2" |bc -l| sed -e "s/^\([0-9]*\).\([0-9]\{2\}\).*/\1.\2/"

När jag skriptar och fixar så använder jag normalt sett alltid calc... det är den som funkar bäst eftersom den även stödjer saker som roten ur och har fördefinerade konstanter för typ pi osv

Man kan göra det lätt för sig också när jag tänker efter :P
echo "scale=2; 3/2" | bc

edit: ahh sry, missförstod det första du skriva att scale bara kapar bort siffror.
__________________
Senast redigerad av _sajko 2008-09-26 kl. 13:23.
Citera
2008-09-26, 13:37
  #4
Medlem
calc verkar inget standardprogram. Jag håller på med en uppgift som ska fungera utan extra program. Bourne ska klara köra det också, så inget Bash-specifikt.

Jo, som sagt vet jag hur scale fungerar men det är oanvändbart eftersom det kapar istället för att avrunda. Om man nu överser med det så går det inte få en procentsats med bestämt antal decimaler.

echo "scale=3;2/3*100" | bc -l
ger 66.600
Jag vill få det till 66.6%, 3.4% osv.

Vad jag vill ha är alltså en procentsats avrundat (inte kapat) till 1 decimal.
Ditt sed exempel förstår jag inte riktigt.
__________________
Senast redigerad av Lanix 2008-09-26 kl. 13:51.
Citera
2008-09-26, 14:32
  #5
Medlem
Citat:
Ursprungligen postat av Lanix
calc verkar inget standardprogram. Jag håller på med en uppgift som ska fungera utan extra program. Bourne ska klara köra det också, så inget Bash-specifikt.

Jo, som sagt vet jag hur scale fungerar men det är oanvändbart eftersom det kapar istället för att avrunda. Om man nu överser med det så går det inte få en procentsats med bestämt antal decimaler.

echo "scale=3;2/3*100" | bc -l
ger 66.600
Jag vill få det till 66.6%, 3.4% osv.

Vad jag vill ha är alltså en procentsats avrundat (inte kapat) till 1 decimal.
Ditt sed exempel förstår jag inte riktigt.

Mitt sed exempel är samma sak som att använda scale=, bara jag som är lite korkad och inte tänkte på scale= :P

Kod:
var=$(echo "scale=3; (2/3)*100" |bc -l|sed -e "s/\([0-9]\+\.[0-9]\).*$/\1/")
echo "$var%"
Ger nog ungefär resultatet du letar efter.
sed:en gör följande:
[0-9]\+\. letar efter 1 eller flera nummer mellan 0 till 9 fram tills den stöter på tecknet "."
[0-9] letar efter 1 nummer mellan 0-9
\( \) säger bara att buffra det som står emellan och skapa variabeln \1
.*$ är allt efter den första decimalen, för att du ska bli av med resten :P

Det är ju inte det bästa sättet att göra detta på antar jag, men det är det jag kom på lite snabbt... om du ska använda det för en one-liner eller i ett script som inte ska göra något avancerat eller särskilt ofta så är det nog ganska okey att använda den... men ska du ha något som rullar hela tiden så skulle jag nog försöka hitta nån annan lösning :P

Det inget av dessa gör är att runda talet... Bash är inte byggt för att hantera floating point beräkningar så dom flesta applikationerna runt det handskas inte särskilt bra med det heller... så jag tror du får leva med en 1/10's felmarginal. Om ingen annan har en helt brilliant lösning med builtin shell funktioner :P
Citera
2008-09-26, 14:54
  #6
Medlem
Kod:
printf "%.1f\n" `echo "scale=2;100*2/3" | bc`
fungerar ju, om nu printf räknas som standard. Annars lär väl awk avrunda som folk.
Citera
2008-09-26, 19:49
  #7
Medlem
Citat:
Ursprungligen postat av Lanix
bc verkar vara skräp. "scale" avrundar inte vid division utan kapar endast siffrorna (wtf?). Det verkar inte gå att avrunda/kapa efter multiplikation. Jag hittar inget om hur man använder matte med awk. expr klarar inte decimaler. Så man kan inte räkna med decimaler i Bourne på ett korrekt sätt?

Jag vill kunna räkna ut en procentsats och avgöra hur många decimaler det ska ha.
Är det verkligen så svårt att skala upp till ett heltal och sedan lägga till 5 så att en simpel kapning (vid tillbakaskalningen) blir en korrekt avrundning?
Kod:
a=2
b=3

c=`expr 10000 \* $a / $b + 5`

echo `expr $c / 100`.`expr $c / 10 % 10`%
Men vill man kunna justera antalet decimaler på ett enkelt sätt blir det smidigare att göra motsvarande beräkning i t.ex. dc istället:
Kod:
t=2 # täljare
n=3 # nämnare
d=1 # antal decimaler

echo `echo "10 $d dk1+^ds 100*$t*$n/5+l /p" | dc`%
Citera

Skapa ett konto eller logga in för att kommentera

Du måste vara medlem för att kunna kommentera

Skapa ett konto

Det är enkelt att registrera ett nytt konto

Bli medlem

Logga in

Har du redan ett konto? Logga in här

Logga in