fixed point implementation c++, problem in calling a static member function

hello all i am doing fixed point implementation in c++ which is done by the following code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
#ifndef __fixed_point_header_h__
#define __fixed_point_header_h__

#include <boost/assert.hpp>
#include <boost/static_assert.hpp> 
#include <boost/operators.hpp>
#include <limits>
#endif
namespace fp {
	template<typename FP, unsigned char I, unsigned char F = std::numeric_limits<FP>::digits - I>

	class fixed_point: boost::ordered_field_operators<fp::fixed_point<FP, I, F>  >
	{     
	BOOST_CONCEPT_ASSERT((boost::Integer<FP>)); 

	BOOST_STATIC_ASSERT(I + F == std::numeric_limits<FP>::digits); 
	
	 
template<int P,typename T = void> 
	struct power2
	{
		static const long long value = 2 * power2<P-1,T>::value;
	};

	template <typename P>
	struct power2<0, P>
	{
		static const long long value = 1;
	};
    
	
	fixed_point(FP value,bool): fixed_(value){ } // initializer list
	
    public:
	typedef FP base_type; ///  fixed point base type of this fixed_point class.
	static const unsigned char integer_bit_count = I; ///  integer part bit count.
	static const unsigned char fractional_bit_count = F; /// fractional part bit count.
    
	fixed_point(){ } /// Default constructor.

   
	//Conversion by constructors.

	//Integer to Fixed point

	template<typename T> fixed_point(T value) : fixed_((FP)value << F)
   {
    BOOST_CONCEPT_ASSERT((boost::Integer<T>)); 
    }
	// Converting constructor.
	//!
	//! This constructor takes a numeric value of type bool and converts it to 
	//! this fixed_point type.
	fixed_point(
		/// The value to convert.
		bool value)
		: fixed_((FP)(value * power2<F>::value))
	{ }
	
	fixed_point(float value) :fixed_((FP)(value * power2<F>::value))
    { }
    
	fixed_point(double value) : fixed_((FP)(value * power2<F>::value))
    { }

    fixed_point(long double value) : fixed_((FP)(value * power2<F>::value))
    { }
     
	/// Copy constructor,explicit definition
	fixed_point(
		/// The right hand side.
		fixed_point<FP, I, F> const& rhs)
		: fixed_(rhs.fixed_)
	{ }

	// copy-and-swap idiom.

    /// Copy assignment operator.
	fp::fixed_point<FP, I, F> & operator =(fp::fixed_point<FP, I, F> const& rhs)
	{
	fp::fixed_point<FP, I, F> temp(rhs); 
	swap(temp); .
	return *this;  //return by reference
    }
	/// Exchanges the elements of two fixed_point objects.
	void swap(
		/// The right hand side.
		fp::fixed_point<FP, I, F> & rhs)
	{
		std::swap(fixed_, rhs.fixed_);
	}
      
	bool operator <(
		/// Right hand side.
		fp::fixed_point<FP, I, F> const& rhs) const
	{
		return 
			fixed_ < rhs.fixed_;  //return by value
	}

	bool operator ==(
		/// Right hand side.
		fp::fixed_point<FP, I, F> const& rhs) const
	{
		return 
			fixed_ == rhs.fixed_; //return by value
    }
	/// Negation operator.
	bool operator !() const
	{
		return fixed_ == 0; //return true if equal to zero, false otherwise.
	}	
	/// Unary minus operator.
	
	
	fp::fixed_point<FP, I, F> operator -() const
	{
		fp::fixed_point<FP, I, F> result;
		result.fixed_ = -fixed_;
		return result;     // return The negative value.
	}

	/// Addition.
	
	fp::fixed_point<FP, I, F> & operator +=(fp::fixed_point<FP, I, F> const& summation)
	{
		fixed_ += summation.fixed_;
		return *this; //! /return A reference to this object.
	}

	/// Subtraction.
	
	fp::fixed_point<FP, I, F> & operator -=(fp::fixed_point<FP, I, F> const& subtraction)
	{
		fixed_ -= subtraction.fixed_;
		return *this;  // return A reference to this object.
	}
	

   /// Multiplication.
	
		
	fp::fixed_point<FP, I, F> & operator *=(
		/// Factor for mutliplication.
		fp::fixed_point<FP, I, F> const& factor)
	{
		
	fixed_ = ( fixed_ * (factor.fixed_ >> F) ) +
		( ( fixed_ * (factor.fixed_ & (power2<F>::value-1) ) ) >> F );

		return *this;   //return A reference to this object.
	}

	/// Division.
	
	
	fp::fixed_point<FP, I, F> & operator /=(
		/// Divisor for division.
		fp::fixed_point<FP, I, F> const& divisor)
	{
        
	fp::fixed_point<FP, I, F> fp_z=1;
        
	fp_z.fixed_ = ( (fp_z.fixed_) << (F-2) ) / ( divisor.fixed_ >> (2) );
	*this *= fp_z;

	return *this;   //return A reference to this object

	}
    friend fp::fixed_point<FP, I, F> fmod(fp::fixed_point<FP, I, F> a,fp::fixed_point<FP, I, F> b)
	{
		fp::fixed_point<FP, I, F> result;
		
		result.fixed_ = a.fixed_ % b.fixed_ ;
		return result;
	}
	 
	//cos_sin cordic function
	static fp::fixed_point<FP, I, F> cossin_cordic(fp::fixed_point<int, 15> beta, int n)
    //beta angle in radians
    //n number of iterations
  {
     # define ANGLES_LENGTH 60 //local parameter
     # define KPROD_LENGTH 33  //local parameter

	//Initialization of tables of constants used by CORDIC
    //need a table of arctangents of negative powers of two, in radians: atan(2.^-(0:59));

    fp::fixed_point<FP, I, F> angle;
    fp::fixed_point<FP, I, F> angles[ANGLES_LENGTH] = {
    7.8539816339744830962E-01, // arctan(2.^(0))
    4.6364760900080611621E-01, // arctan(2.^(-1))
    2.4497866312686415417E-01, 
    1.2435499454676143503E-01, 
    6.2418809995957348474E-02, 
    3.1239833430268276254E-02, 
    1.5623728620476830803E-02, 
    7.8123410601011112965E-03, 
    3.9062301319669718276E-03,}; 
	
	//A table of products of reciprocal lengths of vectors [1, 2^-2i]: 1 / sqrt ( 1 + (1/2)^(2i) ).
	fp::fixed_point<FP, I, F> kprod[KPROD_LENGTH] = {    
    0.70710678118654752440, 
    0.63245553203367586640, 
    0.61357199107789634961, 
    0.60883391251775242102, 
    0.60764825625616820093, 
    0.60735177014129595905, 
    0.60727764409352599905, 
    0.60725911229889273006, 
    0.60725447933256232972, 
    0.60725332108987516334, 
    0.60725303152913433540, 
    0.60725295913894481363, 
     };
	double pi = 3.141592653589793;
	int j;
	double sign_factor;
	fp::fixed_point<FP, I, F> factor;
    fp::fixed_point<FP, I, F> poweroftwo;
	fp::fixed_point<FP, I, F> sigma; 
	fp::fixed_point<FP, I, F> c2;
    fp::fixed_point<FP, I, F> s2;
   // fp::fixed_point<FP, I, F> theta;
	
	//  Shift angle to interval [-pi/2,pi/2] and account for signs.
	 if ( beta < - 0.5 * pi )
	 {
     beta = beta + pi;
     sign_factor = -1.0;
     }
     else if ( 0.5 * pi < beta)
     {
     beta = beta - pi;
     sign_factor = -1.0;
     }
     else
     {
     sign_factor = +1.0;
     }
	
	 //  Initialize loop variables: start with 2-vector, cosine of 1 and sine of zero
	 fp::fixed_point<FP, I, F> c= 1.0;   //c will give the value cos(beta)
	 fp::fixed_point<FP, I, F> s= 0.0;  //s will give the value sin(beta)
	
	 poweroftwo = 1;
	 angle =angles[0];
	
	//  Iterations
	for ( j = 1; j <= n; j++ )
    {
    if ( beta < 0.0 )     
      {
      sigma = -1.0;     //theta is -ve sigma is -ve
      }
    else
      {
      sigma = 1.0;    //theta is +ve sigma is +ve
      }
	 
	 factor = sigma * poweroftwo; //used in matrix multiplication
	 
	 //2-by-2 matrix multiplication
	 c2 = c - factor * s;  
	 s2 = factor * c + s;
	 
	 c = c2;
     s = s2; 
	
	 beta = beta - sigma * angle; // update the remaining angle
	 poweroftwo = poweroftwo / 2;
		
	//  Update the angle from table, or eventually by just dividing by two.

    if ( ANGLES_LENGTH < j + 1 )
    {
      angle = angle / 2.0;
    }
    else
    {
      angle = angles[j];
    }
  }
  
   //   Adjust length of output vector to be [cos(beta), sin(beta)]
  
   //  KPROD is essentially constant after a certain point, so if n is
   //  large, just take the last available value.
  
	c = c * kprod [ std::min ( n, KPROD_LENGTH )  ];
	s = s * kprod [ std::min ( n, KPROD_LENGTH )  ];
    
  
   return c;
   return s;
  # undef ANGLES_LENGTH
  # undef KPROD_LENGTH
}
	
	
private:
	/// The value in fixed point format.
	FP fixed_;
 };

} // namespace fmpl

#endif

#endif // __fixed_point_h__ 


the problem is when i call the cossin_cordic static member function from the test file given below
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <stdio.h>
#include <cmath>
#include "fixed_point_header.h"
int main()
{
{
     fp::fixed_point<int, 15> fp1 = -3.141592654; // -180°
      for ( int n = 0; n <= 25; n = n + 5 )
       {
   float cos_sin=fp::fixed_point<int, 15>::cossin_cordic(fp1,n);
   printf( "the values are %f\n", float (cos_sin));
  	  }
  	  } 
}

i am getting the error ambiguous overload for âoperator<â in âbeta < ((-5.0e-1) * pi)â
i know the problem the static member function cannot access the members and objects of structs. am i right?

and how to solve this problem, do i need to implement the cossin_cordic function as a non member function.
could someone please help me hw to proceed?


Last edited on
I believe that it means that the compiler cannot differentiate between this operator or function and another.
The error says line 227 is ambiguous.
if ( beta < - 0.5 * pi )

Doesn't it say what the candidates are?
Considering that this won't compile due to quite a few things before the error you are talking about, I cannot comment.

Post code that is at least syntactically correct and then we'll talk. Maybe you pasted your header file incorrectly.

Looks similar to another fixed point lib I saw just recently.

http://www.codeproject.com/Articles/37636/Fixed-Point-Class
@pogrady the compiler cannot access the overloaded operators < , + , - etc,.in the struct as i mentioned the function cossin_cordic as a static member function.

Should i declare as a non static member function or how should i proceed? can you please help me?
Last edited on
i tried cossin_cordic as a non static member function, but as a member function i am getting the
error cossin_cordic was not declared in this scope in Test file.



Last edited on
@peter87 it is saying

candidates are:
operator<(const float, double) <built-in>
operator<(const double, double) <built-in>
operator<(const long double, double) <built-in>
operator<(long long int, double) <built-in>
@coder777do i need to use cossin_cordic as a free function rather than using it as member function. if yes, how do i proceed? can some one please help, i would be greateful!
Last edited on
I can see one potential problem is i have no operator< that takes fixed_point on the LHS and double on the RHS.

so do i do i need to replace all the double,int parameters with the fixedpoint type in cossin_cordic function
I'm not sure why you operator< is not one of the candidates.

What is inheriting from boost::ordered_field_operators doing? Maybe that somehow causes problems.

Does it work if you convert the rhs to fixed_point type?
if ( beta < fp::fixed_point<int, 15>(- 0.5 * pi) )
yes i tried the same and it works,
the problem is operator< does not takes fixed_point on the LHS and double on the RHS.

when it is fixed_point objects on both the LHS and RHS, it works fine.
I don't know what boost::ordered_field_operators does but if it makes the fixed_point implicit convertible to float, double, long double and long long that could be the problem. In that case you should probably overload operator< for these types too.
Last edited on
@Peter87as far as i know the boost field operators implement a few operators directly, the others are generated automatically via the ordered_field_operators
//!
//! The ordered_field_operators template takes and generates (==>) the
//! following operators:
//! += ==> + (addable),
//! -= ==> - (subtractable),
//! *= ==> * (multipliable),
//! /= ==> / (dividable),
//! < ==> > , >=, <= (less_than_comparable),
//! == ==> != (equality_comparable).
Last edited on
when i change all the parameters in the cossin_cordic function to the fixed_point types it is working fine and i am getting the results as i expect.

But in the test file how do i print both the return values ie. c, s from the cossin_cordic function.

the below test file prints the cos of fp1
1
2
3
4
5
6
7
8
9
int main()
{
fp::fixed_point<int, 15> fp1 =3.141592654;
for ( int n = 0; n <= 25; n = n + 5 )
   {
   float cos=fp::fixed_point<int, 15>::cossin_cordic(fp1,n);
   printf( "fixedpoint values of cos are %f\n", float (cos));
    }
}

but i need to print the sin value also returned from the cossin_cordic function, so how should i change the test file. can you please help?
Last edited on
i think i need to seperate the cossin_cordic function as cos_cordic and sin_cordic function and return c in the cos_cordic function and return s in the sin_cordic function. am i right? please correct me if am not
Topic archived. No new replies allowed.