Czy to właściwy sposób na konwersję typu float to integer w bash? Czy jest jakaś inna metoda?
flotToint() {
printf "%.0f\n" "$@"
}
bash
floating-point
Rahul Patil
źródło
źródło
%.0f
zaokrągli w górę lub w dół. Czy tego chcesz? Możesz użyćprintf "%d\n" "$@" 2>/dev/null
do posiekania frakcji.Odpowiedzi:
grzmotnąć
W
bash
, to prawdopodobnie tak dobre, jak to możliwe. To używa wbudowanej powłoki. Jeśli potrzebujesz wyniku w zmiennej, możesz użyć podstawienia polecenia lubbash
konkretnego (choć teraz również obsługiwanego przezzsh
):Mógłbyś:
Ale to usunęłoby część ułamkową zamiast podać najbliższą liczbę całkowitą i nie działałoby to dla wartości
$float
podobnych1.2e9
lub.12
na przykład.Zwróć również uwagę na możliwe ograniczenia wynikające z wewnętrznej reprezentacji liczb zmiennoprzecinkowych:
Otrzymujesz liczbę całkowitą, ale są szanse, że nigdzie nie będziesz mógł jej użyć.
Ponadto, jak zauważył @BinaryZebra, w kilku
printf
implementacjach (bash, ksh93, yash, a nie GNU, zsh, dash) zależy od ustawień regionalnych (separator dziesiętny, którym może być.
lub,
).Jeśli więc
printf
liczby zmiennoprzecinkowe są zawsze wyrażane za pomocą kropki jako separatora dziesiętnego, a chcesz, aby była traktowana jako taka niezależnie od ustawień regionalnych użytkownika wywołującego skrypt, musisz ustawić ustawienia regionalne na C:Za pomocą
yash
możesz także:(patrz poniżej).
POSIX
nie jest POSIX, ponieważ
%f
nie musi być obsługiwany przez POSIX.POSIXly możesz:
Ustawienia regionalne nie mają na to wpływu (przecinek nie może być separatorem dziesiętnym,
awk
ponieważ jest już tam znakiem specjalnym w składni (print 1,2
tak samo, jakprint 1, 2
do przekazania dwóch argumentówprint
)zsh
W
zsh
(który obsługuje arytmetykę zmiennoprzecinkową (separatorem dziesiętnym jest zawsze kropka)), masz funkcjęrint()
matematyczną, która daje ci najbliższą liczbę całkowitą jako liczbę zmiennoprzecinkową (jak wC
) iint()
daje ci liczbę całkowitą od liczby zmiennoprzecinkowej (jak wawk
). Możesz więc zrobić:Lub:
Należy jednak pamiętać, że chociaż
double
s może reprezentować bardzo duże liczby, liczby całkowite są znacznie bardziej ograniczone.ksh93
ksh93 była pierwszą powłoką podobną do Bourne'a, która obsługiwała arytmetykę zmiennoprzecinkową. ksh93 optymalizuje podstawianie poleceń, nie używając potoku lub rozwidlenia, gdy polecenia są tylko wbudowanymi poleceniami. Więc
nie rozwidla się. Lub nawet lepiej:
co również nie rozwidla, ale także nie sprawia kłopotów z tworzeniem fałszywego środowiska podpowłoki.
Możesz także:
Ale uważaj na:
Możesz także:
Ale jak dla
zsh
:Strzeż się, że
ksh93
arytmetyka zmiennoprzecinkowa honoruje ustawienie separatora dziesiętnego w ustawieniach narodowych (mimo że w,
przeciwnym razie jest operatorem matematycznym ($((1,2))
w ustawieniach francuskich / niemieckich ... byłoby 6/5, a to samo co$((1, 2))
2 w ustawieniach angielskich) .yash
Yash obsługuje również arytmetyki zmiennoprzecinkowej, ale nie ma funkcji matematycznych, takich jak
ksh93
/zsh
„srint()
. Możesz jednak przekonwertować liczbę na liczbę całkowitą, używając na przykład operatora binarnego lub operatora (działa również w trybie in,zsh
ale nie w trybie inksh93
). Zauważ jednak, że obcina on część dziesiętną, nie podaje najbliższej liczby całkowitej:yash
honoruje separator dziesiętny ustawienia narodowego na wyjściu, ale nie dla stałych literału zmiennoprzecinkowego w wyrażeniach arytmetycznych, co może powodować niespodzianki:Jest to dobre, ponieważ możesz używać stałych zmiennoprzecinkowych w swoich skryptach, które używają kropki i nie musisz się martwić, że przestanie działać w innych lokalizacjach, ale nadal będzie w stanie poradzić sobie z liczbami wyrażonymi przez użytkownika tak długo, jak długo jak pamiętasz, aby zrobić:
źródło
int=${float%.*}
działał bardzo dobrze w moim skrypcie bash (wersja 3.2.57 (1)) na komputerze Mac (wersja 10.13.4 (17E199)).,
dziesiętną podstawkę. Zobacz sekcję oLC_ALL=C
bc
- Język kalkulatora o dowolnej precyzjiint (float) powinien wyglądać następująco:
Aby zaokrąglić lepiej, użyj tego:
Przykład:
źródło
float=-2; echo "($float+0.5)/1" | bc
daje-1
.Poprzednia przesłana odpowiedź była prawie poprawna: „Możesz zrobić:
Ale to usunęłoby część ułamkową zamiast dać najbliższą liczbę całkowitą i nie działałoby to dla wartości $ float jak na przykład 1.2e9 lub .12 .... ”
Po prostu użyj
${float%%.*}
.źródło
Jest to bardzo prosty hacky
Próbka wyjściowa
źródło
sed
, alecut
rozwiązanie jest prostsze. Wolęsed
lub,cut
ponieważ są IMHO bardziej dostępne na osadzonych celach niżawk
(co jest nadal dość powszechne przezbusybox
niżbc
).Związane z:
Odpowiedź uzupełniająca @ Stéphane Chazelas
awk
:źródło
printf
robi Bash , czy też jest jakiś inny powód, aby preferować awk nad wbudowaneprintf
.