Help please, strange behavior

S

Simply_Red

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

V

So i got to use:

float FRound(double f, BYTE b)
{
char sz[20];
char szFmt[5] = { '%','.','0'+b,'f', 0 };
sprintf(sz, szFmt, f);
return atof(sz);
}

and put :
long nbNiveau = FRound ((y1-y2)/y3+1,0);
 
S

Simply_Red

Well, that's not the case. In C++, when converting a floating point value
into an integer, the fractional part is always truncated.
now i know it, but what i found strange is that, if i put the same
instruction in watch window(debug), i get the result that i need. (yhi-
ylo)/stepy+1 became 161, in watch window and nbNiveau = 160
 
V

Victor Bazarov

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

V

So i got to use:

float FRound(double f, BYTE b)
{
char sz[20];
char szFmt[5] = { '%','.','0'+b,'f', 0 };
sprintf(sz, szFmt, f);
return atof(sz);
}

and put :
long nbNiveau = FRound ((y1-y2)/y3+1,0);

Ugh!... Please don't do that. For any 'f' greater than 1e10
it will overrun the buffer ('sz'), which is how security holes
get created/exploited.

What is your goal here? Is (y1-y2) very close to N * y3 or is
it arbitrary? If it's close, you can always try

long nbNiveau = (y1-y2)/y3 + 1; // your formula
if ((nbNiveau - 1) * y3 < (y1-y2)) // verify!
++nbNiveau; // bump it up!

V
 
V

Victor Bazarov

Simply_Red said:
now i know it, but what i found strange is that, if i put the same
instruction in watch window(debug), i get the result that i need.
(yhi- ylo)/stepy+1 became 161, in watch window and nbNiveau = 160

Apparently your "watch window" rounds it before outputting. Try

printf("%f", (yhi-ylo)/stepy+1)

and you're likely to see 161 as well. Conversion to text rounds
the value (and lies to you).

V
 
D

Default User

Simply_Red wrote:

i know this, but my pb is that i need

It's best to post in straight English with strange abreviations like
"pb". I assume you mean "problem", but that's not a standard
abreviation in English, except as the chemical name of lead.




Brian
 
R

Rolf Magnus

Default said:
Simply_Red wrote:



It's best to post in straight English with strange abreviations like
"pb". I assume you mean "problem", but that's not a standard
abreviation in English, except as the chemical name of lead.

V.E.R.A. offes "Pipeline Burst".
 
S

Simply_Red

Ugh!... Please don't do that. For any 'f' greater than 1e10
it will overrun the buffer ('sz'), which is how security holes
get created/exploited.

I don't understand what is le10???
What is your goal here? Is (y1-y2) very close to N * y3 or is
it arbitrary? If it's close, you can always try
long nbNiveau = (y1-y2)/y3 + 1; // your formula
if ((nbNiveau - 1) * y3 < (y1-y2)) // verify!
++nbNiveau; // bump it up!

Y1,Y2 and Y3 aren't arbitrary and i know that (y1-y2)/y3 = N
(integer).


and if i use:

long LRound(double f)
{
char sz[20];
char szFmt[5] = { '%','.','0','f', 0 };
sprintf(sz, szFmt, f);
return atol(sz);
}
 
S

Simply_Red

It's best to post in straight English with strange abreviations like
"pb". I assume you mean "problem", but that's not a standard
abreviation in English, except as the chemical name of lead.

Brian

Sorry, this abreviation is used in french.
 
H

Howard

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

True, but where did you get 159.99999998?

The problem is that, sometimes, the result of (yhi-ylo)/stepY will not be an
exact integer, because stepY may not be exactly representable in binary (as
a double or float). So sometimes your array size will be too small.

The solution for handling this depends on your goal. How are you later
using the array elements?

In your example, stepY is 0.1, or 1/10, which means you're expecting to get
(yhi-ylo)*10 = 160, right? Well, where does stepY come from? Can you
compute it from something like 1/numElementsPerUnit, where
numElementsPerUnit is an integer? If so, your code could change to:

nbNiveau = (yhi-ylo)*numElementsPerUnit + 1;
stepY = 1 / numElementsPerUnit;

That would avoid the issue entirely.

If stepY is not representable that way, and if yhi-ylo isn't too big, you
could just add 1.1 instead of 1 before truncating to an integer, but that's
not the prefered solution.

Victor's idea of "bumping up" the value might work for you, as well, if all
you care about is having "enough" elements in the array.

One thing to note: If you ever make calculations like (i-ylo)/stepY, or
simply i*stepY, then for large values of i the result will get further and
further from what you expect. But that's probably not be a problem for you,
since your values are small.

By the way, one thing I like to do when investigating problems involving
calculations like this is to store intermediate results to another variable,
like this:

double temp = (yhi-ylo)/stepY +1;
long nbNiveau = temp;

This lets you examine the values yourself when debugging, instead of trying
to guess what's going on inside the program.

Hope this helps...

-Howard
 
S

Simply_Red

True, but where did you get 159.99999998?

The problem is that, sometimes, the result of (yhi-ylo)/stepY will not be an
exact integer, because stepY may not be exactly representable in binary (as
a double or float). So sometimes your array size will be too small.

The solution for handling this depends on your goal. How are you later
using the array elements?

In your example, stepY is 0.1, or 1/10, which means you're expecting to get
(yhi-ylo)*10 = 160, right? Well, where does stepY come from? Can you
compute it from something like 1/numElementsPerUnit, where


I take the value of stepY from a database, i can't compute it.



numElementsPerUnit is an integer? If so, your code could change to:

nbNiveau = (yhi-ylo)*numElementsPerUnit + 1;
stepY = 1 / numElementsPerUnit;

That would avoid the issue entirely.

If stepY is not representable that way, and if yhi-ylo isn't too big, you
could just add 1.1 instead of 1 before truncating to an integer, but that's
not the prefered solution.

Victor's idea of "bumping up" the value might work for you, as well, if all
you care about is having "enough" elements in the array.

One thing to note: If you ever make calculations like (i-ylo)/stepY, or
simply i*stepY, then for large values of i the result will get further and
further from what you expect. But that's probably not be a problem for you,
since your values are small.

By the way, one thing I like to do when investigating problems involving
calculations like this is to store intermediate results to another variable,
like this:

double temp = (yhi-ylo)/stepY +1;
long nbNiveau = temp;

This lets you examine the values yourself when debugging, instead of trying
to guess what's going on inside the program.

Hope this helps...

-Howard


thank you for your help.
 

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,769
Messages
2,569,582
Members
45,057
Latest member
KetoBeezACVGummies

Latest Threads

Top