Whats wrong with this code?? (MS-DOS/TC 1.0)
John Stanley
john at viper.Lynx.MN.Org
Thu Mar 24 02:25:32 AEST 1988
In article <4935 at sigi.Colorado.EDU>
murillo at 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 at viper.UUCP)
Software Consultant - DynaSoft Systems
UUCP: ...{amdahl,ihnp4,rutgers}!meccts!viper!john
More information about the Comp.lang.c
mailing list