The following code is meant to calculate 7 terms: tcapneg, tcappos, tneg1, tneg2, tpos1, tpos2, tzcap (only the calculation of tpos1 and tpos2 is shown here), and determine the entry that satisfies the condition of being the smallest positive non-zero entry.
int hitb;
double PCLx = 2.936728;
double PCLz = -0.016691;
double PDCx = 0.102796;
double PDCz = 0.994702;
double q = 0.002344;
double s = 0.0266;
double v = 0.0744;
double a = -q * PDCx * PDCx;
double b = s * PDCx - 2 * q*PCLx*PDCx - PDCz;
double c = -1.0*(PCLz q * pow(PCLx, 2) - s * PCLx v);
double d = b * b - 4 * a*c;
if (d >= 0.0f) // only take solution if t real
{
tpos1 = (-b sqrt(d)) / (2 * a);
tpos2 = (-b - sqrt(d)) / (2 * a);
}
printf("\n %f %f %f %f %f %f %f", tcapneg, tcappos, tneg1, tneg2, tpos1, tpos2, tzcap);
yielding the result:
0.000000 0.000000 -40326.381162 -0.156221 -40105.748386 0.000194 0.016780
It is seen that the expected result should be smallest = tpos2 = 0.000194.
double smallest = -1.0;
double tlist[7] = { tcapneg, tcappos, tneg1, tneg2, tpos1, tpos2, tzcap };
const int size = sizeof(tlist) / sizeof(int);
for (int i = 0; i < size; i )
{
if (tlist[i] > EPSILON && (smallest == -1.0 || tlist[i] < smallest))
{
smallest = tlist[i];
}
}
printf("\n %f", smallest);
The output for smallest = 0.000192, thus smallest != tpos2 != 0.00194. Why is there this small change in value for the selected smallest entry?
The result of smallest will be fed to the following code:
if (smallest == tneg1 || smallest == tneg2)
{
hitb = 1;
}
else if (smallest == tpos1 || smallest == tpos2)
{
hitb = 2;
}
else if (smallest == tcappos)
{
hitb = 3;
}
else if (smallest == tcapneg)
{
hitb = 4;
}
else if (smallest == tzcap)
{
hitb = 5;
}
In this case, we should satisfy the condition to write hitb = 2, however this is failing due to the inequality above.
CodePudding user response:
Probably you never iterate over the last elements of the array: you calculate the size as sizeof(double*) / sizeof(int)
which is not true. Just use std::vector
type for an array and iterate over it using iterator types:
std::vector<double>tlist = ...
for(auto i = tlist.begin(); i != tlist.end(); i )
{
double v = (*i);
/* ... */
}
Also you should thoroughly check the logic of your condition: is EPSILON positive?
CodePudding user response:
Your array double tlist[7]
is in double
with 7 elements. sizeof(double) is 8, so sizeof(tlist)
is 8*7 = 56
. While sizeof(int)
is 4, so your size = sizeof(tlist) / sizeof(int)
is 56/4 = 14
. Your loop goes beyond number of elements in the array. It counts 7 more double values after the array in memory, because the array name is used as a pointer
.
Here is my code to verify the above nanalysis
#include <iostream>
using namespace std;
int main()
{
double da[7] = {0.0, 0.0, -40326.381162, -0.156221, -40105.748386, 0.000194, 0.016780};
const int sda = sizeof(da);
const int sin = sizeof(int);
const int siz = sda/sin;
cout << "sda:" << sda << " sin:" << sin << " siz:" << siz << endl;
for( int i=0; i<siz; i ) {
cout << "da[" << i << "] = " << da[i] << endl;
}
return 0;
}
Here is the output
sda:56 sin:4 siz:14
da[0] = 0
da[1] = 0
da[2] = -40326.4
da[3] = -0.156221
da[4] = -40105.7
da[5] = 0.000194
da[6] = 0.01678
da[7] = 2.07324e-317
da[8] = 8.48798e-314
da[9] = 1.9098e-313
da[10] = 0
da[11] = 1.31616e-312
da[12] = 0
da[13] = 6.95332e-310
The correct code is
size = sizeof(tlist) / sizeof(double);
Use the following option for GCC to report runtime error
in this case
g -fsanitize=bounds -o main.e main.cpp