Преобразование типов с плавающей запятой в ++ - PullRequest
26 голосов
/ 30 марта 2010

Какие методы используются для преобразования данных типа float в целое число в 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;
}

Ответы [ 8 ]

47 голосов
/ 30 марта 2010

То, что вы ищете, это «приведение типа». Typecasting (помещая тип, который вы знаете , который вы хотите заключить в скобки), сообщает компилятору, что вы знаете, что делаете, и к нему здорово относитесь. Старый способ, который унаследован от C, выглядит следующим образом.

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

Если бы вы только пытались написать

int var_b = var_a;

Вы бы получили предупреждение о том, что вы не можете неявно (автоматически) преобразовать float в int, поскольку вы потеряете десятичную дробь.

Это называется старым способом, поскольку C ++ предлагает превосходную альтернативу, «статическое приведение»; это обеспечивает намного более безопасный способ преобразования из одного типа в другой. Эквивалентный метод будет (и способ, которым вы должны это сделать)

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

Этот метод может выглядеть немного длиннее, но он обеспечивает намного лучшую обработку в таких ситуациях, как случайный запрос «статического приведения» к типу, который не может быть преобразован. Для получения дополнительной информации о том, почему вы должны использовать статическое приведение, см. этот вопрос .

30 голосов
/ 30 марта 2010

Обычный способ:

float f = 3.4;
int n = static_cast<int>(f);
11 голосов
/ 30 марта 2010

Размер некоторых типов с плавающей точкой может превышать размер int. В этом примере показано безопасное преобразование любого типа с плавающей запятой в int с использованием функции 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;
}

Результат:

Unsafe conversion of value:2.2518e+15
2147483647
43
23333
4 голосов
/ 27 апреля 2016

В большинстве случаев (длинные для поплавков, длинные длинные для двойных и длинные двойные):

long a{ std::lround(1.5f) }; //2l
long long b{ std::llround(std::floor(1.5)) }; //1ll
3 голосов
/ 30 марта 2010

Проверьте повышение NumericConversion библиотека. Это позволит явно контролировать, как вы хотите решать такие проблемы, как обработка переполнения и усечение.

0 голосов
/ 20 августа 2015

Одна вещь, которую я хочу добавить. Иногда может быть потеря точности. Возможно, вы захотите добавить некоторые значения epsilon перед преобразованием. Не уверен, почему это работает ... но это работает.

int someint = (somedouble+epsilon);
0 голосов
/ 30 марта 2010

самый простой метод - просто присвоить float для int, например:

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

это обрезает все за плавающей запятой, или вы можете округлить число с плавающей запятой раньше.

0 голосов
/ 30 марта 2010

Я полагаю, что вы можете сделать это, используя приведение:

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