This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

CCS/TMS320VC5502: Newer Compiler Handles Floating-point to Integer Conversion Differently

Part Number: TMS320VC5502TMS320VC5402
Other Parts Discussed in Thread: TEST2, TMS320VC5502

Tool/software: Code Composer Studio

I converted a CCS 3.2 project to CCS 8.0. The converted project throws the following error:

error #175: floating-point value does not fit in required integral type

The error occurs when a type cast is performed on a floating-point constant that is "near" the upper range of a 32-bit signed integer (long). The compiler whines when the floating-point value is between (LONG_MAX - 64) and LONG_MAX. The compiler is happy with integer constants in this range. Here are some examples:

long test1 = (long)2147483583; // OK

long test2 = (long)2147483583.0; // OK

long test3 = (long)2147483583.9; // OK

long test4 = (long)2147483584.0; // error #175

long test5 = (long)2147483584; // OK

long test6 = (long)2147483646; // OK

long test7 = (long)2147483646.0; // error #175

long test8 = (long)2147483646.9; // error #175

long test9 = (long)2147483647.0; // error #175

long test10 = (long)2147483647; // OK

These results were produced with v4.4.1 of cl55.exe.

Is this a compiler bug or a new, stricter interpretation of some implicit conversion rule?

  • Joe,

    Are you using a VC5402 device? The reason I ask is that the compiler referenced (cl55.exe) in the post is for C55x devices vs C54x devices. The last CCS version to support C54x development was CCSv5.5.

    Regards,
    John
  • I meant TMS320VC5502. I have corrected my post (except for E2E's filing of it) and I apologize for the confusion.
  • No problem. I just wanted to check on that before I loop in a compiler expert. I will do that now.

    John
  • Thank you for informing us of this problem.  I can reproduce the same behavior.  The C5500 compiler is inactive.  Bugs are no longer fixed.  However, the C2000 compiler, which is supported, has the same problem.  So I filed CODEGEN-4690 in the SDOWP system against both compilers.  The cause of the problem is almost certainly the same in both compilers.  Fixing it in the C2000 compiler may (no guarantee!) reveal a workaround for the C5500 compiler.  You are welcome to track the issue with the SDOWP link below in my signature.

    Thanks and regards,

    -George

  • The problem here is that C5500 represents all three floating-point types (float, double, and long-double) in 32-bit IEEE format.  That does not provide enough precision to exactly represent 2147483583.0, etc.  As it happens, when converted from text to 32-bit IEEE and then to integer, 2147483583.0 ends up less than LONG_MAX, but 2147483584.0 ends up greater than LONG_MAX.  (Specifically, 2147483520 and 2147483648.  Note that 2147483520 is 24 1-bits, and 32-bit IEEE has a 24-bit mantissa.)

    I have no answer as to why you didn't have the same problem with CCS 3.2.  Possibly something changed during the conversion process, possibly the problem was ignored by the earlier compiler, possibly something else is different.

    C2000 also uses 32-bit IEEE for float and double, but it uses 64-bit IEEE for long-double.  For that platform, 2147483583.0L is the way to specify a constant that converts cleanly to long.  Unfortunately, C5500 has no 64-bit floating-point type and that technique can't be used.

  • Maybe the thing to do is convert LONG_MAX to float, store that somewhere, and in your conversion by typecasting, first test against that floating point value. Something like this for positive numbers:

    const float LongMaxAsFloat = (float) LONG_MAX;
    
    long ConvertFloatToLong(float Float)
    {
    	if (Float >= LongMaxAsFloat)
    		return LONG_MAX;
    	
    /* probably need some handling for negative numbers, too */

    return (long) Float; }

  • Dear pf:

    Thank you for following-up. This problem appeared in a #define macro that converts floating-point constants to fixed-point integer representations (for example: #define Q30(x) ...). It may be that the old compiler truncated the mantissa to 24 bits without complaint and the new compiler treats it as an error. I will try to add some bit masking and bit shifting to the macro to make it work with the new compiler.

    Joe

  • Dear twelve12pm:

    Thank you for the response. My float <--> integer conversion is taking place in a #define macro at compile time, rather than at run time. I will see if a more elaborate macro addresses the problem.