Je cherche toujours une pure réponse bc
expliquant comment arrondir une seule valeur dans une fonction, mais voici une pure réponse bash
:
#!/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..."
Essentiellement, cela extrait soigneusement les décimales, tout multiplie par 100 milliards (10¹⁰, 10**10
en bash
), ajuste la précision et l’arrondi, effectue la division réelle, rétablit la magnitude appropriée, puis réinsère la décimal.
Pas à pas:
La fonction embiggen()
assigne 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 l’ajuste pour correspondre à la précision (par exemple, embiggen 48.86
devient 10¹⁰ × 4886/100 et renvoie 488600000000
, qui est 488,600,000,000).
Nous voulons une précision finale de centièmes. Nous multiplions donc le premier nombre par 100, en ajoutions 5 à des fins d’arrondi, puis nous divisons le deuxième nombre. Cette assignation de $answer
nous laisse cent fois la réponse finale.
Nous devons maintenant ajouter le point décimal. Nous assignons une nouvelle valeur $int
à $answer
en excluant ses deux derniers chiffres, puis echo
avec un point et en $answer
en excluant la valeur $int
déjà prise en charge. (Peu importe le bogue 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 codant.)
L'une des principales raisons pour lesquelles j'utilise zsh
en tant que 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 dans bash
, mais je suis à peu près sûr qu'une telle fonctionnalité n'existe pas encore.)