Page 4 of 5

Re:a c question

Posted: Thu Mar 25, 2004 2:51 pm
by Tim
First of all: stdarg's implementation is opaque as far as applications are concerned. In other words, all applications care about is that stdarg works as documented.
Neo wrote: 1) do we declare va_list as a char* or void* ? void* seems more generic but i think char* would permit pointer arithmetic without warnings.
Whichever is most convenient. va_list is implementation-defined, i.e. opaque; it can be whatever type you want.
2) what exactly does va_end() do? I could find no info other than the explantion that "it must be called once after processing" and that "it does cleanup"
Whatever it needs to. If your va_start needs to allocate some memory, va_end should free it. va_end can do nothing if you want.
3) i also saw that the linux src uses "rounded off" sizes for all datatypes. does this have to be done or can we just add

Code: Select all

sizeof([i]datatype[/i])
to the arg pointer?
This is because of the way the stack works on the x86. Each item on a 32-bit stack is a multiple of 32 bits in size.

Re:a c question

Posted: Thu Mar 25, 2004 2:57 pm
by Neo
Tim Robinson wrote:
3) i also saw that the linux src uses "rounded off" sizes for all datatypes. does this have to be done or can we just add

Code: Select all

sizeof(datatype)
to the arg pointer?
This is because of the way the stack works on the x86. Each item on a 32-bit stack is a multiple of 32 bits in size.
Oh! the stack. I was thinking about varible sized structures in general without thinkin of the stack. Now the thing is clearer. Thanks Tim

Re:a c question

Posted: Fri Mar 26, 2004 11:37 am
by Neo
does this allocate space for the entire string or only a pointer. if it allocates only for a pointer is this way of declaring strings wrong? and where does the memory for the string come from? the stack or data section??

Code: Select all

char *a="hello world";

Re:a c question

Posted: Fri Mar 26, 2004 1:03 pm
by Tim
Both. It allocates memory for "char *a" in the normal way (i.e. the same as if you had written "int a"), and puts the memory for "hello world" somewhere in the executable. This is commonly in the .text or .rodata sections.

Re:a c question

Posted: Tue Apr 13, 2004 3:38 pm
by Neo
do the C/C++ operators work only on integers. The reason i'm asking this is

Code: Select all

#include<stdio.h>
main()
{
  float a=7.07;
  if(a==7.07)
   printf("Less");
  else
   printf("More");
}
only on explicitly casting it do i get the correct answer. Why?

Re:a c question

Posted: Tue Apr 13, 2004 4:39 pm
by Schol-R-LEA
I could be mistaken, but I suspect it's because the floating point representation of 7.07 isn't quite exact. If you try different constants (1.0, 1.1, 2.0, 2.1) you'll get varying degrees of accuracy. Also, in gcc at least, it works differently when comparing two variables rather than a variable and a literal; this can be demostrated with the following program:

Code: Select all

#include <stdio.h>

void compare (float x, float y);

main()
{
  float a[8] = {0.09, 0.9, 1.0, 2.0, 2.1, 2.1478, 3.0, 4.0};
  
  compare (a[0], 0.09);
  if(a[0] == 0.09)
   printf("%f == %f\n", a[0], 0.09);
  else if(a[0] < 0.09)
   printf("%f < %f\n", a[0], 0.09);
  else
   printf("%f > %f\n", a[0], 0.09);
  printf("\n");
  
  compare (a[1], 0.9);
  if(a[1] == 0.9)
   printf("%f == %f\n", a[1], 0.9);
  else if(a[0] < 0.9)
   printf("%f < %f\n", a[1], 0.9);
  else
   printf("%f > %f\n", a[1], 0.9);  
  printf("\n");
  
  compare (a[2], 1.0);
  if(a[2] == 1.0)
   printf("%f == %f\n", a[2], 1.0);
  else if(a[2] < 1.0)
   printf("%f < %f\n", a[2], 1.0);
  else
   printf("%f > %f\n", a[2], 1.0);  
  printf("\n"); 
  
  compare (a[3], 2.0);
  if(a[3] == 2.0)
   printf("%f == %f\n", a[3], 2.0);
  else if(a[3] < 2.0)
   printf("%f < %f\n", a[3], 2.0);
  else
   printf("%f > %f\n", a[3], 2.0);  
  printf("\n");   
  
  compare (a[4], 2.1);
  if(a[4] == 2.1)
   printf("%f == %f\n", a[4], 2.1);
  else if(a[4] < 2.1)
   printf("%f < %f\n", a[4], 2.1);
  else
   printf("%f > %f\n", a[4], 2.1);  
  printf("\n");   
  
  compare (a[5], 2.1478);
  if(a[5] == 2.1478)
   printf("%f == %f\n", a[5], 2.1478);
  else if(a[5] < 2.1478)
   printf("%f < %f\n", a[5], 2.1478);
  else
   printf("%f > %f\n", a[5], 2.1478);  
  printf("\n");  
  
  compare (a[6], 3.0);
  if(a[6] == 3.0)
   printf("%f == %f\n", a[6], 3.0);
  else if(a[6] < 3.0)
   printf("%f < %f\n", a[6], 3.0);
  else
   printf("%f > %f\n", a[6], 3.0);  
  printf("\n"); 

  compare (a[7], 4.0);
  if(a[7] == 4.0)
   printf("%f == %f\n", a[7], 4.0);
  else if(a[7] < 4.0)
   printf("%f < %f\n", a[7], 4.0);
  else
   printf("%f > %f\n", a[7], 4.0);  
  printf("\n");   
    
  getchar();
}  
  
void compare (float x, float y) 
{ 
  if( x == y)
   printf("%f == %f\n", x, y);
  else if(x < y)
   printf("%f < %f\n", x, y);
  else
   printf("%f > %f\n", x, y);
}
The same comparisons are done each time, but whereas the variable to variable comparisons always come out equal, the variable to literal ones are only equal if the literal have an exact representation in binary floating point.

At least, that's my thoughts on it. C&CW.

Re:a c question

Posted: Wed Apr 14, 2004 10:21 am
by anubis
Hi,
Schol-R-Lea might indeed be right. I learned the same things in college when i studied Computer Organization from a book.
It mentioned that though 7.07 was always printed as 7.07 it might is represented in hardware as 7.069999999999999999999999... So comparison might not work.
Hope that helps.

_anubis.

Re:a c question

Posted: Wed Apr 14, 2004 12:39 pm
by Neo
then how does it work when type-casted????

Re:a c question

Posted: Wed Apr 14, 2004 2:37 pm
by Schol-R-LEA
Well, if you're typecasting to int, then it simply that the values are all stripped down to the nearest integer value. If you are casting to float, then presumably the literal is stored as a temporary variable, which would be in the same representation as the variable it's being compared to.

I've modified my test script to demostrate this. A copy of it is attached.

[attachment deleted by admin]

Re:a c question

Posted: Wed Apr 14, 2004 4:59 pm
by anubis
Hi,
Ummm.... seems that the floating point representation is pretty scrwed in PC's making (A+B)+C != A+(B+C)....
My question is if a Number say 7.07 is internally represented as something else... say for example 7.069999999999999... what will 7.06999999999999... be internally represented as? To rephrase it if a number is represented temporarily as something else, can two different floats (7.07 & 7.069999 as example) have the same internal representation??? Hmmm...

Re:a c question

Posted: Wed Apr 14, 2004 5:06 pm
by Tim
Yes.

Every base has numbers which cannot be represented accurately. For example, in decimal, you cannot accurately represent 1/3 or pi. In base 3, you can represent 1/3 accurately, but you can't represent 1/10 accurately. Binary (i.e. the base used by computers) is just the same.

You can make it more accurate by adding more digits after the decimal (binary) point: 0.333333333 is closer to 1/3 than 0.333333, and [tt](double) 7.07[/tt] is closer to 7.07 than [tt](float) 7.07[/tt]. Neither, though, is exact.

Re:a c question

Posted: Sun Apr 18, 2004 7:51 am
by Perica
..

Re:a c question

Posted: Sun Apr 18, 2004 7:58 am
by Candy
Perica wrote:
Tim Robinson wrote:For example, in decimal, you cannot accurately represent 1/3 or pi.
I don't understand. As far as I know you can't represent pi accurately in any base as it has infinite digits after it's decimal point. Was that a typo or is there something I don't know...? ???
That's not a typo, and not something you don't know, but something you don't interpret.

He never implied that you could represent it in any base (even though in base pi you can represent pi accurately :P), but you cannot do that in base 10.

Re:a c question

Posted: Sun Apr 18, 2004 8:09 am
by Perica
..

Re:a c question

Posted: Sun Apr 18, 2004 8:26 am
by Tim
Sure, you can use any number as a base.

1 in base pi equals pi in base 10.
10 in base pi equals pi[sup]2[/sup] in base 10.
1234 in base pi equals 1*pi[sup]4[/sup] + 2*pi[sup]3[/sup] + 3*pi[sup]2[/sup] + 4*pi in base 10.

Using a complex number as a base is fun...

PS: Those numbers, in decimal, are:
1[sub]pi[/sub] = 3.1415927[sub]10[/sub]
10[sub]pi[/sub] = 9.8696044[sub]10[/sub]
1234[sub]pi[/sub] = 201.5968282[sub]10[/sub]