Overflow in C++ SUM implementation?

Hello,

I am working on implementing a strategy in C++ and I have successfully implemented quite a few now. The one I am currently working involves using the SUM() function. I am working my own C++ implementation of it but I am stuck on handling the numbers that get too large, how does AmiBroker handle these? My implementation is quite close to matching my C++ implementation but there are certain sections of my SUM() results where the numbers go negative, assuming this is overflow.

I have tried using doubles in C++ but it crashes AmiBroker when I run the plugin. Any insight would be greatly appreciated.

I guess you used integers if you say that "numbers go negative" because only in integers you would see that kind of overflow behavior.

You should be using float or double type for running sum. When you return value, you have to return float.

1 Like

I appreciate the quick response.

I am using float, I just thought floats could overflow as well my apologies. When I was trying to use doubles I was returning as doubles, I will try to return as floats. Thank you.

I am still receiving the same result. Here are the two ways I have tried to implement:

My method:
AmiVar nvrn = gSite.AllocArrayResult();
double *runningSum = new double[nSize];
for(int i = period-1; i < nSize;i++){
for(int j = i; j >= i-period+1; j--)
runningSum[i] += Upvolume.array[j];
}
for(int i = 0;i<nSize;i++)
nvrn.array[i] = runningSum[i];

Another method (this is throwing an exception for me, I used array for the period parameter because SUM is a variable period function:

    AmiVar nvrn = gSite.AllocArrayResult();
AmiVar sumArgs[2];
float *sumArgsList = new float[nSize];
for(int i = 0; i < nSize;i++){
	sumArgsList[i] = period.val;
}
sumArgs[0] = Upvolume;
sumArgs[1].type = VAR_ARRAY;
sumArgs[1].array = sumArgsList;
nvrn = gSite.CallFunction("Sum",2,sumArgs);

Here are snapshots of the data using 'Explore':
My data is on the left, the AFL implementation is on the right. Everything matches up except for one section, this is the same pattern through all quotes.
Capture

@CodySigvartson,

You need to initialize the values in the runningSum array to zero before using it.

Also, check for Null values in your data. Null values equal -1e10.

Subtract 1e10 from the values on the right and you will get the negative values shown on the left.

It’s also good practice to cast double to float like this:

nvrn.array[i] = (float)runningSum[i];

-Alan

1 Like

Use example codes shipped with ADK that explain how to write plugins.

Open up Sample/Functions.cpp and learn from the code that I wrote as a guidance for people. It has a function (called SkipEmptyValues()) that should be used in ALL of your functions that skips empty values that usually occur in the beginning of arrays.

Do NOT hard code -1e10. This value MAY CHANGE in the future. You should use macros instead. There are macros EMPTY_VAL, IS_EMPTY( x ) and NOT_EMPTY( x ) defined in Plugin.h that one should use to detect empty values.

Example codes show precisely how one should write things. As I wrote open up examples and learn from them. Excerpt from Sample/Functions.cpp:

// Helper function
// to skip empty values  returns index of first non-null element
int SkipEmptyValues( int nSize, float *Src, float *Dst )
{
	int i;

	for( i = 0; i < nSize && IS_EMPTY( Src[ i ] ); i++ )
	{
		Dst[ i ] = EMPTY_VAL;
	}

	return i;
}
2 Likes

Thanks for both of your help, I was able to get it working as expected.