Help please, strange behavior

S

Simply_Red

i'm sorry i posted this in other groupes, and i didn't see it, and as
this group is most actif, i repost it here, and sorry for
mutliposting:

Hi,
i'm using VC6, i have this declaration:

typedef struct tagTLimite {
double Debut;
double Fin;
}Limites;

typedef struct TagElemTab {
double NivY;
bool Existe;
std::vector<Limites> PtLimites;
}ElemTabCont;

void myfunc( )
{
......
ElemTabCont * ContNonOrd;//contour non ordone
long nbNiveau = (yhi-ylo)/stepY +1 ;
ContNonOrd = new ElemTabCont [nbNiveau];
......
}
i don't know why,nbNiveau is equal to (yhi-ylo)/stepY, it didn't
+1????and even if i put:
ContNonOrd = new ElemTabCont [nbNiveau+1]; the size of ContNonOrd =
nbNiveau????
 
V

Victor Bazarov

Simply_Red said:
i'm sorry i posted this in other groupes, and i didn't see it, and as
this group is most actif, i repost it here, and sorry for
mutliposting:

Hi,
i'm using VC6, i have this declaration:

typedef struct tagTLimite {
double Debut;
double Fin;
}Limites;

typedef struct TagElemTab {
double NivY;
bool Existe;
std::vector<Limites> PtLimites;
}ElemTabCont;

void myfunc( )
{
.....
ElemTabCont * ContNonOrd;//contour non ordone
long nbNiveau = (yhi-ylo)/stepY +1 ;

What is the type of 'yhi', 'ylo', 'stepY'? What are their values?
What value do you get in 'nbNiveau'? What did you expect?

It is possible that you're encountering rounding (truncation in
case of integer division) and adding 1 doesn't do what you need
it to do.
ContNonOrd = new ElemTabCont [nbNiveau];
.....
}
i don't know why,nbNiveau is equal to (yhi-ylo)/stepY, it didn't
+1????and even if i put:
ContNonOrd = new ElemTabCont [nbNiveau+1]; the size of ContNonOrd =
nbNiveau????

That last statement is beyond me. What do you mean by "the size of
ContNotOrd"? How the hell can you know the size? How can it be
different from the size you requested?

V
 
S

Simply_Red

Simply_Redwrote:








What is the type of 'yhi', 'ylo', 'stepY'? What are their values?
What value do you get in 'nbNiveau'? What did you expect


yhi, ylo, stepY are doubles values: 16, 0, 0.1 respectively
I get 160 in nbNiveau, and I need 161.


?
It is possible that you're encountering rounding (truncation in
case of integer division) and adding 1 doesn't do what you need
it to do.
ContNonOrd = new ElemTabCont [nbNiveau];
.....
}
i don't know why,nbNiveau is equal to (yhi-ylo)/stepY, it didn't
+1????and even if i put:
ContNonOrd = new ElemTabCont [nbNiveau+1]; the size of ContNonOrd =
nbNiveau????

That last statement is beyond me. What do you mean by "the size of
ContNotOrd"? How the hell can you know the size? How can it be
different from the size you requested?


i just verify in watch window ContNotOrd[160].
 
R

red floyd

Simply_Red said:
i'm sorry i posted this in other groupes, and i didn't see it, and as
this group is most actif, i repost it here, and sorry for
mutliposting:

Hi,
i'm using VC6, i have this declaration:

typedef struct tagTLimite {
double Debut;
double Fin;
}Limites;

typedef struct TagElemTab {
double NivY;
bool Existe;
std::vector<Limites> PtLimites;
}ElemTabCont;
[redacted]

In addition to what Victor said to you, the definitions above are C-ish
and not really needed. They should be:

struct Limites {
double Debut;
double Fin;
};

struct ElemTabCont {
double NivY;
bool Existe;
std::vector<Limites> PtLimites;
};

No typedefs or "tag" names are necessary.
 
R

Rolf Magnus

Simply_Red said:
yhi, ylo, stepY are doubles values: 16, 0, 0.1 respectively
I get 160 in nbNiveau, and I need 161.

double isn't precise either. Note that 0.1 in binary is a periodic number
that cannot be represented exactly. So instead of 0.1, you get the closest
representable value. As a result, you might get something like
160.99999999998, which gets truncated to 160 when converted to long.
 
K

Kai-Uwe Bux

Simply_Red said:
i'm sorry i posted this in other groupes, and i didn't see it, and as
this group is most actif, i repost it here, and sorry for
mutliposting:

Hi,
i'm using VC6, i have this declaration:

typedef struct tagTLimite {
double Debut;
double Fin;
}Limites;

typedef struct TagElemTab {
double NivY;
bool Existe;
std::vector<Limites> PtLimites;
}ElemTabCont;

void myfunc( )
{
.....
ElemTabCont * ContNonOrd;//contour non ordone
long nbNiveau = (yhi-ylo)/stepY +1 ;
ContNonOrd = new ElemTabCont [nbNiveau];
.....
}
i don't know why,nbNiveau is equal to (yhi-ylo)/stepY, it didn't
+1????and even if i put:

How did you tell? Probably you misinterpret some output that we do not see
because your code snippet is incomplete.


and even if i put: ContNonOrd = new ElemTabCont [nbNiveau+1]; the size of
ContNonOrd = nbNiveau????

Again, how did you tell?


Please post a minimal complete program that shows the problem. With the code
fragments from above, there is no way to tell what the problem is
(especially since we do not even know the types of yhi, yhl, and stepY.


Best

Kai-Uwe Bux
 
S

Simply_Red

double isn't precise either. Note that 0.1 in binary is a periodic number
that cannot be represented exactly. So instead of 0.1, you get the closest
representable value. As a result, you might get something like
160.99999999998, which gets truncated to 160 when converted to long.

but if 160.999999998 is truncated to 160, 159.99999998 must be
truncated to 159.....
 
V

Victor Bazarov

Simply_Red said:
yhi, ylo, stepY are doubles values: 16, 0, 0.1 respectively
I get 160 in nbNiveau, and I need 161.

You have stumbled upon a well-known (now to you as well) situation
when 16/0.1 is not 160 (exactly) but rather 159.999999999999. Add
1 to it and you get 160.999999999999 and assign it to a 'long', you
get 160. It's called "imprecise representation of a decimal value"
and essentially all computers with binary FP units suffer from it.

To calculate those things "correctly", add 1.0000001 instead of 1:

long nbNiveau = (yhi-ylo)/stepY + 1.0000001;

It's not pretty, but it will work better. The number of zeros after
the decimal point depends on your 'yhi-ylo' scale.
?
It is possible that you're encountering rounding (truncation in
case of integer division) and adding 1 doesn't do what you need
it to do.
ContNonOrd = new ElemTabCont [nbNiveau];
.....
}
i don't know why,nbNiveau is equal to (yhi-ylo)/stepY, it didn't
+1????and even if i put:
ContNonOrd = new ElemTabCont [nbNiveau+1]; the size of ContNonOrd =
nbNiveau????

That last statement is beyond me. What do you mean by "the size of
ContNotOrd"? How the hell can you know the size? How can it be
different from the size you requested?


i just verify in watch window ContNotOrd[160].

I don't know how you do that, but tell me, if you do

int main() {
long nbNiveau = 160;
char *ContNotOrd = new char[nbNiveau + 1];
}

and "verify in watch window", do you get 160 or 161 _elements_? Do
not tell me the last index (it is less by 1 than the size, right?)

V
 
S

Simply_Red

yhi, ylo, stepY are doubles values: 16, 0, 0.1 respectively
I get 160 in nbNiveau, and I need 161.

You have stumbled upon a well-known (now to you as well) situation
when 16/0.1 is not 160 (exactly) but rather 159.999999999999. Add
1 to it and you get 160.999999999999 and assign it to a 'long', you
get 160. It's called "imprecise representation of a decimal value"
and essentially all computers with binary FP units suffer from it.

To calculate those things "correctly", add 1.0000001 instead of 1:

long nbNiveau = (yhi-ylo)/stepY + 1.0000001;

It's not pretty, but it will work better. The number of zeros after
the decimal point depends on your 'yhi-ylo' scale.


?
It is possible that you're encountering rounding (truncation in
case of integer division) and adding 1 doesn't do what you need
it to do.
ContNonOrd = new ElemTabCont [nbNiveau];
.....
}
i don't know why,nbNiveau is equal to (yhi-ylo)/stepY, it didn't
+1????and even if i put:
ContNonOrd = new ElemTabCont [nbNiveau+1]; the size of ContNonOrd =
nbNiveau????
That last statement is beyond me. What do you mean by "the size of
ContNotOrd"? How the hell can you know the size? How can it be
different from the size you requested?
i just verify in watch window ContNotOrd[160].

I don't know how you do that, but tell me, if you do

int main() {
long nbNiveau = 160;
char *ContNotOrd = new char[nbNiveau + 1];
}

and "verify in watch window", do you get 160 or 161 _elements_? Do
not tell me the last index (it is less by 1 than the size, right?)

V

when i give a value to ContNotOrd[161] i have a crash, and 160
no.....for my example i check the vector of the 160 elem, when there
is no pb it contain _First = 0 _Last = 0 _End = 0.
 
S

Simply_Red

Simply_Red said:
i'm sorry i posted this in other groupes, and i didn't see it, and as
this group is most actif, i repost it here, and sorry for
mutliposting:
Hi,
i'm using VC6, i have this declaration:
typedef struct tagTLimite {
double Debut;
double Fin;
}Limites;
typedef struct TagElemTab {
double NivY;
bool Existe;
std::vector<Limites> PtLimites;
}ElemTabCont;
void myfunc( )
{
.....
ElemTabCont * ContNonOrd;//contour non ordone
long nbNiveau = (yhi-ylo)/stepY +1 ;
ContNonOrd = new ElemTabCont [nbNiveau];
.....
}
i don't know why,nbNiveau is equal to (yhi-ylo)/stepY, it didn't
+1????and even if i put:

How did you tell? Probably you misinterpret some output that we do not see
because your code snippet is incomplete.
and even if i put: ContNonOrd = new ElemTabCont [nbNiveau+1]; the size of
ContNonOrd = nbNiveau????

Again, how did you tell?

Please post a minimal complete program that shows the problem. With the code
fragments from above, there is no way to tell what the problem is
(especially since we do not even know the types of yhi, yhl, and stepY.

Best

Kai-Uwe Bux

bool __declspec(dllexport) CALLBACK NewMakeContour(LPSAFEARRAY FAR
*saY, VARIANT FAR *pvArray, double yhi, double ylo,double stepX,double
stepY)
{

SAFEARRAYBOUND sabound[1]; // 1-D array
SAFEARRAY FAR* psa = NULL; // SAFEARRAY structure pointer
HRESULT hr; // Operations result
float HUGEP *vbY; // Tableau Contenant tous les points
long UboundY;
double V;
long ptTabRes,ptTabSource;

hr = SafeArrayAccessData(*saY, (void HUGEP**)&vbY);
UboundY = (*saY)->rgsabound[0].cElements;

ElemTabCont * ContNonOrd;//contour non ordone
long nbNiveau = (yhi-ylo)/stepY+1 ;// +1 ; je ne sais pas pourquoi il
ne me fait pas le + 1;
ContNonOrd = new ElemTabCont[nbNiveau];
//ContNonOrd = new ElemTabCont[161];//donc je suis obliger de le
faire ici

V = vbY[1];//le premier pt est un pt du contour
ptTabRes = 0;
ptTabSource = 0;
while (FRound(V,3) <= FRound(yhi,3))
{
FindLevelPt(vbY, ptTabSource,ContNonOrd,ptTabRes,V,UboundY,stepX);
ptTabRes++;
V+=stepY;
}
delete[] ContNonOrd;
hr = SafeArrayUnaccessData(*saY);
return true
}


void FindLevelPt(float* TabSource, long& ptTabSource,ElemTabCont*
ContNonOrd,long ptTabRes,double V, long UBoundY, float StepX) {

Limites XLimites;

ContNonOrd[ptTabRes].NivY = V;
//si on est au niv superieur a V=>pas de point au niveau V
if (FRound(TabSource[ptTabSource+1],3) == FRound(V,3))
{
ContNonOrd[ptTabRes].Existe = true;

bool nivDepasse = false;
bool terminer = false;
while (!nivDepasse && !terminer)
{
XLimites.Debut = TabSource[ptTabSource];

bool trouve = false;//true si on trouve la limite du segment
ptTabSource+=3;//le debut a ete deja trouver
while(!trouve && ptTabSource <= UBoundY-3) //-1 z, -2 y -3 x
{
nivDepasse = (FRound(TabSource[ptTabSource+1],3) > FRound(V,3));
trouve = (FRound(TabSource[ptTabSource]-TabSource[ptTabSource-3],
3)>FRound(StepX,3)) || nivDepasse ;
ptTabSource+=3;
}
if (trouve) {
XLimites.Fin = TabSource[ptTabSource-6];
ptTabSource-=3;//pour pointer au prochain debut.
ContNonOrd[ptTabRes].PtLimites.push_back(XLimites);
}
else {//le dernier pt ou la derniere ligne
terminer = true;
XLimites.Fin = TabSource[ptTabSource-3];
ContNonOrd[ptTabRes].PtLimites.push_back(XLimites);
}
}
}
else ContNonOrd[ptTabRes].Existe = false;
}
 
R

Rolf Magnus

Simply_Red said:
That last statement is beyond me. What do you mean by "the size of
ContNotOrd"? How the hell can you know the size? How can it be
different from the size you requested?
i just verify in watch window ContNotOrd[160].

I don't know how you do that, but tell me, if you do

int main() {
long nbNiveau = 160;
char *ContNotOrd = new char[nbNiveau + 1];
}

and "verify in watch window", do you get 160 or 161 _elements_? Do
not tell me the last index (it is less by 1 than the size, right?)

when i give a value to ContNotOrd[161] i have a crash,

That's not surprising. If nbNiveau is 160, then you allocate an array with
161 elements, numbered 0 to 160. So if you try to access the element with
index 161, you are going past the end of your array.
 
S

Simply_Red

when i just put long nbNiveau = (yhi-ylo)/stepY. i get nbNiveau = 160

i was wrong it's 159...........

and if i use float, is there pbs with the precision???
 
S

Simply_Red

That's not surprising. If nbNiveau is 160, then you allocate an array with
161 elements, numbered 0 to 160. So if you try to access the element with
index 161, you are going past the end of your array.

i know this, but my pb is that i need that nbNiveau = 161, and i get
160, i was sure that when the value is betwwen 160.51 and
160.99999999, in long the compilator will replace it with 160
 
S

Simply_Red

i know this, but my pb is that i need that nbNiveau = 161, and i get
160, i was sure that when the value is betwwen 160.51 and
160.99999999, in long the compilator will replace it with 160

i wanted to say: i was sure that when the value is betwwen 160.51 and
 
V

Victor Bazarov

Simply_Red said:
i was wrong it's 159...........

and if i use float, is there pbs with the precision???

Of course. Just like if you use 'double', only worse.

V
 
R

Rolf Magnus

Simply_Red said:
i wanted to say: i was sure that when the value is betwwen 160.51 and

Well, that's not the case. In C++, when converting a floating point value
into an integer, the fractional part is always truncated.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,537
Members
45,024
Latest member
ARDU_PROgrammER

Latest Threads

Top