Sto ancora cercando una bc
risposta pura a come arrotondare un solo valore all'interno di una funzione, ma ecco una bash
risposta pura :
#!/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..."
Fondamentalmente, questo estrae attentamente i decimali, moltiplica tutto per 100 miliardi (10¹⁰, 10**10
in bash
), regola la precisione e l'arrotondamento, esegue la divisione effettiva, divide nuovamente alla grandezza appropriata e quindi reinserisce il decimale.
Passo dopo passo:
La embiggen()
funzione assegna la forma intera troncata del suo argomento $int
e salva i numeri dopo il punto in $fraction
. Il numero di cifre frazionarie è indicato in $precision
. La matematica moltiplica 10¹⁰ per la concatenazione di $int
e $fraction
quindi la regola per adattarla alla precisione (ad esempio embiggen 48.86
diventa 10¹⁰ × 4886/100 e restituisce 488600000000
488.600.000.000).
Vogliamo una precisione finale di centesimi, quindi moltiplichiamo il primo numero per 100, aggiungiamo 5 per arrotondare e quindi dividiamo il secondo numero. Questo incarico $answer
ci lascia cento volte la risposta finale.
Ora dobbiamo aggiungere il punto decimale. Assegniamo un nuovo $int
valore per $answer
escludere le sue ultime due cifre, quindi echo
con un punto e $answer
escludendo il $int
valore già curato. (Non importa il bug di evidenziazione della sintassi che fa apparire questo come un commento)
(Bashismo: l'esponenziazione non è POSIX, quindi questo è un bashismo. Una soluzione POSIX pura richiederebbe anelli per aggiungere zeri piuttosto che usare poteri di dieci. Inoltre, "embiggen" è una parola perfettamente cromulante.)
Uno dei motivi principali che uso zsh
come shell è che supporta la matematica in virgola mobile. La soluzione a questa domanda è piuttosto semplice in zsh
:
printf %.2f $((float/1.18))
(Mi piacerebbe vedere qualcuno aggiungere un commento a questa risposta con il trucco di abilitare l'aritmetica in virgola mobile bash
, ma sono abbastanza sicuro che una tale funzionalità non esiste ancora.)