Board index » cppbuilder » Any help on why?

Any help on why?


2004-07-07 08:58:05 AM
cppbuilder32
The following example was from Sams Learning C in 24hrs.
-------------------------
#include <stdio>
#include <stdarg>
double AddDouble(int x, ...);
main()
{
double d1 = 1.5;
double d2 = 2.5;
double d3 = 3.5;
double d4 = 4.5;
printf("GIven an argument: %2.1f\n", d1);
printf("The result returned bu AddDouble() is: %2.1f\n\n", AddDouble(1,
d1));
printf("Given arguments: %2.1f and %2.1f\n", d1, d2);
printf("The result returned by AddDouble() is %2.1f\n\n", AddDouble(2,
d1, d2));
printf("Given arguments: %2.1f, %2.1f and %2.1f\n", d1, d2, d3);
printf("The result returned by AddDouble() is %2.1f\n\n", AddDouble(3,
d1, d2, d3));
printf("Given arguments: %2.1f, %2.1f, %2.1f and %2.1f\n", d1, d2, d3,
d4);
printf("The result returned by AddDouble() is %2.1f\n\n", AddDouble(4,
d1, d2, d3, d4));
return 0;
}
/* Definition of AddDouble() */
double AddDouble(int x, ...)
{
va_list arglist;
int i;
double xresult;
double result = 0.0;
printf("The number of arguments is : %d\n", x);
va_start(arglist, x);
for (i=0; i<x; i++){
xresult = double va_arg(arglist, double);
result += xresult;
printf("%d %X, %X\n", i, xresult, result);
}
va_end(arglist);
return result;
}
-------------------------------------------------
I was having problems getting the results. However, I found the mistake and
it now works.
BUT... In the process, I found by putting in some printf statements to aid
in debug, That prints the
variable "xresult" resulted in printing 0x0000. However the variable
"result" printed ok. Any ideas why the compiler forgets xresult?
Thanks
Stan DeGroff
 
 

Re:Any help on why?

Quote
>... by putting in some printf statements to aid in debug, That prints the
>variable "xresult" resulted in printing 0x0000. However the variable
>"result" printed ok.

Wrong type specifier in the printf().
>printf("%d %X, %X\n", i, xresult, result);

%X is used with integers. Use %f with doubles.
Wayne,
I wanted to look at the data as a Hexadecimal floating pt. number. It
didn't effect it when I tried %f.
"result" worked ok with %X. "xresult" returned 0 in either format. No
particular reason.
Quote

Did you type this in or copy & paste? This line looks odd:
>xresult = double va_arg(arglist, double);
It should be a typecast:
xresult = (double) va_arg(arglist, double);

The original text for the function was :
-----------
double AddDouble(int x, ...)
{
va_list arglist;
int i;
double result = 0.0;
printf("The number of arguments is : %d\n", x);
va_start(arglist, x);
for (i=0; i<x; i++)
result += va_arg(arglist, double);
va_end(arglist);
return result;
-----------------------
I didn't get the format right for type cast. Still not sure what, when or
how with type cast.
I was trying anything to find out what works. Trying to type it as a double
was one of my experiments.
Is that what I need to do to get xresult to print?
Here's what the output was (type cast or not, same output):
------------
GIven an argument: 1.5
The number of arguments is : 1
0 0, 3FF80000
The result returned bu AddDouble() is: 1.5
Given arguments: 1.5 and 2.5
The number of arguments is : 2
0 0, 3FF80000
1 0, 40040000
The result returned by AddDouble() is 4.0
Given arguments: 1.5, 2.5 and 3.5
The number of arguments is : 3
0 0, 3FF80000
1 0, 40040000
2 0, 400C0000
The result returned by AddDouble() is 7.5
Given arguments: 1.5, 2.5, 3.5 and 4.5
The number of arguments is : 4
0 0, 3FF80000
1 0, 40040000
2 0, 400C0000
3 0, 40120000
The result returned by AddDouble() is 12.0
--------------------
I think when I figure out why xresult doesn't print, I will have hit another
milestone in my understanding of how C works.
Quote

--
Wayne A. King
( XXXX@XXXXX.COM , XXXX@XXXXX.COM )
 

Re:Any help on why?

Stan DeGroff wrote:
Quote
for (i=0; i<x; i++){
xresult = double va_arg(arglist, double);
result += xresult;
printf("%d %X, %X\n", i, xresult, result);
}
That prints the
variable "xresult" resulted in printing 0x0000. However the variable
"result" printed ok. Any ideas why the compiler forgets xresult?
I know this sounds weird, but try this.
for (i=0; i<x; i++){
xresult = double va_arg(arglist, double);
printf("%d %X, %X\n", i, xresult, result);
result += xresult;
}
I think that because xresult isn't needed later, it is optimised away.
If xresult were global, or used later, it would be made "real".
(Apparantly, being inside a printf is being invisible.)
There's a bug in the optimizer.
BTW, which compiler are you using?
 

{smallsort}

Re:Any help on why?

"Stan DeGroff" < XXXX@XXXXX.COM >writes:
Quote
I wanted to look at the data as a Hexadecimal floating pt. number.
What does "Hexadecimal floating pt. number" mean?
 

Re:Any help on why?

Wayne A. King wrote:
Quote
On Wed, 7 Jul 2004 02:53:38 -0400, "Stan DeGroff" < XXXX@XXXXX.COM >wrote:

>I wanted to look at the data as a Hexadecimal floating pt. number.

As I said: %X is for use with *integer* arguments, not with floats/doubles.
What if you want to see how a float works?
Hex output is quite reasonable for such.
%X takes BYTES off the stack and displays them. It doesn't care what
type they were before they got put on the stack.
And, there is no difference on the stack between an int and a float
(other than perhaps the number of bytes, a size issue).
Poster could have used %lX for float or double as %X is int, whatever
size that is (target dependant)..
 

Re:Any help on why?

Thomas Maeder [TeamB] wrote:
Quote
"Stan DeGroff" < XXXX@XXXXX.COM >writes:

>I wanted to look at the data as a Hexadecimal floating pt. number.

What does "Hexadecimal floating pt. number" mean?
The Hex representation of a floating point number?
 

Re:Any help on why?

Bob Gonder < XXXX@XXXXX.COM >writes:
Quote
Thomas Maeder [TeamB] wrote:

>"Stan DeGroff" < XXXX@XXXXX.COM >writes:
>
>>I wanted to look at the data as a Hexadecimal floating pt. number.
>
>What does "Hexadecimal floating pt. number" mean?

The Hex representation of a floating point number?
[I know I am being a nuisance, but]
What does "The Hex representation of a floating point number" mean?
What is result of applying that representation to 3.1415?
 

Re:Any help on why?

Bob Gonder < XXXX@XXXXX.COM >writes:
Quote
Poster could have used %lX for float or double as %X is int, whatever
size that is (target dependant)..
Certainly not.
 

Re:Any help on why?

Thomas Maeder [TeamB] wrote:
Quote
What does "The Hex representation of a floating point number" mean?
What is result of applying that representation to 3.1415?
Dunno as I dislike the inaccuracy of floats and doubles, and I've
never had enough desire to learn *exactly* how the mantisa/etc are
encoded. However, the Hex of it shows the full implementation. Now
I've forgotten what the value portion is.... I remember the mantisa
scales the result so there are no leading zeros, but I forget what the
"number" portion is called......
OP showed output that looks a lot like the interal of a float to me:
Quote
Given arguments: 1.5, 2.5, 3.5 and 4.5
The number of arguments is : 4
0 0, 3FF80000
1 0, 40040000
2 0, 400C0000
3 0, 40120000
Ok, I'll write a proggie.
BCB5.
pi pushes 8 bytes
{char pie[40];
float pi = 3.1415;
int i;
for( i=0;i<10;i++)
{ sprintf(pie,"pi=%f %LX",pi,pi);
cputs( pie);
cputs("\n\r");//works better on my console than \r\n
pi+=pi;
}
pi=3.141500 400921CAC0000000
pi=6.283000 401921CAC0000000
pi=12.566000 402921CAC0000000
pi=25.132000 403921CAC0000000
pi=50.264000 404921CAC0000000
pi=100.528000 405921CAC0000000
pi=201.056000 406921CAC0000000
pi=402.112000 407921CAC0000000
pi=804.223999 408921CAC0000000
pi=1608.447998 409921CAC0000000
Looks like 400 is the mantisa and 31415 == 921cac
 

Re:Any help on why?

Thomas Maeder [TeamB] wrote:
Quote
Bob Gonder writes:

>Poster could have used %lX for float or double as %X is int, whatever
>size that is (target dependant)..

Certainly not.
Certainly not what? dependant? Ok, but I thought in the olden days
floats were 4 bytes, doubles, double that (hence the distinction).
In BCB (just tested it) floats are pushed as 8. so %LX works for them.
And, since we are in the BC group, not BCB, the following from BC++3.1
help on float:
float, double and long double (keywords)
ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
Real number data types
Type ?Length ?Range
---------------+---------+---------------------------------------
float ?32 bits ? 3.4 * (10**-38) to 3.4 * (10**+38)
double ?64 bits ? 1.7 * (10**-308) to 1.7 * (10**+308)
long double ?80 bits ?3.4 * (10**-4932) to 1.1 * (10**+4932)
 

Re:Any help on why?

Bob Gonder < XXXX@XXXXX.COM >writes:
Quote
Thomas Maeder [TeamB] wrote:

>Bob Gonder writes:
>
>>Poster could have used %lX for float or double as %X is int, whatever
>>size that is (target dependant)..
>
>Certainly not.

Certainly not what? dependant? Ok, but I thought in the olden days
floats were 4 bytes, doubles, double that (hence the distinction).
X and lX are for integral values. Using them for something else is an even
uglier hack than using the *printf() machinery at all.
To peek at the internals of, say, a double, the portable way is to
treat it as an array of unsigned char, as in
double d(3.11415);
unsigned char const *const begin(reinterpret_cast<unsigned char *>(&d));
unsigned char const *const end(begin + sizeof d);
for (unsigned char const *c = begin; c!=end; ++c)
printf("%u ",static_cast<unsigned int>(*c));
The result of this snippet is not portable, but the approach looks very
portable to me.
 

Re:Any help on why?

Thomas Maeder [TeamB] wrote:
Quote
X and lX are for integral values. Using them for something else is an even
uglier hack than using the *printf() machinery at all.
And you call the below code *Not* ugly?
Quote
To peek at the internals of, say, a double, the portable way is to
treat it as an array of unsigned char, as in

double d(3.11415);
unsigned char const *const begin(reinterpret_cast<unsigned char *>(&d));
unsigned char const *const end(begin + sizeof d);
for (unsigned char const *c = begin; c!=end; ++c)
printf("%u ",static_cast<unsigned int>(*c));
Yeah, but you want to use hex. You can't see the bits in 123.
My BC++ doesn't support 'reinterpret_cast' That's some new-age mumbo
jumbo designed to slow down programmers. I suppose it's so hard to
type that it encourages programmers to do *anything* (even use the
correct types!) to avoid it.
Not to mention, the OP's code was C not C++ to begin with.
 

Re:Any help on why?

I just wanted to see the bit layout.
"Thomas Maeder [TeamB]" < XXXX@XXXXX.COM >wrote in message
Quote
"Stan DeGroff" < XXXX@XXXXX.COM >writes:

>I wanted to look at the data as a Hexadecimal floating pt. number.

What does "Hexadecimal floating pt. number" mean?
 

Re:Any help on why?

BC++ V5.02 Copyright 1997
You've come up with exactly what I think was going on. I've seen other
cases do the same.
printf doesn't seem to invoke code that produces values that stick around
beyond their non-printf use.
When I look at the CPU screen I see that code is optimized. (Even though I
have "no optimization" checked in the project->options screen. Some
statements can't be used as break points as they have been optimized away as
well.)
Is there a way to insure optimization is not invoked?
"Bob Gonder" < XXXX@XXXXX.COM >wrote in message
Quote
Stan DeGroff wrote:

>for (i=0; i<x; i++){
>xresult = double va_arg(arglist, double);
>result += xresult;
>printf("%d %X, %X\n", i, xresult, result);
>}
>That prints the
>variable "xresult" resulted in printing 0x0000. However the variable
>"result" printed ok. Any ideas why the compiler forgets xresult?

I know this sounds weird, but try this.

for (i=0; i<x; i++){
xresult = double va_arg(arglist, double);
printf("%d %X, %X\n", i, xresult, result);
result += xresult;
}

I think that because xresult isn't needed later, it is optimised away.
If xresult were global, or used later, it would be made "real".
(Apparantly, being inside a printf is being invisible.)
There's a bug in the optimizer.

BTW, which compiler are you using?


 

Re:Any help on why?

Quote
My BC++ doesn't support 'reinterpret_cast' That's some new-age
mumbo
jumbo designed to slow down programmers. I suppose it's so hard to
type that it encourages programmers to do *anything* (even use the
correct types!) to avoid it.
LOL!