[comp.lang.c] Whats wrong with this code??

murillo@sigi.Colorado.EDU (Rodrigo Murillo) (03/19/88)

OK, I give up.  Can some one tell me why the expresion below (see comments)
yields a result that is different than what the initial results would suggest?

A hand multiplication of the resultant disk values (total sectors free, bytes
per sector, etc.) yields the correct number of bytes free,  but the same
expression yields a number that hsa no correlation with the original values.

Do I need a cast somewhere in the expression?
Please e-mail me.  Thanks.
---------------------------------------------------------
/* program determines amount of disk free in bytes */
 
#include <dos.h>
/* relevant structure is:

struct dfree {
   unsigned df_avail;   /* available clusters */
   unsigned df_total    /* total cluster */
   unsigned df_bsec;    /* bytes per sector */
   unsigned df_sclus;   /* sectors per cluster */

*/

main()
{
 
/* This seems to be the proper prototype, but TC barfs
   void getdfree(int, struct dfree *); */
 
   unsigned long bytesf;    /* total bytes free */
   struct dfree dfreep;
 
   getdfree(0, &dfreep);
 
   printf("Available clusters: %u\n", dfreep.df_avail);
   printf("Total clusters: %u\n", dfreep.df_total);
   printf("Bytes per sector: %u\n", dfreep.df_bsec);
   printf("Sectors per clusters: %u\n", dfreep.df_sclus);
 
   /* THIS IS THE OFFENDING EXPRESION */ 
   /* why is this number different that the numbers from above would
   produce?  My calculator produces the right value, but the expression
   below does not! */
 
   bytesf =  dfreep.df_avail * dfreep.df_sclus * dfreep.df_bsec;
 
   printf("Disk free: %u\n", bytesf);
 
}

-- 
_______________________________________________________________________________
 Rodrigo Murillo, University of Colorado - Boulder  (303) 761-0410 
 murillo@boulder.colorado.edu | ..{hao|nbires}!boulder!murillo
 ( Machines have less problems.  I'd like to be a machine. -- Andy Worhol )

swarbric@tramp.Colorado.EDU (Frank Swarbrick) (03/19/88)

I had this same problem.  You must multiply it by 1L to get it convert to a
long unsigned int.  Make the 1L your first multiplictor [sic?].  I also tried
using the (unsigned long) thing, but multiplying by 1L seems to be the only
way to get it to work.

Frank Swarbrick (and his cat)
swarbric@tramp.UUCP               swarbric@tramp.Colorado.EDU
...!{hao|nbires}!boulder!tramp!swarbric
"Welcome back my friends to the show that never ends..."

swarbric@tramp.Colorado.EDU (Frank Swarbrick) (03/19/88)

Oops, one more thing.  your printf should have "%ul" in it instead of just
"%u".

Frank Swarbrick (and his cat)
swarbric@tramp.UUCP               swarbric@tramp.Colorado.EDU
...!{hao|nbires}!boulder!tramp!swarbric
"Welcome back my friends to the show that never ends..."

john@viper.Lynx.MN.Org (John Stanley) (03/24/88)

In article <4935@sigi.Colorado.EDU>
 murillo@boulder.Colorado.EDU (Rodrigo Murillo) writes:
 >OK, I give up.  Can some one tell me why the expresion below (see comments)
 >yields a result that is different than what the initial results would suggest?

  (part of question deleted)

 >/* relevant structure is:
 >
 >struct dfree {
 >   unsigned df_avail;   /* available clusters */
 >   unsigned df_total    /* total cluster */
 >   unsigned df_bsec;    /* bytes per sector */
 >   unsigned df_sclus;   /* sectors per cluster */

  You forgot the closing brace here, but I assume that was just an
oversight in copying the example...

 >   /* THIS IS THE OFFENDING EXPRESION */ 
 >   /* why is this number different that the numbers from above would
 >   produce?  My calculator produces the right value, but the expression
 >   below does not! */
 > 
 >   bytesf =  dfreep.df_avail * dfreep.df_sclus * dfreep.df_bsec;
 > 
 >   printf("Disk free: %u\n", bytesf);

  The problem is a fairly common one when multiplying large integers.
If you take the numbers displayed by your sample program and multiply
them out by hand (calculator is ok too.. :) I suspect you'll discover
the number you created was greater than 65535.  When this happens in
the example you gave, the number gets truncated.  It doesn't matter
that you told the compiler you're saving the number into a long, what
matters is that the resultant type from multiplying two integers
together is another integer.
  You program (doing just what you told it to do) multiplys out the
three integers, truncating when the results exceeds 65535, converts
the integer to a long and stores it into the long.
  The safe way to fix this is:

      bytesf =  (long)dfreep.df_avail
              * (long)dfreep.df_sclus
              * (long)dfreep.df_bsec;

--- 
John Stanley (john@viper.UUCP)
Software Consultant - DynaSoft Systems
UUCP: ...{amdahl,ihnp4,rutgers}!meccts!viper!john