Je cherche toujours une réponse pure en bc
sur la façon d'arrondir juste une valeur dans une fonction, mais voici une réponse pure en bash
:
#!/bin/bash
echo "Insérez le prix que vous souhaitez calculer :"
read float
echo "Voici le prix sans taxes :"
embiggen() {
local int precision fraction=""
if [ "$1" != "${1#*.}" ]; then # il y a un point décimal
fraction="${1#*.}" # juste les chiffres après le point
fi
int="${1%.*}" # le float comme entier tronqué
precision="${#fraction}" # le nombre de chiffres fractionnels
echo $(( 10**10 * $int$fraction / 10**$precision ))
}
# arrondir vers le bas si négatif
if [ "$float" != "${float#-}" ]
then round="-5000000000"
else round="5000000000"
fi
# calculer la réponse arrondie (sans point décimal)
answer=$(( ( `embiggen $float` * 100 + $round ) / `embiggen 1.18` ))
int=${answer%??} # la réponse comme entier tronqué
echo $int.${answer#$int} # réassembler avec la précision correcte
read -p "Appuyez sur une touche pour continuer..."
Essentiellement, cela extrait soigneusement les décimales, multiplie tout par 100 milliards (10¹, 10**10
en bash
), ajuste la précision et l'arrondi, effectue la division réelle, divise à nouveau à la magnitude appropriée, puis réinsère le point décimal.
Étape par étape :
La fonction embiggen()
attribue la forme entière tronquée de son argument à $int
et enregistre les chiffres après le point dans $fraction
. Le nombre de chiffres fractionnels est noté dans $precision
. Le calcul multiplie 10¹ par la concaténation de $int
et $fraction
puis ajuste cela pour correspondre à la précision (par exemple, embiggen 48.86
devient 10¹ × 4886 / 100 et retourne 488600000000
qui est 488 600 000 000).
Nous voulons une précision finale en centièmes, donc nous multiplions le premier nombre par 100, ajoutons 5 pour des raisons d'arrondi, puis divisons le deuxième nombre. Cette attribution de $answer
nous laisse cent fois la réponse finale.
Maintenant nous devons ajouter le point décimal. Nous attribuons une nouvelle valeur de $int
à $answer
en excluant ses deux derniers chiffres, puis echo
avec un point et le $answer
en excluant la valeur $int
qui a déjà été prise en charge. (Peu importe le bug de mise en évidence de syntaxe qui fait qu'il semble s'agir d'un commentaire)
(Bashisme : l'exponentiation n'est pas POSIX, donc c'est un bashisme. Une solution pure POSIX nécessiterait des boucles pour ajouter des zéros plutôt que d'utiliser des puissances de dix. En outre, "embiggen" est un mot tout à fait cromulent.)
Une des principales raisons pour lesquelles j'utilise zsh
comme shell est qu'elle prend en charge les mathématiques en virgule flottante. La solution à cette question est assez simple en zsh
:
printf %.2f $((float/1.18))
(J'adorerais voir quelqu'un ajouter un commentaire à cette réponse avec l'astuce pour activer l'arithmétique en virgule flottante dans bash
, mais je suis assez sûr qu'une telle fonctionnalité n'existe pas encore.)