La conversion de double, char* en C++ avec la haute performance
Mon application a besoin de convertir des valeurs double char* écrire à un tuyau qui n'accepte que des caractères. Les façons habituelles de faire cela est l'aide de l' sprintf() la fonction ou à l'aide de ostringstream de iomanip.h fichier d'en-tête.
S'avère, ces deux ont vraiment de la mauvaise performance. Et mon application doit faire cette conversion si souvent qu'il devient le principal goulot d'étranglement.
Est-il une autre fonction que je pourrais utiliser? Ce que la logique puis-je utiliser pour écrire une conversion efficace de la fonction? La seule chose que j'ai réussi à venir jusqu'ici est d'obtenir chaque individu chiffres à l'aide de la division et de la mod des opérations, et ajouter ces chiffres à un char* pour obtenir la totalité de la valeur de type double. Cela ne semble pas être une bonne approche si, et aura probablement une mauvaise performance elle-même.
Merci d'avance pour vos pensées.
EDIT: Il y a une certaine confusion sur la façon dont le char* sera utilisé. Le char* sera un argument de la fonction fwrite qui écrit à un tuyau.
- Qu'entendez-vous par "pipe n'accepte que les caractères"? Pouvez-vous envoyer/écrire des octets? Le format dans lequel les données de cette pipe question (est-il besoin d'être lisible par l'homme), ou voulez-vous convertir le dos de l'autre côté?
- Lire ceci: stackoverflow.com/questions/3173056/...
- pourquoi ne pas bitcast à un int et encoder qui en hexadécimal, et l'envoyer (puis de l'autre côté de convertir retour)
Vous devez vous connecter pour publier un commentaire.
Si vous souhaitez imprimer le nombre de type double peut prendre en charge, quelle que soit l'utilisation de la bibliothèque pour faire le travail. Il enregistre vos santé mentale: Pourquoi ne "dtoa.c" contiennent tellement de code?
Si vous souhaitez imprimer un sous-ensemble de nombres de type double. Par exemple, jusqu'à 4 chiffres après le point décimal, et pas plus de 5 chiffres avant le point décimal, alors vous pouvez arrondir le nombre et le convertir en int type, avant d'imprimer les documents à l'aide de la division et de la mod. Je peux confirmer les performances de cette méthode.
EDIT:
Si vous original le but est d'envoyer les données pour la communication, puis l'envoi de la forme binaire de double sera la plus rapide et la plus précise de la méthode (pas possible de la perte de précision due à la conversion). La manière de faire cela est expliqué dans d'autres réponses.
Vous pouvez utiliser les std::ostream
write
et std::istreamread
méthodes avec n'importe quel type de données vous avez juste à reinterpret_cast les données comme un pointeur de char:si vous voulez lire les données octet par octet. l'utilisation de cette technique
ce sera de retour le plus faible de l'octet de dbl. et ptr++ va se référer 2e octet de dbl.
Vous êtes dans le contrôle des deux extrémités du tuyau? Êtes-vous juste essayer de tunnel de double à travers ou vous avez besoin d'un texte valide représentation de la double?
Si vous êtes juste de tunneling et le tuyau est de 8 bits nettoyer puis utilisez l'une des réponses ci-dessus.
Si vous avez besoin d'une chaîne d'utiliser l'une de l'autre les réponses ci-dessus.
Si votre problème est que le tuyau est à seulement 7 bits de large, puis de les convertir à radix 64 sur l'écriture et à l'arrière à nouveau sur lecture.
Certains systèmes offrent
dtostre
etdtostrf
fonctions de conversion - pourrait être intéressant de l'analyse comparative. Vous pouvez regardersprintf()
code source (par exemple, version GNU) pour des idées, de la cueillette jusqu'à la%e
,%f
et/ou%g
mise en forme comme vous le souhaitez, en évitant la chaîne de format d'interprétation de l'étape et même inlinable, et de la performance-tune pour le goût), vous pourriez être en mesure de retirer de revêtement spécial pour NaN, de l'infini, et d'autres valeurs si vous savez que vous n'avez pas à les gérer.La partie lente de
sprintf
sur votre système peut ne pas être nécessairement la conversion de la double, mais l'analyse de la chaîne de format. Qui pourrait être de bonnes nouvelles pour vous que c'est quelque chose que vous pouvez optimiser loin.En outre, essayez difficile de documenter toutes les connaissances que vous avez au sujet de gamme, l'exactitude, et la nature de la
double
valeurs que vous avez besoin de processus, et l'utiliser pour développer un algorithme spécial.En supposant que vos données ne sont jamais nombres dénormalisés, l'utilisation d'un fixe et de précision, un nombre relativement élevé d'effectuer résultat peut ressembler à ceci:
Cependant, la
sprintf
etostream
approches vous sont déjà au courant de sont les seules solutions qui sont général et portable.Espère que cette aide.
À l'aide de
ftoa
sera légèrement mieux quesprintf
que c'est ce qu'il utilise en interne. Voir la question relative à la ici Aussi regarder comment ftoa est mis en œuvre dans votre bibliothèque de source et de voir si vous pouvez l'améliorer en fonction de vos scénarios.Il semble
ftoa
n'est pas la norme à tous, mon mauvais. Voici un discussion montrant une mise en œuvre qui prétend être beaucoup plus rapide que sprintf. Vous auriez besoin de profil à la fois sur votre propre environnements cibles, et de mettre en œuvre avec double plutôt que de flotter.