ISF  2.2 rev 5
Intelligent Sensing Framework for Kinetis with Processor Expert
Ac_Fixed_utils.c
Go to the documentation of this file.
1 /*!
2 ********************************************************************************
3 * File: Ac_Fixed_utils.c
4 *
5 * Copyright (c) 2015, Freescale Semiconductor, Inc.
6 *
7 *******************************************************************************/
8 
9 #include "Ac_Fixed_utils.h"
10 
11 typedef union {
12  float fN;
15 
16 #define IEEE754_MANTISSA_MASK (0x7fffff)
17 #define IMPLICIT_ONE (0x800000)
18 #define IEEE754_EXPONENT(n) ((int32)((n)>>23) & 0xff)
19 #define IEEE754_MANTISSA(n) ((int32)(n) & IEEE754_MANTISSA_MASK)
20 #define IEEE754_SIGN(n) (((uint32)(n))>>31)
21 
22 uint32 float32_To_AcFixed(float fN, uint8 W, uint8 I, uint8 S, int32 *status)
23 {
25  uint32 n;
26  int32 m,e,shift;
27 
28  cB.fN = fN;
29  m = IEEE754_MANTISSA(cB.iN); /* mantissa */
30  e = IEEE754_EXPONENT(cB.iN); /* exponent */
31  n = IEEE754_SIGN(cB.iN); /* negative (sign bit is set) */
32 
33  /* add implicit 1 if exponent is not zero */
34  if (e) m |= IMPLICIT_ONE;
35 
36  /* remove 127 bias for true exponent */
37  e -= 127;
38 
39  /* compute amount to shift to get to the specified fixed format */
40  shift = (I - e - 1) + (24 - W);
41 
42  /* If shift is not enough to move the "1" into the
43  ** valid bit range for the specified format, the
44  ** original number is too large to fit.
45  ** Report the error.
46  */
47  if (shift < (24 - W + S)) (*status)++;
48 
49  m >>= shift;
50 
51  /* change sign if float was negative and fixed format specifies a sign bit */
52  if (n && S) m = -m;
53 
54  return (uint32)m;
55 }
56 
57 
58 #ifdef COMPILE_TEST_FUNCTIONS
59 
60 typedef struct {
61  float num;
62  uint8 W;
63  uint8 I;
64  uint8 S;
65 } AcFixed_t;
66 
67 // This is by no means a complete test suite- simply a few numbers to check the
68 // operation
69 static AcFixed_t fnums[] = {
70  { .num= 15.356789, .W=16, .I=2, .S=0},
71  { .num= 1.356789, .W=16, .I=2, .S=0},
72  { .num= 0.00356789,.W=16, .I=2, .S=0},
73  { .num= 500.0, .W=16, .I=8, .S=1},
74  { .num=-500.0, .W=16, .I=8, .S=1},
75  { .num= 1.0, .W=16, .I=8, .S=1},
76  { .num= -1.0, .W=16, .I=8, .S=1},
77  { .num= 2.5, .W=16, .I=8, .S=1},
78  { .num= -2.5, .W=16, .I=8, .S=1},
79  { .num= 37.5, .W=16, .I=8, .S=1},
80  { .num= 112.9875, .W=16, .I=8, .S=1},
81  { .num= 360.0, .W=16, .I=8, .S=1},
82  { .num= 249.1231232, .W=16, .I=8, .S=1},
83  { .num= -45.965, .W=16, .I=8, .S=1},
84  { .num= -27.8, .W=16, .I=8, .S=1},
85  { .num= -25.0, .W=16, .I=8, .S=1},
86  { .num=-279.2, .W=16, .I=8, .S=1},
87  { .num=-360.0, .W=16, .I=8, .S=1}
88 };
89 
90 void test_fixed_point()
91 {
92  int32 st;
93  uint16 fixedPt;
94  int i;
95 
96  for (i=0; i < sizeof(fnums)/sizeof(AcFixed_t); i++ )
97  {
98  fixedPt = (uint16) float32_To_AcFixed(fnums[i].num, fnums[i].W, fnums[i].I, fnums[i].S, &st);
99  };
100 }
101 #endif
unsigned char uint8
Definition: isf_types.h:76
#define IEEE754_MANTISSA(n)
#define IMPLICIT_ONE
#define IEEE754_SIGN(n)
signed long int int32
Definition: isf_types.h:74
unsigned short int uint16
Definition: isf_types.h:77
unsigned long int uint32
Definition: isf_types.h:78
uint32 float32_To_AcFixed(float fN, uint8 W, uint8 I, uint8 S, int32 *status)
This function converts an IEEE-754 32-bit floating point number into a fixed point integer format...
#define IEEE754_EXPONENT(n)