web-dev-qa-db-ja.com

C ++浮動小数点から整数型への変換

C++でfloat型のデータを整数に変換するために使用されるさまざまな手法は何ですか?

#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

探しているのは「型キャスト」です。型キャスト(あなたがknow括弧内に入れたい型を入れる)は、あなたが何をしていて、それでかっこいいかをコンパイラーに伝えます。 Cから継承される古い方法は次のとおりです。

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

書き込もうとしただけの場合

int var_b = var_a;

小数点を失うため、floatintに暗黙的に(自動的に)変換できないという警告が表示されます。

C++は優れた代替手段である「静的キャスト」を提供するため、これは古い方法と呼ばれます。これにより、あるタイプから別のタイプに変換するはるかに安全な方法が提供されます。同等の方法は、(およびその方法)

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

このメソッドはもう少し長く見えるかもしれませんが、変換できない型で「静的キャスト」を誤って要求するような状況では、はるかに優れた処理を提供します。静的キャストを使用する理由の詳細については、 この質問 を参照してください。

47
thecoshman

通常の方法は次のとおりです。

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

一部のfloat型のサイズは、intのサイズを超える場合があります。この例は、int safeFloatToInt(const FloatType &num);関数を使用して、任意のfloat型からintへの安全な変換を示しています。

#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
11
zoli2k

ほとんどの場合(floatの場合はlong、doubleおよびlong doubleの場合はlong long):

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

Boost NumericConversion ライブラリを確認してください。オーバーフロー処理や切り捨てなどの問題に対処する方法を明示的に制御できます。

3
simong

私はあなたがキャストを使用してこれを行うことができると信じています:

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

最も簡単な方法は、単にfloatをintに割り当てることです。次に例を示します。

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

これにより、浮動小数点の背後のすべてが切り捨てられるか、浮動小数点数を前に丸めることができます。

0
sanjuro

1つ追加したいことがあります。場合によっては、精度が失われる可能性があります。変換する前にイプシロン値を最初に追加することができます。なぜそれが機能するのかはわかりませんが、機能します。

int someint = (somedouble+epsilon);
0
asdacap