ambiguous overload for 'operator+' when typecasting from unsigned char to a fixed point data type

306 views Asked by At

I implementing an image processing algorithm on vivado hls, as a part of optimization, I am trying to change the floating point representation into fixed point representation.

Here is the part where it is going wrong

#include <ap_fixed.h>
unsigned char win[3][3];
typedef ap_ufixed<11,8> fix;
struct pixel_f
{
    fix r;
    fix g;
    fix b;
};
pixel_f new_pix;
.
.
.
.
.

new_pix.r = ((fix)(win[1][0] + win[1][2]) / 2)+0.5;

when I tried to execute it, it is giving me an error saying

demosiac_core.cpp:16:49: error: ambiguous overload for 'operator+' (operand types are 'ap_fixed_base<11, 8, false, (ap_q_mode)5u, (ap_o_mode)3u, 0>::RType<32, 32, true>::div {aka ap_fixed<12, 9, (ap_q_mode)5u, (ap_o_mode)3u, 0>}' and 'double')
   new_pix.r = ((fix)(win[1][0] + win[1][2]) / 2)+0.5;

can someone help me with any suggestions related to why it is going wrong and what can be done to make this work??

Thanks in advance,

1

There are 1 answers

1
john On

Looking at the header files it seems the problem is that the ap_ufixed class has both a constructor that takes a double i.e. fix::fix(double), and an operator that converts to a double i.e. fix::operator double(). But it does not define an addition operator that takes a fix and a double, i.e. there is no operator+(fix, double).

So when code like this is being compiled

fix x = ...;
double y = ...;
fix z = x + y;

the compiler doesn't know whether to convert y to fix and add two fix values, or whether to convert x to a double and add two double values. That what the ambiguity in the compiler error message is refering to.

The solution is to say precisely what you want, if you want that addition to add two fix values then write this

new_pix.r = ((fix)(win[1][0] + win[1][2]) / 2)+ fix(0.5);

if you want the addition to add two double values (seems less likely) then write this

new_pix.r = (double)((fix)(win[1][0] + win[1][2]) / 2) + 0.5;

or maybe you want to rewrite the expression entirely. I can't see why this wouldn't do the same as your code (get the average of win[1][0] and win[1][2] but rounding up) but in a simpler and more efficient way

new_pix.r = (win[1][0] + win[1][2] + 1) / 2;

Incidentally it seems there are operators defined that take integer values, which is why the / 2 in your code doesn't cause the same problem.