1

I have a seemingly simple goal: I want to convert a float into an integer-type that is exactly 32 bit wide. The code I am posting works on my windows machine, but not on the Linux device I am trying to run the code in the end. I have tried this first:

float a;
a = /*some real number, for example 1.08825e+11*/;
if (!isfinite(a)){
 return -1;
}
int32_t b;
b = static_cast<int32_t> (a);

Which does not work -the programs just crashes with this information in the command window:

Runtime received SIGFPE (address: 0xb62cd3b7 reason: floating-point invalid operation)

Then I have found a function in another question on stack overflow that safely converts float into int-data types and have tried to adopt the function for my needs. This is my version:

template <class FloatType>
int32_t safeFloatToDINT(const FloatType& num) {
    //check if float fits into int32_t
    if (std::numeric_limits<int32_t>::digits < std::numeric_limits<FloatType>::digits) {
        // check if float is smaller than max int32_t
        if ((num < static_cast<FloatType>(std::numeric_limits<int32_t>::max())) &&
            (num > static_cast<FloatType>(std::numeric_limits<int32_t>::min()))) {
            return static_cast<int32_t>(num); //safe to cast
        }
        else {
            std::cerr << "Unsafe conversion of value:" << num << std::endl;
            //NaN is not defined for int32_t return the largest int32_t value
            return std::numeric_limits<int32_t>::max();
        }
    }
    else {
        //It is safe to cast
        return static_cast<int32_t>(num);
    }
}

Unfortunately, b = safeFloatToDINT(a); throws the FPU exception, too. I have also just tried writing b = (int32_t)a; but that does not work either. I would like to know how I can take my float variable and safely convert it into an integer type that spans 32 bit. Thank you in advance.

MYZ
  • 331
  • 2
  • 10
  • You never initialize `a` – Kevin Apr 29 '20 at 16:34
  • `a` is uninitialized. – RamblinRose Apr 29 '20 at 16:34
  • Sorry I should have been more specific. My program initializes a always and checks for its validity. I updated the question to reflect that. – MYZ Apr 30 '20 at 10:12
  • `static_cast` is unnecessary, float to integer is an implicit conversion. It probably crashes because of an integer division by 0 elsewhere - that is what causes `SIGFPE`. Run it under a debugger to find the line which causes the crash. – Maxim Egorushkin Apr 30 '20 at 11:06
  • @Maxim Egorushkin Thank you for your comment. The conversion line is exactly where the program crashes. there is no division involved. In the second approach the line `(num < static_cast(std::numeric_limits::max())` crashes. If I use `double` instead of `float` the second approach works. I still do not understand the underlying problem so that I can prevent a even bigger number to crash the `double` version of the code as well. – MYZ Apr 30 '20 at 11:41
  • @MertY What platform and CPU? – Maxim Egorushkin Apr 30 '20 at 11:44
  • @MaximEgorushkin This is using a Intel(R) Atom(TM) CPU E680 on a Linux device – MYZ Apr 30 '20 at 11:46
  • What does `std::fetestexcept(FE_ALL_EXCEPT)` return? – Maxim Egorushkin Apr 30 '20 at 11:51

0 Answers0