J'écris un ensemble de fonctions de conversion de type numérique pour un moteur de base de données, et je suis préoccupé par le comportement de la conversion de grandes valeurs à virgule flottante types entiers avec une plus grande précision. Prenez par exemple la conversion d'un int de 32 bits en un flottant de précision simple de 32 bits. Le significande de 23 bits du flotteur donne environ 7 chiffres décimaux de précision, donc la conversion de tout int avec plus de 7 chiffres environ entraînera une perte de précision (ce qui est bien et attendu). Cependant, lorsque vous convertissez un flotteur de retour à un int, vous vous retrouvez avec des artefacts de sa représentation binaire dans les chiffres de poids faible:Arrondi à utiliser pour la conversion aller-retour int -> float -> int
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
int a = 2147483000;
cout << a << endl;
float f = (float)a;
cout << setprecision(10) << f << endl;
int b = (int)f;
cout << b << endl;
return 0;
}
Cette impression:
2147483000
2147483008
2147483008
008 talonnage, Au-delà de la précision du flottant, il semble donc indésirable de conserver dans l'int, puisque dans une application de base de données, les utilisateurs sont principalement concernés par la représentation décimale, et les 0 à la fin sont utilisés pour indiquer des chiffres insignifiants. Voici donc mes questions: y a-t-il des systèmes existants bien connus qui effectuent des arrondis décimaux significatifs dans les conversions float -> int (ou double -> long long), et y a-t-il des algorithmes connus et efficaces? alors? (Remarque: Je suis conscient que certains systèmes ont des types à virgule flottante décimale, tels que ceux définis par IEEE 754-2008, mais ils ne disposent pas du support matériel courant et ne sont pas intégrés en C/C++. Je veux les prendre en charge plus tard, mais j'ai toujours besoin de gérer les flottants binaires de manière intuitive.)
Cette situation envoie un drapeau rouge, demande « Pourquoi est-il une conversion aller-retour? » Cela implique que la valeur doit être stockée dans la base de données sous la forme d'un entier et non d'un flottant. Un peu comme simplifier une expression algébrique. –
Bonne question. Je ne prévois certainement pas qu'il y ait des conversions aller-retour, et rien dans le moteur de base de données lui-même ne provoquera cela. Cependant, cette base de données est conçue pour des données en mémoire très condensées, donc j'ai besoin d'utiliser les plus petits types possibles.Je ne veux pas que les utilisateurs (qui peuvent soumettre leurs propres requêtes de type SQL) pensent qu'ils obtiennent beaucoup plus de précision qu'ils ne le sont réellement quand ils convertissent un flottant binaire en un int ou un flottant décimal de plus haute précision. –