bc: ustaw liczbę cyfr po przecinku


52

bc obsługuje liczby jako liczby całkowite:

# echo "100/3" | bc
33

bc -l obsługuje liczby jako obiekty zmiennoprzecinkowe:

# echo "100/3" | bc -l
33.33333333333333333333

Czy istnieje sposób na ograniczenie liczby cyfr po przecinku?


10
Co ciekawe, działa to tylko z podziałem. Jeśli chcesz to zrobić scale=0;1234*1.1, musisz napisać, jak scale=0;1234*1.1/1zdobyć 1357. W przeciwnym razie, bez względu na wartość scale, otrzymasz 1357.4.
Wok

Czy komentarz @ Wok ​​nie powinien być odpowiedzią na zaakceptowaną odpowiedź, a nie na pytanie? Dopóki nie przeczytam odpowiedzi, nie miałem pojęcia, do czego odnosi się ten komentarz.
Wilson F

1
@WilsonF Dodano odniesienie do odpowiedzi.
Adam Matan

2
@ Wok, to nie zależy od dzielenia lub mnożenia. To zależy od danych wejściowych - największa liczba dokładności określa dokładność na wyjściu. Zauważ, jak ci 1234*1.0to da1234.0
Richlv,

Odpowiedzi:


70

Ustaw scalespecjalną zmienną:

$ echo "scale=2; 100/3" | bc
33.33

3
Zobacz komentarz @ Woka do pytania.
Adam Matan

$ echo "scale=2; (100/180)*180" | bcdaje 99,00 :(
Donatas Olsevičius

@ DonatasOlsevičius dzieje się tak, ponieważ (100/180) = 0,55, a następnie (0,55 * 180) = 99. To daje odpowiednią wartość :)
Kamaldeep singh Bhatia

Byłoby miło, gdyby zaokrąglono w górę, jeśli powyżej .5. ~$ echo "scale=2; 12/104" | bc .11 W przypadku zaokrąglenia w górę byłoby to .12. Jednak nadal powinno to spełniać moje zadanie.
jbrock

3
Można zachować precyzję aż drukowanie wartości w następujący sposób: echo "result = (100/180) * 180; scale=2; result / 1" | bc -l. Teraz masz 99.99.
Byron Hawkins,

10

scaledziała tylko dla podziału; jeśli niektórzy maniacy potrzebują tego w rozmnażaniu, możesz to zrobić za pomocą manipulacji ciągami. Powiedz, jeśli potrzebujesz pomnożyć 32 * 0.60, odpowiedź brzmi 19.20. Jeśli chcesz uzyskać odpowiedź w pojedynkę, możesz to zrobić różnymi metodami.

  1. Używanie manipulacji ciągami

    $ S=$(echo "32*.60" | bc ) ; echo ${S%.*}
    19
    

    Składnia manipulacji ciągiem: ${Variable%pattern}spowoduje to usunięcie krótkiego pasującego wzorca, który nastąpi po %. Więcej informacji na temat manipulacji ciągami znajduje się w przewodniku Advanced Bash-Scripting .

  2. Używanie Scalejak stwierdzono przez**chronitis**

    $ echo "scale=0; 32*60/100" | bc
    19
    
  3. Aby pozbyć się ostatnich zer, zamiast manipulacji ciągiem, można również podzielić przez 1.

    $ echo "0.232 * 1000" | bc
    232.000
    
    $ echo "0.232 * 1000 / 1" | bc
    232
    

Zauważ, że jak wspomniałem w moim komentarzu do pytania, nie jest to spowodowane mnożeniem, ale raczej liczbami wejściowymi mającymi część dziesiętną. Lub, inaczej mówiąc, liczba z „najdłuższą” częścią dziesiętną określa, ile miejsc dziesiętnych będzie miało wynik.
Richlv,

4

Oprócz poprzednich odpowiedzi

echo "scale=2; 1.0150876" | bc

Zwroty

1.0150876

Dodaj operacje matematyczne, aby uzyskać tylko 2 liczby dziesiętne - (NUMER * 100) / 100

echo "scale=2; (1.0150876 * 100) / 100" | bc

Teraz wraca

1.01

3

możesz także użyć polecenia printf, aby zaokrąglić wynik do 3 miejsc po przecinku

# printf "%.3f\n" $(echo "100/3" | bc -l)
3.333

2

Zaokrąglenie

Skala = 2 obcina odpowiedź na dwie cyfry dziesiętne, ale możemy zaokrąglić w następujący sposób:

$ echo "a=12/104; scale=2; (a+0.005)/1" | bc -l
.12
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.