Comment pouvons-nous tronquer float64 type à une certaine précision dans golang?
package main
import (
"fmt"
"strconv"
)
func main() {
k := 10/3.0
i := fmt.Sprintf("%.2f", k)
f,_ := strconv.ParseFloat(i, 2)
fmt.Println(f)
}
J'ai eu à écrire le programme ci-dessus pour diminuer la précision d'un float64 variable à 2.
Dans ce cas, j'ai été en utilisant à la fois strconv et de l'esf. Est-il une autre méthode logique par lequel il peut être fait ?
- Pourquoi voulez-vous diminuer la précision d'un float64 variable?
- Lors de l'affichage des données en html, je n'ai pas envie d'afficher ou de stocker plus de 2 chiffres. J'ai été confronté à la situation où j'ai dû convertir en chaîne de caractères et a été pensée de méthodes alternatives.
- Juste à l'aide de l'esf.Sprintf("%.2f", k) lorsque vous le montrer dans le code html est probablement le meilleur moyen pour cela.
- J'ai le même besoin, mais pour une raison différente. Je prends un total valeur de l'argent et en le divisant de plus de X jours. J'ai besoin chaque jour pour avoir une réelle valeur de l'argent au centime le plus proche, pas une fraction de centime, car je ne peux pas demander à mes clients pour un demi-penny. Je ne veux pas stocker une valeur plus spécifique parce que j'ai aussi besoin de prendre le total de ma X les valeurs de la monnaie, ajoutez-les à nouveau, et de trouver la différence entre le montant d'origine, de sorte que je peux ajouter que la différence sur la dernière journée de la charge.
- Sur le dessus des exemples ci-dessous, au lieu de les tronquer l'aide de
int()
la bibliothèque de mathématiques aTrunc(float64) float64
qui retourne simplement le type entier, il est préférable de l'utiliser. - Blair Connolly - ne pas utiliser float pour stocker des valeurs monétaires! stackoverflow.com/questions/3730019/...
Vous devez vous connecter pour publier un commentaire.
Vous n'avez pas besoin de code supplémentaire ... c'est aussi simple que
Le Code De Test
math/big
, ce qui vous permet de générer une chaîne de valeur à une précision spécifiée à tout moment, tout en gardant la "exact" float intacte.fmt.Printf("%.2f", 2.289)
vous donnera2.29
(et juste%f
vous montrera la pleine2.289
- ce n'est donc pas un problème de constantes étant arrondis, etc.)Je viens juste de commencer à Aller et trouve surprenant qu'il n'a ni "toFixed" fonction (comme en JavaScript), ce qui permettrait de réaliser ce que vous voulez, ni même un "tour" de la fonction.
J'ai ramassé un one-liner fonction round d'ailleurs, et a également fait toFixed (), qui dépend du round():
Utilisation:
toFixed(92234, 14)
-> "-92233.72036854776"Je ne vois vraiment pas le point, mais vous pourriez faire quelque chose comme ça, sans strconv:
Personne n'a mentionné l'aide
math/big
. Les résultats en ce qui concerne la question d'origine sont les mêmes que l'on a accepté la réponse, mais si vous travaillez avec des flotteurs qui exigent un degré de précision ($argent$), alors vous devriez utiliserbig.Float
.Par la question de départ:
Malheureusement, vous pouvez voir que
.Text
ne pas utiliser la définition de mode d'arrondi (sinon, cette réponse pourrait être plus utile), mais semble toujours arrondir vers zéro:Néanmoins, il ya certains avantages à avoir votre flotteur stockées en tant que
big.Float
.La réponse par threeve m'a amené à ce problème sur GitHub où une solution basée sur
math/big
d'arrondi des valeurs est présenté - de cette façon, la méthode d'arrondi est utilisé correctement:Le mode d'arrondi est également respectée dans threeve exemple:
->
correctement les rendements0.05
Aussi, Allez 1.10 a été libéré et a ajouté une
math.Round()
fonction, voir cette excellente réponse par icza: Golang Tour la plus Proche de 0,05Cependant, on ne devrait pas utiliser
float
pour le stockage des valeurs monétaires. (Voir: Pourquoi ne pas utiliser le Double ou Float pour représenter la monnaie?)Une façon de contourner ce problème est d'utiliser une bibliothèque qui implémente
decimal
comme https://github.com/ericlagergren/decimal ou https://github.com/shopspring/decimalLa solution la plus simple est une troncature numérique (en supposant que
i
est un float et que vous souhaitez une précision de 2 décimales):Par exemple:
MÉFIEZ-vous!
Si vous faites affaire avec un grand nombre (les numéros de la croix de la valeur max de frontières), vous devez savoir que le ci-dessus peut conduire à grave à virgule flottante de précision des questions:
Imprime:
9.223372036854776e+18 -9.223372036854776e+17
Voir aussi:
math
valeur numérique de la gamme des constantesmath/grand
C'est un peu la solution de contournement comment pouvez-vous faire un tour de flotteur à l'aide de conversion de type int en arrière:
https://play.golang.org/p/yg2QYcZ-2u
Être prudent avec la longitude et la latitude flotter comme troncature et d'arrondi peuvent donner des résultats complètement différents... comme il peut vous mettre sur le mauvais côté d'une latitude de la frontière.
modifier à partir de @creack