Je cherche toujours une bc
réponse pure à la méthode pour arrondir une seule valeur dans une fonction, mais voici une bash
réponse pure :
#!/bin/bash
echo "Insert the price you want to calculate:"
read float
echo "This is the price without taxes:"
embiggen() {
local int precision fraction=""
if [ "$1" != "${1#*.}" ]; then # there is a decimal point
fraction="${1#*.}" # just the digits after the dot
fi
int="${1%.*}" # the float as a truncated integer
precision="${#fraction}" # the number of fractional digits
echo $(( 10**10 * $int$fraction / 10**$precision ))
}
# round down if negative
if [ "$float" != "${float#-}" ]
then round="-5000000000"
else round="5000000000"
fi
# calculate rounded answer (sans decimal point)
answer=$(( ( `embiggen $float` * 100 + $round ) / `embiggen 1.18` ))
int=${answer%??} # the answer as a truncated integer
echo $int.${answer#$int} # reassemble with correct precision
read -p "Press any key to continue..."
En gros, cela extrait soigneusement les décimales, multiplie tout par 100 milliards (10¹⁰, 10**10
en bash
), ajuste de précision et de l' arrondissement, effectue la division réelle, divise Retour à la grandeur appropriée, et réinsère alors la décimale.
Pas à pas:
La embiggen()
fonction affecte la forme entière tronquée de son argument à $int
et enregistre les nombres après le point dans $fraction
. Le nombre de chiffres fractionnaires est noté dans $precision
. Le calcul multiplie 10¹⁰ par la concaténation de $int
et $fraction
puis ajuste cela pour correspondre à la précision ( embiggen 48.86
devient par exemple 10¹⁰ × 4886/100 et renvoie 488600000000
ce qui est 488,600,000,000).
Nous voulons une précision finale de centièmes. Nous multiplions donc le premier nombre par 100, en ajoutons 5 aux fins de l'arrondi, puis nous divisons le deuxième nombre. Cette cession de $answer
nous laisse cent fois la réponse finale.
Nous devons maintenant ajouter le point décimal. Nous attribuons une nouvelle $int
valeur pour $answer
exclure ses deux derniers chiffres, puis echo
un point et l’ $answer
exclusion de la $int
valeur déjà prise en charge. (Peu importe le bug de mise en évidence de la syntaxe qui le fait apparaître comme un commentaire)
(Bashism: l’exponentiation n’est pas POSIX, c’est donc un penchant. Une solution POSIX pure nécessiterait des boucles pour ajouter des zéros plutôt que d’utiliser des puissances de dix. En outre, "embiggen" est un mot parfaitement cromulant.)
L'une des principales raisons pour lesquelles j'utilise zsh
le shell est qu'il prend en charge les mathématiques en virgule flottante. La solution à cette question est assez simple dans zsh
:
printf %.2f $((float/1.18))
(J'aimerais beaucoup que quelqu'un ajoute un commentaire à cette réponse en essayant d'activer l'arithmétique en virgule flottante bash
, mais je suis à peu près sûr qu'une telle fonctionnalité n'existe pas encore.)