Est-ce la bonne façon de faire une conversion de flottant en entier dans bash? Y a-t-il une autre méthode?
flotToint() {
printf "%.0f\n" "$@"
}
bash
floating-point
Rahul Patil
la source
la source
%.0f
arrondira de haut en bas. Est-ce que c'est ce que tu veux? Vous pouvez utiliserprintf "%d\n" "$@" 2>/dev/null
pour couper la fraction.Réponses:
frapper
Dans
bash
, c'est probablement aussi bon que cela. Cela utilise un shell intégré. Si vous avez besoin du résultat dans une variable, vous pouvez utiliser la substitution de commande, ou la commandebash
spécifique (bien que désormais également prise en charge parzsh
):Vous pourriez faire:
Mais cela supprimerait la partie décimale au lieu de vous donner l'entier le plus proche et cela ne fonctionnerait pas pour des valeurs de
$float
type similaire1.2e9
ou.12
par exemple.Notez également les limitations possibles dues à la représentation interne des floats:
Vous obtenez un entier, mais il est probable que vous ne pourrez utiliser cet entier nulle part.
De plus, comme l'a noté @BinaryZebra, dans plusieurs
printf
implémentations (bash, ksh93, yash, et non GNU, zsh, dash), il est affecté par les paramètres régionaux (le séparateur décimal qui peut être.
ou,
).Ainsi, si vos flottants sont toujours exprimés avec le point comme séparateur décimal et que vous souhaitez le traiter comme tel
printf
quel que soit le paramètre régional de l'utilisateur qui appelle votre script, vous devez le définir en C:Avec
yash
, vous pouvez aussi faire:(voir ci-dessous).
POSIX
ne POSIX
%f
n'a pas à être pris en charge par POSIX.POSIXly, vous pouvez faire:
Celui-ci n'est pas affecté par les paramètres régionaux (la virgule ne peut pas être un séparateur décimal,
awk
car il s'agit déjà d'un caractère spécial dans la syntaxe (print 1,2
identiqueprint 1, 2
à celle utilisée pour passer deux argumentsprint
).zsh
Dans
zsh
(qui prend en charge l’arithmétique en virgule flottante (le séparateur décimal est toujours la période)), vous avez larint()
fonction mathématique qui vous donne l’entier le plus proche sous forme de float (comme dansC
) etint()
un entier à partir de float (comme dansawk
). Alors tu peux faire:Ou:
Cependant, notez que
double
s peut représenter de très grands nombres, les nombres entiers sont beaucoup plus limités.ksh93
ksh93 était le premier shell de type Bourne à supporter l'arithmétique en virgule flottante. ksh93 optimise la substitution de commande en n'utilisant pas de canal ou en forçant lorsque les commandes ne sont que des commandes intégrées. Alors
ne fourche pas. Ou même mieux:
ce qui ne va pas non plus, mais ne va pas non plus tout le problème de la création d’un faux environnement de sous-shell.
Vous pouvez aussi faire:
Mais méfiez-vous de:
Vous pouvez aussi faire:
Mais comme pour
zsh
:Attention, l'
ksh93
arithmétique en virgule flottante respecte le paramètre de séparateur décimal défini dans l'environnement local (même s'il,
s'agit par ailleurs d'un opérateur mathématique ($((1,2))
serait 6/5 dans un environnement français / allemand ... et identique$((1, 2))
, 2 dans un environnement anglais) .yash
Yash prend également en charge l' arithmétique en virgule flottante , mais ne dispose pas de fonctions mathématiques comme
ksh93
/zsh
s »rint()
. Vous pouvez toutefois convertir un nombre en entier en utilisant le binaire ou l' opérateur par exemple (fonctionne également danszsh
mais pas dansksh93
). Notez cependant que cela tronque la partie décimale, il ne vous donne pas l'entier le plus proche:yash
respecte le séparateur décimal des paramètres régionaux en sortie, mais pas les constantes littérales à virgule flottante dans ses expressions arithmétiques, ce qui peut entraîner des surprises:En un sens, vous pouvez utiliser des constantes à virgule flottante dans vos scripts qui utilisent la période et ne pas avoir à craindre que celle-ci ne fonctionne plus dans d'autres paramètres régionaux, tout en conservant la capacité de traiter les nombres tels qu'exprimés par l'utilisateur aussi longtemps. comme tu te souviens de le faire:
la source
int=${float%.*}
a très bien fonctionné dans mon script bash (version 3.2.57 (1) -release) sur Mac (version 10.13.4 (17E199)).,
pour base décimale. Voir la section à propos deLC_ALL=C
bc
- Un langage de calculateur de précision arbitraireint (float) devrait ressembler à:
Pour arrondir mieux utiliser ceci:
Exemple:
la source
float=-2; echo "($float+0.5)/1" | bc
donne-1
.La réponse précédente était presque correcte: "Vous pourriez faire:
Mais cela supprimerait la partie décimale au lieu de vous donner l’entier le plus proche et cela ne fonctionnerait pas pour les valeurs de $ float telles que 1.2e9 ou .12 par exemple ... "
Il suffit d'utiliser
${float%%.*}
.la source
Un hacky très simple est
Échantillon de sortie
la source
sed
, mais lacut
solution est plus simple. Je préfèresed
oucut
comme ils sont à mon humble avis plus disponible sur les cibles intégrées queawk
(ce qui est encore assez commun viabusybox
quebc
).Apparenté, relié, connexe:
Complétant @ Stéphane Chazelas
awk
réponse:la source
printf
ou s'il y a une autre raison de préférer awk à la fonction intégréeprintf
.