Dived Error with Structure Elements

The divide statement below gives an entirely wrong answer:

     Result = dfi->Free / dfi->Allocated;     // Result <- 178956470 = 0x0AAAA8B6

where dfi->Free is -12000 and dfi->Allocated is 24, and the correct answer is -500.  

If I just bring the values into temps first it works fine:

      temp1 = dfi->Free;
      temp2 = dfi->Allocated;
      Result = temp1 / temp2;  // Result <- -500

Is there some restriction on C divides  with structure elements that I'm not aware of?  All the variables are "long" types.

Thanks for any input.
Steve
stevaAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

stevaAuthor Commented:
I'm doing the compile with VC++ 6.0 and the source is a .c, not .cpp.
InteractiveMindCommented:
Does this make any difference:

   Result = (dfi->Free) / (dfi->Allocated);

?
InteractiveMindCommented:
Mind you, my tests perform fine without using parenthesis--but who knows. :-\

Or something like...

   Result = (*dfi).Free / (*dfi).Allocated ;

Perhaps there's some mistake elsewhere? If the above suggestions don't work, then could we see some more of your code.
Expert Spotlight: Joe Anderson (DatabaseMX)

We’ve posted a new Expert Spotlight!  Joe Anderson (DatabaseMX) has been on Experts Exchange since 2006. Learn more about this database architect, guitar aficionado, and Microsoft MVP.

stevaAuthor Commented:
The parentheses don't help. Here's the source. (This one's .cpp, which also fails.)

// div_err.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"


typedef struct {
      unsigned long           Magic;
      long                     BufSize;            

      long                      NumberOfBufs;
      unsigned long      Build;

      unsigned long      Pad0;
      unsigned long      JournalCompiled;      

      unsigned long      j_mode;            
      unsigned long      j_records;            

      unsigned long      MinReqSize_KB;      
      unsigned long      MinFileSize_MB;      

      unsigned long      DfOn;
      unsigned long      TrackAll;            

      long            TrackedFiles;
      unsigned long      BufsAllocated;

      long            DfEnable;
      long            FreeBufs;

      long            UsedBufCount;
      long            AvgDiskRequestsPending;

      long             EarlyPasses;            
      long             PkDiskRequestsPending;

      unsigned long      SearchDepth;
      long             BuildNo;

      long             AccessThreshold;      
      long             ControlBits;

      long             AvgLaunchUsec;            
      long             AvgDiskUsec;            
      
      long             Launches;                  
      long             PkDiskUsec;

      long             LicenseInfo;            
      long             RtlCopyRate;

      unsigned long       RequestIntervalUsec;

      long             RequestServiceTimeUsec;

      long             ShortPasses;            
      long             NoBufPasses;            

      long             ActiveRequests;
      long            UsedBufs;            

      long             AccReqs;      
      long             PkLaunchUsec;

      long            AccReqLength_KB;      
      unsigned long      RequestIntervalPkUsec;

      long            BufsHitWhileLoading;
      long            QualifiedMisses;

      long            MajVer;
      long            MinVer;

} DF_INFO;


int main(int argc, char* argv[])
{
 DF_INFO df_inf;
 long temp1, temp2, temp3;
 
 DF_INFO *dfi = &df_inf;

      dfi->FreeBufs = -12000;
      dfi->BufsAllocated = 24;

      temp1 = dfi->FreeBufs / dfi->BufsAllocated;                // temp1 <- 178956470

      temp2 = dfi->FreeBufs;
      temp3 = dfi->BufsAllocated;
      temp1 = temp2 / temp3;                                 // temp1 <- -500

      return 0;
}

stevaAuthor Commented:
Ah!  If you make BufsAllocated a long instead of an unsigned long it works!  So why does dividing an unsigned long by a long fail?
stevaAuthor Commented:
Ah!  It appears that if you divide a signed value by an unsigned value, the compiler first casts the numerator to be unsigned.  So we're dividing -12000 = 0xFFFFD120 by 0x18 to get 0x0AAAA8B6 = 178956470.  You'd think it would give some warning that it was applying casts. You'd also think that it might cast a different way: if numerator OR denominator were signed, cast the other to be signed so the sign is maintainted. Do you know of any C rules or documentation that addresses this?

In any case.  I'll give you the points, just for chatting with me about it.

Thanks,
Steve
InteractiveMindCommented:
> Do you know of any C rules or documentation that addresses this?
Nothing official, but it is explained briefly here:
http://www.gimpel.com/html/oldbugs/bug573.htm

I'm glad it's sorted now :-)

Also, sorry about the delay in response--I'm in the GMT timezone, and went to bed quite early (making up for hours I spent the other night, playing with my rubik's cube :-P).

Cheers.

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Programming

From novice to tech pro — start learning today.