web-dev-qa-db-fra.com

Conversions à virgule flottante C ++ en type entier

Quelles sont les différentes techniques utilisées pour convertir un type flottant de données en entier en C++?

#include<iostream>
using namespace std;
struct database
{
    int id,age;
    float salary;
};
int main()
{
    struct database employee;
    employee.id=1;
    employee.age=23;
    employee.salary=45678.90; 
    /*
    How can i print this value as an integer
    (with out changing the salary data type in the declaration part) ?
    */
    cout<<endl<<employee.id<<endl<<employee.age<<endl<<employee.salary<<endl;
    return 0;
}
26
moala

Ce que vous cherchez, c'est du "casting de type". typecasting (mettre le type que vous - savez vous voulez entre parenthèses) indique au compilateur que vous savez ce que vous faites et que vous êtes cool avec. L'ancienne méthode héritée de C est la suivante.

float var_a = 9.99;
int   var_b = (int)var_a;

Si tu avais seulement essayé d'écrire

int var_b = var_a;

Vous auriez reçu un avertissement vous informant que vous ne pouvez pas implicitement (automatiquement) convertir un float en int, car vous perdez la décimale.

C'est ce que l'on appelle l'ancienne méthode, car C++ offre une alternative supérieure, la "conversion statique"; cela fournit un moyen beaucoup plus sûr de convertir d'un type à un autre. La méthode équivalente serait (et la façon dont vous devriez le faire)

float var_x = 9.99;
int   var_y = static_cast<int>(var_x);

Cette méthode peut sembler un peu plus longue, mais elle offre une bien meilleure gestion dans des situations telles que la demande accidentelle d'un "transtypage statique" sur un type qui ne peut pas être converti. Pour plus d'informations sur les raisons pour lesquelles vous devez utiliser la conversion statique, consultez cette question .

47
thecoshman

La manière normale consiste à:

float f = 3.4;
int n = static_cast<int>(f);
30
Naveen

La taille de certains types de flottants peut dépasser la taille de int. Cet exemple montre une conversion sûre de n'importe quel type de flottant en int en utilisant la fonction int safeFloatToInt(const FloatType &num);:

#include <iostream>
#include <limits>
using namespace std;

template <class FloatType>
int safeFloatToInt(const FloatType &num) {
   //check if float fits into integer
   if ( numeric_limits<int>::digits < numeric_limits<FloatType>::digits) {
      // check if float is smaller than max int
      if( (num < static_cast<FloatType>( numeric_limits<int>::max())) &&
          (num > static_cast<FloatType>( numeric_limits<int>::min())) ) {
         return static_cast<int>(num); //safe to cast
      } else {
        cerr << "Unsafe conversion of value:" << num << endl;
        //NaN is not defined for int return the largest int value
        return numeric_limits<int>::max();
      }
   } else {
      //It is safe to cast
      return static_cast<int>(num);
   }
}
int main(){
   double a=2251799813685240.0;
   float b=43.0;
   double c=23333.0;
   //unsafe cast
   cout << safeFloatToInt(a) << endl;
   cout << safeFloatToInt(b) << endl;
   cout << safeFloatToInt(c) << endl;
   return 0;
}

Résultat:

Unsafe conversion of value:2.2518e+15
2147483647
43
23333
11
zoli2k

Pour la plupart des cas (long pour les flotteurs, long long pour le double et long double):

long a{ std::lround(1.5f) }; //2l
long long b{ std::llround(std::floor(1.5)) }; //1ll
4
Roman Gorislavski

Découvrez le boost NumericConversion bibliothèque. Il permettra de contrôler explicitement la façon dont vous souhaitez gérer les problèmes tels que la gestion des débordements et la troncature.

3
simong

Je pense que vous pouvez le faire en utilisant un casting:

float f_val = 3.6f;
int i_val = (int) f_val;
0
Seidr

la technique la plus simple consiste à simplement affecter float à int, par exemple:

int i;
float f;
f = 34.0098;
i = f;

cela tronquera tout derrière la virgule flottante ou vous pouvez arrondir votre nombre flottant avant.

0
sanjuro

Je voudrais ajouter une chose. Parfois, il peut y avoir une perte de précision. Vous voudrez peut-être ajouter une valeur epsilon avant la conversion. Je ne sais pas pourquoi cela fonctionne ... mais cela fonctionne.

int someint = (somedouble+epsilon);
0
asdacap