C++ floating point naar integer type conversies

Wat zijn de verschillende technieken die worden gebruikt om gegevens van het type float naar integer in C++ te converteren?

#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;
}

Antwoord 1, autoriteit 100%

Wat u zoekt is ‘type casting’. typecasting (door het type dat je kentdat je wilt tussen haakjes te zetten) vertelt de compiler dat je weet wat je doet en dat je er cool mee bent. De oude manier die is geërfd van C is als volgt.

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

Als je alleen had geprobeerd te schrijven

int var_b = var_a;

Je zou een waarschuwing hebben gekregen dat je een floatniet impliciet (automatisch) kunt converteren naar een int, omdat je het decimaalteken verliest.

Dit wordt de oude manier genoemd omdat C++ een superieur alternatief biedt, ‘static cast’; dit biedt een veel veiligere manier om van het ene type naar het andere over te schakelen. De equivalente methode zou zijn (en de manier waarop u het zou moeten doen)

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

Deze methode ziet er misschien wat langdradig uit, maar biedt veel betere afhandeling voor situaties zoals het per ongeluk aanvragen van een ‘statische cast’ op een type dat niet kan worden geconverteerd. Zie voor meer informatie over waarom u statische cast zou moeten gebruiken. deze vraag.


Antwoord 2, autoriteit 43%

Normale manier is om:

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

Antwoord 3, autoriteit 22%

De grootte van sommige float-types kan groter zijn dan int.
Dit voorbeeld toont een veilige conversie van elk type float naar intmet behulp van de functie 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;
}

Resultaat:

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

Antwoord 4, Autoriteit 9%

Voor de meeste gevallen (lang voor drijvers, lang lang voor dubbel en lang dubbel):

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

Antwoord 5, Autoriteit 4%

Bekijk de Boost NumericConversion bibliotheek. Het zal het mogelijk maken om expliciet te bepalen hoe u wilt omgaan met problemen zoals overstroomafhandeling en truncatie.


Antwoord 6

Ik denk dat je dit kunt doen met een cast:

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

Antwoord 7

De eenvoudigste techniek is om de vlotter alleen toe te wijzen aan INT, bijvoorbeeld:

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

Hiermee wordt alles achter het zwevende punt afknippen of kunt u eerder uw float-nummer afronden.


Antwoord 8

Een ding dat ik wil toevoegen. Soms kan er nauwkeurig verlies zijn. Misschien wilt u eerst wat EPSILON-waarde toevoegen voordat u het converteert. Niet zeker waarom dat werkt … maar het werkt.

int someint = (somedouble+epsilon);

Other episodes