Преобразования с плавающей точкой в ​​С++ в целые типы

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

Ответ 1

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

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

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

int var_b = var_a;

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

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

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

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

Ответ 2

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

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

Ответ 3

Размер некоторых типов float может превышать размер int. В этом примере показано безопасное преобразование любого типа float в 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

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

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

Ответ 5

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

Ответ 6

Я считаю, что вы можете сделать это с помощью броска:

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

Ответ 7

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

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

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

Ответ 8

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

int someint = (somedouble+epsilon);