moala
moala

Reputation: 5334

C++ floating point to integer type conversions

What are the different techniques used to convert float type of data to integer in 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;
}

Upvotes: 71

Views: 375064

Answers (11)

thecoshman
thecoshman

Reputation: 8650

What you are looking for is 'type casting'. typecasting (putting the type you know you want in brackets) tells the compiler you know what you are doing and are cool with it. The old way that is inherited from C is as follows.

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

If you had only tried to write

int var_b = var_a;

You would have got a warning that you can't implicitly (automatically) convert a float to an int, as you lose the decimal.

This is referred to as the old way as C++ offers a superior alternative, 'static cast'; this provides a much safer way of converting from one type to another. The equivalent method would be (and the way you should do it)

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

This method may look a bit more long winded, but it provides much better handling for situations such as accidentally requesting a 'static cast' on a type that cannot be converted. For more information on the why you should be using static cast, see this question.

Upvotes: 107

Naveen
Naveen

Reputation: 73433

Normal way is to:

float pi = 3.1415;
int i = static_cast<int>(f); // i = 3

Always rounds down:

float f = 3.999;
int n = static_cast<int>(f); // n = 3

Upvotes: 44

Surya Stefanus
Surya Stefanus

Reputation: 1

I know this is an old question, but hope my answer can help. Here what I use in for my microcontroller:

  float temperature = 31.14
  float humidity = 66.70

  int intTemperature = static_cast<int>(round(temperature)); 
  int intHumidity = static_cast<int>(round(humidity)); 

Upvotes: 0

VojtaK
VojtaK

Reputation: 678

When you'd like to round the result as well you can e.g.

std::cout << static_cast<int>(2.49f+0.5f);//2
std::cout << static_cast<int>(2.51f+0.5f);//3

Upvotes: -1

Harri Luoma
Harri Luoma

Reputation: 51

This is one way to convert IEEE 754 float to 32-bit integer if you can't use floating point operations. It has also a scaler functionality to include more digits to the result. Useful values for scaler are 1, 10 and 100.

#define EXPONENT_LENGTH 8
#define MANTISSA_LENGTH 23
// to convert float to int without floating point operations
int ownFloatToInt(int floatBits, int scaler) {
    int sign = (floatBits >> (EXPONENT_LENGTH + MANTISSA_LENGTH)) & 1;
    int exponent = (floatBits >> MANTISSA_LENGTH) & ((1 << EXPONENT_LENGTH) - 1);
    int mantissa = (floatBits & ((1 << MANTISSA_LENGTH) - 1)) | (1 << MANTISSA_LENGTH);
    int result = mantissa * scaler; // possible overflow
    exponent -= ((1 << (EXPONENT_LENGTH - 1)) - 1); // exponent bias
    exponent -= MANTISSA_LENGTH; // modify exponent for shifting the mantissa
    if (exponent <= -(int)sizeof(result) * 8) {
        return 0; // underflow
    }
    if (exponent > 0) {
        result <<= exponent; // possible overflow
    } else {
        result >>= -exponent;
    }
    if (sign) result = -result; // handle sign
    return result;
}

Upvotes: -1

Roman Gorislavski
Roman Gorislavski

Reputation: 1

For most cases (long for floats, long long for double and long double):

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

Upvotes: 9

asdacap
asdacap

Reputation: 838

One thing I want to add. Sometimes, there can be precision loss. You may want to add some epsilon value first before converting. Not sure why that works... but it work.

int someint = (somedouble+epsilon);

Upvotes: 1

zoli2k
zoli2k

Reputation: 3458

Size of some float types may exceed the size of int. This example shows a safe conversion of any float type to int using the int safeFloatToInt(const FloatType &num); function:

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

Result:

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

Upvotes: 18

simong
simong

Reputation: 268

Check out the boost NumericConversion library. It will allow to explicitly control how you want to deal with issues like overflow handling and truncation.

Upvotes: 3

sanjuro
sanjuro

Reputation: 1661

the easiest technique is to just assign float to int, for example:

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

this will truncate everything behind floating point or you can round your float number before.

Upvotes: 1

Seidr
Seidr

Reputation: 4936

I believe you can do this using a cast:

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

Upvotes: 1

Related Questions