Technical Support
Support Resources
Product Information
Information in this knowledgebase article applies to:
I'm using a Cortex-M4 based target device and now want to convert
floating point variables to rounded integer numbers, for example:
float fvalue = 99.999f;
int32_t i32value;
int main(void)
{
i32value = fvalue; // result 99 instead of 100
.....
The ARMCC v5.x compiler I'm using translates the code above as
follows:
VLDR s0,[r0,#0]
VCVT.S32.F32 s0,s0
LDR r0,|L3.304|
VSTR s0,[r0,#0]
The value of i32value is truncated and rounded to 99, instead of
100. Is it possible to make the compiler use the VCVTR instruction
instead of VCVT to get the rounded value 100, instead of 99?
First of all, note that according to the C99 standards, all
conversions from float to integer are truncated.
As written here "VCVT, VCVTR between floating-point and integer",
the floating-point to integer operation normally uses the Round
towards Zero rounding mode, but can optionally use the rounding mode
specified by the FPSCR.
In order to have VCVTR instead of VCVT, you can use the function
_ffix_r().
Moreover, you can use these two C99 functions fegetround() and fesetround() to get and set a
different round mode.
For example:
#include <math.h>
#include <rt_fp.h>
#include <fenv.h>
...
int mode = fegetround();
i32value = _ffix_r(fvalue); // result 100 instead of 99
fesetround(mode);
...
This can enable you to use one round mode for only one conversion.
You can also use fesetround() to change the round mode for the entire
project.
Note that in order to use fegetround() and fesetround(), the
Microlib option in µVision should be disabled.
Last Reviewed: Wednesday, December 7,.