P: n/a

I have create these 2 files. Called main.c and atr.c. They seem to work
pretty well. I just wanted to submit them to see what if any errors others
that know more might find. Thanks.
atr.c
#include <stdio.h>
double
atr (double th, double tl, double wc)
{
if (th  tl th  wc && tl  wc < th  tl)
{
return th  tl;
}
if (th  wc th  tl && tl  wc < th  wc)
{
return th  wc;
}
if (tl  wc th  wc && th  tl < tl  wc)
{
return tl  wc;
}
}
main.c
#include <stdio.h>
#include <stdlib.h>
extern double atr ( double th, double tl, double wc );
int
main (int argc, char *argv[])
{
if (argc != 4)
{
fprintf (stderr, "usage error th, tl, wc\n");
exit (EXIT_FAILURE);
}
double th, tl, wc;
th = strtod (argv[1], NULL);
tl = strtod (argv[2], NULL);
wc = strtod (argv[3], NULL);
printf("%.2f\n", atr(th, tl, wc));
}
Bill  
Share this Question
P: n/a

Oh yes and tl means today's low. Th means today's high and wc means week's
close.
Bill  
P: n/a

On Jun 11, 11:11*am, "Bill Cunningham" <nos...@nspam.comwrote:
* * I have create these 2 files. Called main.c and atr.c. They seem towork
pretty well. I just wanted to submit them to see what if any errors others
that know more might find. Thanks.
atr.c
#include <stdio.h>
double
atr (double th, double tl, double wc)
{
* if (th  tl th  wc && tl  wc < th  tl)
* * {
* * * return th  tl;
* * }
* if (th  wc th  tl && tl  wc < th  wc)
* * {
* * * return th  wc;
* * }
* if (tl  wc th  wc && th  tl < tl  wc)
* * {
* * * return tl  wc;
* * }
}
main.c
#include <stdio.h>
#include <stdlib.h>
extern double atr ( double th, double tl, double wc );
int
main (int argc, char *argv[])
{
* if (argc != 4)
* * {
* * * fprintf (stderr, "usage error th, tl, wc\n");
* * * exit (EXIT_FAILURE);
* * }
* double th, tl, wc;
* th = strtod (argv[1], NULL);
* tl = strtod (argv[2], NULL);
* wc = strtod (argv[3], NULL);
* printf("%.2f\n", atr(th, tl, wc));
}
You haven't said what the intent of the atr function is, so how are
we to know whether it is getting the right answer?
Just a bit of math shows that there are cleaner comparisons.
For example,
if ( th  tl th  wc )
is the same as
if ( wc tl )

Fred Kleinschmidt  
P: n/a

On Jun 11, 11:11*am, "Bill Cunningham" <nos...@nspam.comwrote:
* * I have create these 2 files. Called main.c and atr.c. They seem towork
pretty well. I just wanted to submit them to see what if any errors others
that know more might find. Thanks.
atr.c
#include <stdio.h>
double
atr (double th, double tl, double wc)
{
* if (th  tl th  wc && tl  wc < th  tl)
* * {
* * * return th  tl;
* * }
* if (th  wc th  tl && tl  wc < th  wc)
* * {
* * * return th  wc;
* * }
* if (tl  wc th  wc && th  tl < tl  wc)
* * {
* * * return tl  wc;
* * }
}
main.c
#include <stdio.h>
#include <stdlib.h>
extern double atr ( double th, double tl, double wc );
int
main (int argc, char *argv[])
{
* if (argc != 4)
* * {
* * * fprintf (stderr, "usage error th, tl, wc\n");
* * * exit (EXIT_FAILURE);
* * }
* double th, tl, wc;
* th = strtod (argv[1], NULL);
* tl = strtod (argv[2], NULL);
* wc = strtod (argv[3], NULL);
* printf("%.2f\n", atr(th, tl, wc));
}
Having fixed some of the more obvious errors, I would try this one:
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
static double atr(double th, double tl, double wc)
{
if (th  tl th  wc && tl  wc < th  tl) {
return th  tl;
}
if (th  wc th  tl && tl  wc < th  wc) {
return th  wc;
}
if (tl  wc th  wc && th  tl < tl  wc) {
return tl  wc;
}
assert(0);
return sqrt(1.);
}
int main(int argc, char *argv[])
{
double th,
tl,
wc;
if (argc != 4) {
fprintf(stderr, "usage error th, tl, wc\n");
exit(EXIT_FAILURE);
}
th = strtod(argv[1], NULL);
tl = strtod(argv[2], NULL);
wc = strtod(argv[3], NULL);
printf("%.2f\n", atr(th, tl, wc));
return 0;
}
But then give it inputs of 20 20 20 and see what happens.  
P: n/a

In article <75**********************************@x1g2000prh.g ooglegroups.com>,
Fred <fr*****************@boeing.comwrote:
>Just a bit of math shows that there are cleaner comparisons. For example,
if ( th  tl th  wc ) is the same as
if ( wc tl )
Alegebraically the same, but not the same in the domain of
binary floating point numbers... especially if th is a NaN.

"To the modern spirt nothing is, or can be rightly known,
except relatively and under conditions."  Walter Pater  
P: n/a

"user923005" <dc*****@connx.comwrote in message
news:7e**********************************@2g2000hs n.googlegroups.com...
Having fixed some of the more obvious errors, I would try this one:
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
static double atr(double th, double tl, double wc)
{
if (th  tl th  wc && tl  wc < th  tl) {
return th  tl;
}
if (th  wc th  tl && tl  wc < th  wc) {
return th  wc;
}
if (tl  wc th  wc && th  tl < tl  wc) {
return tl  wc;
}
assert(0);
return sqrt(1.);
}
Assert. Hum never used it. I'll check it out.
Bill  
P: n/a

"Fred" <fr*****************@boeing.comwrote in message
news:759c09a0b2fe4ed38073
You haven't said what the intent of the atr functio
n is, so how are
we to know whether it is getting the right answer?
Ceck my second post. Any answer that is a postive number might be right.
Just a bit of math shows that there are cleaner comparisons.
For example,
if ( th  tl th  wc )
is the same as
if ( wc tl )

Fred Kleinschmidt  
P: n/a

"user923005" <dc*****@connx.comwrote in message
news:7ee08bd4890e434f8bdd
[snip]
assert(0);
return sqrt(1.);
}
What's the sqrt function called for ? And the 0 passed to assert?
Bill  
P: n/a

"Fred" <fr*****************@boeing.comwrote in message
news:759c09a0b2fe4ed38073
You haven't said what the intent of the atr function is, so how are
we to know whether it is getting the right answer?
Just a bit of math shows that there are cleaner comparisons.
For example,
if ( th  tl th  wc )
is the same as
if ( wc tl ) http://www.metaformula.com/averagetruerange.html  
P: n/a

"Bill Cunningham" <no****@nspam.comwrites:
"user923005" <dc*****@connx.comwrote in message
news:7e**********************************@2g2000hs n.googlegroups.com...
Having fixed some of the more obvious errors, I would try this one:
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
static double atr(double th, double tl, double wc)
{
if (th  tl th  wc && tl  wc < th  tl) {
return th  tl;
}
if (th  wc th  tl && tl  wc < th  wc) {
return th  wc;
}
if (tl  wc th  wc && th  tl < tl  wc) {
return tl  wc;
}
assert(0);
return sqrt(1.);
}
Assert. Hum never used it. I'll check it out.
Bill
In your last few messages, quoted text is not marked. In the above,
the text starting with "Having fixed some ..." plus the C code is
quoted from user923005's previous article; only the last line,
starting "Assert. Hum ..." is new.
Whatever you're doing differently when posting followups, please go
back to what you were doing before.

Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
 Antony Jay and Jonathan Lynn, "Yes Minister"  
P: n/a

"user923005" <dc*****@connx.comwrote in message
news:7e**********************************@2g2000hs n.googlegroups.com...
Having fixed some of the more obvious errors, I would try this one:
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
static double atr(double th, double tl, double wc)
{
if (th  tl th  wc && tl  wc < th  tl) {
return th  tl;
}
if (th  wc th  tl && tl  wc < th  wc) {
return th  wc;
}
if (tl  wc th  wc && th  tl < tl  wc) {
return tl  wc;
}
assert(0);
return sqrt(1.);
}
int main(int argc, char *argv[])
{
double th,
tl,
wc;
if (argc != 4) {
fprintf(stderr, "usage error th, tl, wc\n");
exit(EXIT_FAILURE);
}
th = strtod(argv[1], NULL);
tl = strtod(argv[2], NULL);
wc = strtod(argv[3], NULL);
printf("%.2f\n", atr(th, tl, wc));
return 0;
}
But then give it inputs of 20 20 20 and see what happens.
After running this program several times now I am discovering that I am
getting negative numbers. I should never get negative numbers here.
Bill  
P: n/a

"Bill Cunningham" <no****@nspam.comwrote in message
news:ZgW3k.25453$Xu2.7399@trnddc04...
After running this program several times now I am discovering that I am
getting negative numbers. I should never get negative numbers here.
Bill
Sorry not your program to clarify I mean mine. No misunderstanding.
Bill  
P: n/a

Keith Thompson wrote:
In your last few messages, quoted text is not marked. In the above,
the text starting with "Having fixed some ..." plus the C code is
quoted from user923005's previous article; only the last line,
starting "Assert. Hum ..." is new.
Whatever you're doing differently when posting followups, please go
back to what you were doing before.
Probably Bill is using Outlook Express (I have him killfiled, so I
can't check), and is running into the incompatibility with Google
Groups, which Mr. Corbit is using. If so, that can be fixed either by
switching newsreaders (recommended) or downloading and installing OE
Quotefix.
Brian  
P: n/a

"Bill Cunningham" <no****@nspam.comwrites:
"Fred" <fr*****************@boeing.comwrote in message
news:759c09a0b2fe4ed38073
You haven't said what the intent of the atr function is, so how are
we to know whether it is getting the right answer?
<snip>
http://www.metaformula.com/averagetruerange.html
According to that document, what you are trying to calculate with the
atr function is called the "true range". The average true range is
the (moving) average of this value. I think the function is
misnamed  you shoul call it 'tr' or, better, 'true_range'.
Let me recap your version:
double
atr (double th, double tl, double wc)
{
if (th  tl th  wc && tl  wc < th  tl)
{
return th  tl;
}
if (th  wc th  tl && tl  wc < th  wc)
{
return th  wc;
}
if (tl  wc th  wc && th  tl < tl  wc)
{
return tl  wc;
}
}
Part of the art of programming is to write programs that are clear
rather than just correct. I would write this:
double max_of_3(double a, double b, double c)
{
return fmax(fmax(a, b), c);
}
double true_range(double th, double tl, double wc)
{
return max_of_3(th  tl, th  wc, tl  wc);
}
This makes the intent much clearer. Yours is much less clear. In
fact it has a subtle problem that is not easy to reason about. As a
hint, are you sure that at least one of the three big conditions is
always true?

Ben.  
P: n/a

"Bill Cunningham" <no****@nspam.comwrites:
Oh yes and tl means today's low. Th means today's high and wc means week's
close.
If you feel the urge to write this, then it suggests that the
parameters should be called todays_low, todays_high and weeks_close.

Ben.  
P: n/a

On 11 Jun 2008 at 20:43, Default User wrote:
[snip crap]
Marvelous. Just when you thought it was safe, the Loser has crawled back
out from under his stone. I suppose that means we have to endure his
bitching about topposting, topicality and "trolls" again, as well as
the continual updates on the latest contents of his killfile (as if
anyone gives a damn).  
P: n/a

"Ben Bacarisse" <be********@bsb.me.ukwrote in message
news:87************@bsb.me.uk...
According to that document, what you are trying to calculate with the
atr function is called the "true range". The average true range is
the (moving) average of this value. I think the function
[snip]
Part of the art of programming is to write programs that are clear
rather than just correct. I would write this:
double max_of_3(double a, double b, double c)
{
return fmax(fmax(a, b), c);
}
I don't quite get the fmax(fmax(a,b),c);
I know it's algebraic.
double true_range(double th, double tl, double wc)
{
return max_of_3(th  tl, th  wc, tl  wc);
}
This makes the intent much clearer. Yours is much less clear. In
fact it has a subtle problem that is not easy to reason about. As a
hint, are you sure that at least one of the three big conditions is
always true?

Ben.
 
P: n/a

On Jun 11, 3:57*pm, "Bill Cunningham" <nos...@nspam.comwrote:
"Ben Bacarisse" <ben.use...@bsb.me.ukwrote in message
news:87************@bsb.me.uk...
According to that document, what you are trying to calculate with the
atr function is called the "true range". *The average true range is
the (moving) average of this value. *I think the function
[snip]
Part of the art of programming is to write programs that are clear
rather than just correct. *I would write this:
double max_of_3(double a, double b, double c)
{
* * return fmax(fmax(a, b), c);
}
* * I don't quite get the fmax(fmax(a,b),c);
I know it's algebraic.
double true_range(double th, double tl, double wc)
{
* *return max_of_3(th  tl, th  wc, tl  wc);
}
This makes the intent much clearer. *Yours is much less clear. *In
fact it has a subtle problem that is not easy to reason about. *As a
hint, are you sure that at least one of the three big conditions is
always true?
/*
The true range is the greatest of the following:
1) The difference between the current high and the current low
2) The difference between the current high and the previous close
3) The difference between the current low and the previous close
*/
#include <math.h>
double true_range(double current_high, double current_low,
double previous_close)
{
double d1 = fabs(current_high  current_low);
double d2 = fabs(current_high  previous_close);
double d3 = fabs(current_low  previous_close);
double dmax = d1 d2 ? d1 : d2;
dmax = dmax d3 ? dmax : d3;
return dmax;
}
#ifdef UNIT_TEST
#include <stdio.h>
int main(void)
{
double current_high = 0;
double current_low = 0;
double previous_close = 0;
char string[256] = {0};
int converted;
oops0:
puts("Enter current high value:");
fflush(stdout);
if (fgets(string, sizeof string, stdin)) {
converted = sscanf(string, "%lf", ¤t_high);
if (converted != 1)
goto oops0;
oops1:
puts("Enter current low value:");
fflush(stdout);
if (fgets(string, sizeof string, stdin)) {
converted = sscanf(string, "%lf", ¤t_low);
if (converted != 1)
goto oops1;
oops2:
puts("Enter previous close value:");
fflush(stdout);
if (fgets(string, sizeof string, stdin)) {
converted = sscanf(string, "%lf", &previous_close);
if (converted != 1)
goto oops2;
printf("true range of (%f, %f, %f) is %f\n",
current_high,
current_low,
previous_close,
true_range(current_high, current_low,
previous_close)
);
} else {
goto oops2;
}
} else {
goto oops1;
}
} else {
goto oops0;
}
return 0;
}
/* E.g.:
Enter current high value:
111
Enter current low value:
123
Enter previous close value:
125
true range of (111.000000, 123.000000, 125.000000) is 14.000000
*/
#endif  
P: n/a

On 11 Jun, 19:11, "Bill Cunningham" <nos...@nspam.comwrote:
* * I have create these 2 files. Called main.c and atr.c. They seem towork
pretty well. I just wanted to submit them to see what if any errors others
that know more might find. Thanks.
atr.c
#include <stdio.h>
not needed
>
double
atr (double th, double tl, double wc)
a comment would be nice. I've no idea if this is correct
because I don't know what it's supposed to do.
If Average True Range is a well known calculation
you could make a reference to a stats book or whatever.
{
* if (th  tl th  wc && tl  wc < th  tl)
* * {
* * * return th  tl;
* * }
* if (th  wc th  tl && tl  wc < th  wc)
* * {
* * * return th  wc;
* * }
* if (tl  wc th  wc && th  tl < tl  wc)
* * {
* * * return tl  wc;
* * }
}
ah! sane layout. Good.
main.c
#include <stdio.h>
#include <stdlib.h>
extern double atr ( double th, double tl, double wc );
I must admit I'd put this in a header file.
It makes no odds with a single function but as you get
more and more c files and more and more functions it is easier
to manage header files.
int
main (int argc, char *argv[])
{
* if (argc != 4)
* * {
* * * fprintf (stderr, "usage error th, tl, wc\n");
* * * exit (EXIT_FAILURE);
* * }
* double th, tl, wc;
this is invalid in C89
* th = strtod (argv[1], NULL);
no error checking on strtod()
* tl = strtod (argv[2], NULL);
* wc = strtod (argv[3], NULL);
* printf("%.2f\n", atr(th, tl, wc));
main() should return a value (eg. EXIT_SUCCESS)
}

Nick Keighley
"Objectoriented programming is an exceptionally bad idea
that could only have originated in California."
Dijkstra  
P: n/a

On Jun 11, 5:17*pm, user923005 <dcor...@connx.comwrote:
On Jun 11, 3:57*pm, "Bill Cunningham" <nos...@nspam.comwrote:
"Ben Bacarisse" <ben.use...@bsb.me.ukwrote in message
news:87************@bsb.me.uk...
According to that document, what you are trying to calculate with the
atr function is called the "true range". *The average true range is
the (moving) average of this value. *I think the function
[snip]
Part of the art of programming is to write programs that are clear
rather than just correct. *I would write this:
double max_of_3(double a, double b, double c)
{
* * return fmax(fmax(a, b), c);
}
* * I don't quite get the fmax(fmax(a,b),c);
I know it's algebraic.
double true_range(double th, double tl, double wc)
{
* *return max_of_3(th  tl, th  wc, tl  wc);
}
This makes the intent much clearer. *Yours is much less clear. *In
fact it has a subtle problem that is not easy to reason about. *As a
hint, are you sure that at least one of the three big conditions is
always true?
/*
The true range is the greatest of the following:
*1) The difference between the current high and the current low
*2) The difference between the current high and the previous close
*3) The difference between the current low and the previous close
*/
#include <math.h>
double * * * * *true_range(double current_high, double current_low,
double previous_close)
{
* * double * * * * *d1 = fabs(current_high  current_low);
* * double * * * * *d2 = fabs(current_high  previous_close);
* * double * * * * *d3 = fabs(current_low  previous_close);
* * double * * * * *dmax = d1 d2 ? d1 : d2;
* * dmax = dmax d3 ? dmax : d3;
* * return dmax;
}
#ifdef UNIT_TEST
#include <stdio.h>
int * * * * * * main(void)
{
* * double * * * * *current_high = 0;
* * double * * * * *current_low = 0;
* * double * * * * *previous_close = 0;
* * char * * * * * *string[256] = {0};
* * int * * * * * * converted;
oops0:
* * puts("Enter current high value:");
* * fflush(stdout);
* * if (fgets(string, sizeof string, stdin)) {
* * * * converted = sscanf(string, "%lf", ¤t_high);
* * * * if (converted != 1)
* * * * * * goto oops0;
oops1:
* * * * puts("Enter current low value:");
* * * * fflush(stdout);
* * * * if (fgets(string, sizeof string, stdin)) {
* * * * * * converted = sscanf(string, "%lf", ¤t_low);
* * * * * * if (converted != 1)
* * * * * * * * goto oops1;
* * oops2:
* * * * * * puts("Enter previous close value:");
* * * * * * fflush(stdout);
* * * * * * if (fgets(string, sizeof string, stdin)) {
* * * * * * * * converted = sscanf(string, "%lf", &previous_close);
* * * * * * * * if (converted != 1)
* * * * * * * * * * goto oops2;
* * * * * * * * printf("true range of (%f, %f, %f) is %f\n",
* * * * * * * * * * * *current_high,
* * * * * * * * * * * *current_low,
* * * * * * * * * * * *previous_close,
* * * * * * * * * * * *true_range(current_high, current_low,
previous_close)
* * * * * * * * * * );
* * * * * * } else {
* * * * * * * * goto oops2;
* * * * * * }
* * * * } else {
* * * * * * goto oops1;
* * * * }
* * } else {
* * * * goto oops0;
* * }
* * return 0;}
/* E.g.:
Enter current high value:
111
Enter current low value:
123
Enter previous close value:
125
true range of (111.000000, 123.000000, 125.000000) is 14.000000
*/
#endif
Here is the other half of the problem:
#include <assert.h>
typedef struct accumulator {
double sum;
long prior;
long later;
} accumulator;
/*
This function takes a vector node v[k] and computes a sliding window
average for the point at v[k].
*/
double window(const double *const v, accumulator a)
{
long i;
a.sum = 0;
// Add in previous values
for (i = a.prior; i < 0; i++)
a.sum += v[i];
// Add in current value
a.sum += v[0];
// Add in subsequent values
for (i = 1; i <= a.later; i++)
a.sum += v[i];
return a.sum / (a.prior + a.later + 1);
}
/*
This is a sliding window moving average.
We can use historic data windows or future data windows or windows
that use both prior and later values.
double *vector : raw input vector consisting of vector_length
double values.
double *smoothed_vector : smoothed output vector consisting of
vector_length double values.
long period : number of items to combine as the average
(e.g. weekly = 7)
long vector_length : length of both the input and output vectors
*/
void moving_average(const double *const vector, double
*smoothed_vector, long prior, long later, const long vector_length)
{
accumulator a = {0};
long i;
assert(prior >= 0);
assert(later >= 0);
assert(vector_length >= 0);
assert(vector);
assert(smoothed_vector);
prior = prior < vector_length ? prior : vector_length;
later = later < vector_length ? later : vector_length;
for (i = 0; i < vector_length; i++) {
a.prior = prior i ? i : prior;
a.later = later vector_length  i ? vector_length  i :
later;
smoothed_vector[i] = window(&vector[i], a);
}
}
#ifdef UNIT_TEST
#include <stdio.h>
#include <stdlib.h>
#include <float.h>
#include <time.h>
double raw_vector[20];
double smoothed_vector[20];
void show_vector(double *v, size_t len)
{
size_t index;
for (index = 0; index < len; index++)
printf("%*.*g\n ", DBL_DIG + 3, DBL_DIG, v[index]);
}
int main(void)
{
double factor = 1.0 / RAND_MAX;
size_t rvlen = sizeof raw_vector / sizeof raw_vector[0];
size_t svlen = sizeof smoothed_vector / sizeof
smoothed_vector[0];
size_t i;
assert(rvlen == svlen);
srand(time(NULL));
raw_vector[0] = rand() * factor;
for (i = 1; i < rvlen; i++) {
raw_vector[i] = raw_vector[i  1] + (rand() * (rand() % 2 ?
factor : factor));
}
puts("Raw vector:");
show_vector(raw_vector, rvlen);
moving_average(raw_vector, smoothed_vector, 0, 7, rvlen);
puts("\nSmoothed vector [0,7]:");
show_vector(smoothed_vector, rvlen);
moving_average(raw_vector, smoothed_vector, 7, 0, rvlen);
puts("\nSmoothed vector [7,0]:");
show_vector(smoothed_vector, rvlen);
moving_average(raw_vector, smoothed_vector, 7, 7, rvlen);
puts("\nSmoothed vector [7,7]:");
show_vector(smoothed_vector, rvlen);
return 0;
}
#endif  
P: n/a

Bill Cunningham wrote:
"user923005" <dc*****@connx.comwrote in message
news:7ee08bd4890e434f8bdd
[snip]
assert(0);
return sqrt(1.);
}
What's the sqrt function called for ? And the 0 passed to assert?
The assert(0) will printa a diagnostic and in debug mode abort the program,
the sqrt(1.) will cause a domain error to happen (errno being set to EDOM)
in production mode (i.e. which NDEBUG being #defineed)
Bye, Jojo  
P: n/a

On Jun 13, 4:52*am, "Joachim Schmitz" <nospam.j...@schmitzdigital.de>
wrote:
Bill Cunningham wrote:
"user923005" <dcor...@connx.comwrote in message
news:7ee08bd4890e434f8bdd
[snip]
* *assert(0);
* *return sqrt(1.);
}
*What's the sqrt function called for ? And the 0 passed to assert?
The assert(0) will printa a diagnostic and in debug mode abort the program,
the sqrt(1.) will cause a domain error to happen (errno being set to EDOM)
in production mode (i.e. which NDEBUG being #defineed)
To the O.P.:
The purpose of those modifications was to demonstrate a bug in your
program when equal inputs were entered.
E.g., try your original code with 20,20,20 and it does not perform a
correct computation.   This discussion thread is closed Replies have been disabled for this discussion.   Question stats  viewed: 2220
 replies: 21
 date asked: Jun 27 '08
