Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Big integer newbie problem

Reply
Thread Tools

Big integer newbie problem

 
 
cjblaine@gmail.com
Guest
Posts: n/a
 
      09-01-2006
What am I doing wrong?

OUTPUT:
% ./sysconf.sun4x_59
Pages: 262144
Page size KB: 8192
Physical Memory: -1
%

CODE:
/* sysconf.c */
#include <unistd.h>
#include <stdio.h>

int main(void) {
unsigned long long int physmem;

printf("Pages: %d\n", sysconf(_SC_PHYS_PAGES));
printf("Page size KB: %d\n", sysconf(_SC_PAGESIZE));
physmem = sysconf(_SC_PHYS_PAGES) * sysconf(_SC_PAGESIZE) / 1000;
printf("Physical Memory: %d\n", physmem);
}

 
Reply With Quote
 
 
 
 
Spiros Bousbouras
Guest
Posts: n/a
 
      09-01-2006
wrote:

> What am I doing wrong?
>
> OUTPUT:
> % ./sysconf.sun4x_59
> Pages: 262144
> Page size KB: 8192
> Physical Memory: -1
> %
>
> CODE:
> /* sysconf.c */
> #include <unistd.h>
> #include <stdio.h>
>
> int main(void) {
> unsigned long long int physmem;
>
> printf("Pages: %d\n", sysconf(_SC_PHYS_PAGES));
> printf("Page size KB: %d\n", sysconf(_SC_PAGESIZE));
> physmem = sysconf(_SC_PHYS_PAGES) * sysconf(_SC_PAGESIZE) / 1000;
> printf("Physical Memory: %d\n", physmem);
> }


out_of_topic {
sysconf returns long. So the converison specifier
in your printf statements should be the one appropriate
for long and it is **not** %d. The variable physmem
has been declared as "long long int" so once again you
need to use the appropriate specifier to get the correct
value.
}

Actually this was only partially out of topic since the
answer has to do more with the behaviour of
printf rather than the system specific sysconf()
But for Solaris specific questions comp.unix.solaris
will almost always be a more appropriate resource
than this group.

 
Reply With Quote
 
 
 
 
Spiros Bousbouras
Guest
Posts: n/a
 
      09-01-2006
Spiros Bousbouras wrote:

> wrote:
>
> > What am I doing wrong?
> >
> > OUTPUT:
> > % ./sysconf.sun4x_59
> > Pages: 262144
> > Page size KB: 8192
> > Physical Memory: -1
> > %
> >
> > CODE:
> > /* sysconf.c */
> > #include <unistd.h>
> > #include <stdio.h>
> >
> > int main(void) {
> > unsigned long long int physmem;
> >
> > printf("Pages: %d\n", sysconf(_SC_PHYS_PAGES));
> > printf("Page size KB: %d\n", sysconf(_SC_PAGESIZE));
> > physmem = sysconf(_SC_PHYS_PAGES) * sysconf(_SC_PAGESIZE) / 1000;
> > printf("Physical Memory: %d\n", physmem);
> > }

>
> out_of_topic {
> sysconf returns long. So the converison specifier
> in your printf statements should be the one appropriate
> for long and it is **not** %d. The variable physmem
> has been declared as "long long int" so once again you
> need to use the appropriate specifier to get the correct
> value.
> }


Actually "unsigned long long int".

 
Reply With Quote
 
Eric Sosman
Guest
Posts: n/a
 
      09-01-2006


wrote On 09/01/06 15:55,:
> What am I doing wrong?


Three or four things that I can see. First, you're
asking Unix questions in a C newsgroup. Unix people tend
to know a fair amount about C and a reasonable number of
C people have some familiarity with Unix, but the two are
not synonomous. Do you ask questions about the vitamin
content of broccoli at an apple-growers' convention?

However, most of your mistakes are C mistakes, so we
may as well try to address them here.

> OUTPUT:
> % ./sysconf.sun4x_59
> Pages: 262144
> Page size KB: 8192
> Physical Memory: -1
> %
>
> CODE:
> /* sysconf.c */
> #include <unistd.h>
> #include <stdio.h>
>
> int main(void) {
> unsigned long long int physmem;
>
> printf("Pages: %d\n", sysconf(_SC_PHYS_PAGES));


Error of omission: Like many system calls and library
functions, sysconf() can fail. As is common practice, it
indicates its failure by returning a special value (-1, in
this case). You should check for that special value before
plowing blindly ahead; better to announce "I can't tell how
many pages there are" than to say "This machine has -1 pages!"

> printf("Page size KB: %d\n", sysconf(_SC_PAGESIZE));
> physmem = sysconf(_SC_PHYS_PAGES) * sysconf(_SC_PAGESIZE) / 1000;


You've gone to the trouble of using a `long long' for the
physmem variable, presumably because you expect the amount of
memory on the machine might exceed the capacity of a `long'.
Fine, but you haven't quite finished the job. Each of the
sysconf() calls returns a `long', and then you multiply those
together, and then you divide the product by a thousand, and
only then do you finally promote the result to `long long'.
All the arithmetic is carried out in plain `long', and if the
product was too large for `long' the damage has already been
done before the promotion. You'll need to convert one or both
of the sysconf() values to `unsigned long long' *before* trying
to multiply them; afterwards, it's too late.

> printf("Physical Memory: %d\n", physmem);


Do you know what kind of value the "%d" conversion requires?
Well, I'll tell you: it requires an `int'. What have you fed
it? An `unsigned long long'. "Size matters."

Error of omission: You've declared main() correctly, saying
that it returns an `int' value. Well, what `int' value would
you like it to return? (There is a special dispensation in the
latest compilers that lets you get away with this, but not all
compilers are so up-to-date or so lenient. Bad idea to rely
on a safety net that might not be there ...)

> }


--


 
Reply With Quote
 
Walter Roberson
Guest
Posts: n/a
 
      09-01-2006
In article <. com>,
<> wrote:
>What am I doing wrong?


>OUTPUT:
>% ./sysconf.sun4x_59
>Pages: 262144
>Page size KB: 8192
>Physical Memory: -1
>%


>CODE:
>/* sysconf.c */
>#include <unistd.h>


unistd.h is part of POSIX, but not part of the C language or standard
libraries, so this is not really an appropriate place to discuss it.
Try comp.unix.programmer

>#include <stdio.h>


>int main(void) {
> unsigned long long int physmem;


> printf("Pages: %d\n", sysconf(_SC_PHYS_PAGES));


What type does sysconf() return? Does that match the format
specifier %d ? Is it the right length for %d? Is it the right
signed vs unsigned for %d ?

> printf("Page size KB: %d\n", sysconf(_SC_PAGESIZE));


> physmem = sysconf(_SC_PHYS_PAGES) * sysconf(_SC_PAGESIZE) / 1000;


You are taking a value of whatever type sysconf() returns, and
multiplying it by another value of the same type. Because it is
the same two types that involved (not a mix of types), the result
will be of that type. If that type happens to be unsigned then the
value upon overflow is well defined, but if the type happens to
be signed then the resulting value is not defined.

You then take that value, of the type returned by sysconf(), and
divide it by something. If sysconf() returns an unsigned type
then the result is well defined, but if sysconf() returns a
signed type then the result is only well defined if the multiplication
did not overflow.

Once this calculation is completed, it will be of the same type
as what sysconf() returns. You then assign that value into
an unsigned long long. The method of doing that conversion is well
defined... though, as per the above, the value might be nonsense at
this point.

> printf("Physical Memory: %d\n", physmem);


What type have you assigned to physmem? Does that match the
format specifier %d? Is it the right length for %d? Is it the
right signed vs unsigned for %d ?

>}



--
"It is important to remember that when it comes to law, computers
never make copies, only human beings make copies. Computers are given
commands, not permission. Only people can be given permission."
-- Brad Templeton
 
Reply With Quote
 
Robert Gamble
Guest
Posts: n/a
 
      09-01-2006
wrote:
> What am I doing wrong?
>
> OUTPUT:
> % ./sysconf.sun4x_59
> Pages: 262144
> Page size KB: 8192
> Physical Memory: -1
> %
>
> CODE:
> /* sysconf.c */
> #include <unistd.h>


This is not a Standard C header, it is a POSIX header, POSIX is
off-topic here.

> #include <stdio.h>
>
> int main(void) {
> unsigned long long int physmem;
>
> printf("Pages: %d\n", sysconf(_SC_PHYS_PAGES));


sysconf is not a Standard C function, again it is POSIX. You would at
least need to tell us what type this function returns for us to be able
to determine if you are providing the correct conversion specifier to
printf. If I remember correctly, POSIX sysconf returns long, if this
is the case on your platform you should be using %ld, not %d in the
printf call.

> printf("Page size KB: %d\n", sysconf(_SC_PAGESIZE));


Same as above.

> physmem = sysconf(_SC_PHYS_PAGES) * sysconf(_SC_PAGESIZE) / 1000;


The multiplication and division operators have the same precedence and
have a left-to-right associativity which means that the result of the
multiplication will happen first which may result in overflow before
the division occurs. This is because the result of the multiplication
will be of type long, you would do well to either reorder the
expression so the division happens first (which may change the result
if the dividend is sufficiently small) or cast one of the multipliers
to unsigned long long:

physmem = (unsigned long long) sysconf(_SC_PHYS_PAGES) *
sysconf(_SC_PAGESIZE) / 1000;

so that the arithmetic is carried out in the wider type.

> printf("Physical Memory: %d\n", physmem);


physmem has a type of unsigned long long, you should be using the
conversion specifier "%llu" instead of "%d" which is for signed int.

Robert Gamble

 
Reply With Quote
 
cjblaine@gmail.com
Guest
Posts: n/a
 
      09-03-2006
Thanks for all of the replies, even for the ones with attitude.

Using %llu in my printf() solved the problem.

[ Note to self: Hide all UNIX-specific code when asking C "long long
int" questions ]
[ in comp.lang.c. ]

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
GIDS 2009 .Net:: Save Big, Win Big, Learn Big: Act Before Dec 29 2008 Shaguf ASP .Net 0 12-26-2008 09:29 AM
GIDS 2009 .Net:: Save Big, Win Big, Learn Big: Act Before Dec 29 2008 Shaguf ASP .Net Web Controls 0 12-26-2008 06:11 AM
GIDS 2009 Java:: Save Big, Win Big, Learn Big: Act Before Dec 29 2008 Shaguf Python 0 12-24-2008 07:35 AM
GIDS 2009 Java:: Save Big, Win Big, Learn Big: Act Before Dec 29 2008 Shaguf Ruby 0 12-24-2008 05:07 AM
CType(x,Integer) vs. Integer.Parse(x) =?Utf-8?B?Sm9l?= ASP .Net 7 02-07-2006 02:30 AM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57