a c question

Programming, for all ages and all languages.
Tim

Re:a c question

Post 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.
User avatar
Neo
Member
Member
Posts: 842
Joined: Wed Oct 18, 2006 9:01 am

Re:a c question

Post 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
Only Human
User avatar
Neo
Member
Member
Posts: 842
Joined: Wed Oct 18, 2006 9:01 am

Re:a c question

Post 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";
Only Human
Tim

Re:a c question

Post 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.
User avatar
Neo
Member
Member
Posts: 842
Joined: Wed Oct 18, 2006 9:01 am

Re:a c question

Post 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?
Only Human
Schol-R-LEA

Re:a c question

Post 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.
anubis

Re:a c question

Post 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.
User avatar
Neo
Member
Member
Posts: 842
Joined: Wed Oct 18, 2006 9:01 am

Re:a c question

Post by Neo »

then how does it work when type-casted????
Only Human
Schol-R-LEA

Re:a c question

Post 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]
anubis

Re:a c question

Post 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...
Tim

Re:a c question

Post 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.
Perica
Member
Member
Posts: 454
Joined: Sat Nov 25, 2006 12:50 am

Re:a c question

Post by Perica »

..
Last edited by Perica on Tue Dec 05, 2006 9:28 pm, edited 1 time in total.
User avatar
Candy
Member
Member
Posts: 3882
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven

Re:a c question

Post 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.
Perica
Member
Member
Posts: 454
Joined: Sat Nov 25, 2006 12:50 am

Re:a c question

Post by Perica »

..
Last edited by Perica on Tue Dec 05, 2006 9:28 pm, edited 1 time in total.
Tim

Re:a c question

Post 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]
Post Reply