Why am I multiplying when I want to divide (C)?

Discussion in 'Mac Programming' started by farmerdoug, Feb 5, 2010.

  1. farmerdoug macrumors 6502a

    Joined:
    Sep 16, 2008
    #1
    Here's the code:

    Code:
    p = 0;
    		for ( i = 0; i < lp; i++)
    			
    				{
    					p += fwrite(&Pt[i*pagesize], sizeof(char), pagesize, fp);
    						
    				}
    		fclose(fpt);
    		printf("%d\n", p);
    		printf("%d %d \n",pagesize, p/pagesize);
    
    Here's the output:

    264600
    5400 14288400

    Does this make sense to anybody????
     
  2. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #2
    What are the types of p and pagesize?

    Code:
    #include <stdio.h>
    
    int main (int argc, const char * argv[]) 
    {
    	size_t p;
    	size_t pagesize;
    
    	p = 264600;
    	pagesize = 5400;
    
    	printf("%d\n", p);
    	printf("%d %d \n",pagesize, p/pagesize);
    
    	printf("%d * %d = %d\n", p, pagesize, p*pagesize);
    }
    
    Output:
    Code:
    264600
    5400 49 
    264600 * 5400 = 1428840000 
    
    Notice that your unexpected output differs from the actual product by a factor of 100.
     
  3. lloyddean macrumors 6502a

    Joined:
    May 10, 2009
    Location:
    Des Moines, WA
    #3
    The question seems about as malformed as the code fragment.

    Looks to be writing an 'lp' count of 'pagesize' blocks of the array 'Pt' to the stream 'fp'.

    The multiplication is used to calculate an 'offset' within the array 'Pt'.
     
  4. farmerdoug thread starter macrumors 6502a

    Joined:
    Sep 16, 2008
    #4
    Sorry, I don't understand. I've never declared a variable using size_t. Besides, I don't see any likelihood of overflow.

    One of us is missing something.
    I am writing lp pages sized pagesize to a file. p should be pagesize*lp but this is fact has little bearing on the two print statements that follow. If p is 264600 and pagesize in 5400, why is 264600/5400 not 49 as in chown's code.
     
  5. lloyddean macrumors 6502a

    Joined:
    May 10, 2009
    Location:
    Des Moines, WA
    #5
    Code:
    int fwrite( const void *buffer, size_t size, size_t count, FILE *stream );
    What are the 'types' of 'p', 'i', 'lp', 'pagesize' and 'Pt[]'.

    Further hint:

    Code:
    int fwrite( const void *buffer, size_t size, size_t count, FILE *stream );
    The return value is the number of objects written.
     
  6. farmerdoug thread starter macrumors 6502a

    Joined:
    Sep 16, 2008
    #6
    You trying to out terse me.

    Modifying the code doesn't change the output.
    fwrite returns the number of bytes read, it was read in in chunks of pagesize.
    a total of p/pagesize should print 49.
    Code:
    fpt = fopen(filename, "w");
    		p = 0;
    		for ( i = 0; i < lp; i++)
    			
    				{
    					p += fwrite(&Ptrading[i*pagesize], sizeof(char), (size_t) pagesize, fpt);
    						
    				}
    		fclose(fpt);
    		printf("%d\n", p);
    		printf("%ld %ld \n",(size_t)pagesize, (size_t)p/(size_t)pagesize);
    				
    
    P, i, lp are ints.
    pagesize is #define to be 5400.
    Pt is an array allocated to be much larger than lp*pagesize
     
  7. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #7
    Instead of posting code fragments, and us trying to debug it without compilable context, please rewrite your code as a small isolated self-contained program that exhibits the problem.

    You don't have to provide real data. You can use artificial data, generated in any manner (including not generated at all, in which case the output data will be all zeros).

    All the data types, sizes, etc. should be identical to your real program.

    You should allocate memory exactly like your real program.

    You should write data (which was artificially generated) in the same manner as the real program does. Not doing so would defeat the point of the program.

    You should have a main() function and whatever other functions you think make sense in a small self-contained program.

    If the self-contained program doesn't exhibit the problem, then you have to figure out why that is.

    If the self-contained program does exhibit the problem, then everyone else will be able to see it, and some may even be able to determine why.

    As it stands now, you're the only one who has actual compilable code, hence the only one who has actual debuggable code. However, you also find yourself unable to debug that code.

    The only way to solve the problem is to create the intersection of compilable code with debugging skills. If that intersection remains empty, then all you can do is solve the problem by accident.
     
  8. lloyddean macrumors 6502a

    Joined:
    May 10, 2009
    Location:
    Des Moines, WA
    #8
    No not at all. I'm simply trying to give you and idea of what it's like when the other end of a conversation expects you to be a mindreader and work with assumed common information where there is none.

    I was going to post something to the effect of what chown33 just posted so I'll let his stand.
     
  9. jared_kipe macrumors 68030

    jared_kipe

    Joined:
    Dec 8, 2003
    Location:
    Seattle
    #9
    The fact that p came out as 264600 when expressed as an integer does not necessarily mean it is an integer and will follow integer division.

    Try
    printf("%d %d \n",pagesize, (int)p/pagesize);
    or maybe
    printf("%d %d \n",pagesize, (int)p/(int)pagesize);

    As an idea...

    EDIT: my first inclination would be to also set a breakpoint down in there somewhere and observe the values.
     
  10. farmerdoug thread starter macrumors 6502a

    Joined:
    Sep 16, 2008
    #10
    guys.

    On (too) many occasions, I have suffered because I have not posted the full code. You would easily see things I have missed. On the other hand, your responses, when not yelling at me, are usually helpful; I eventually get it. So let me just be a little more specific since my working skills preclude writing other test code until absolutely necessary. I'm an old dog stuck in my ways.

    The file gets written to; I've looked at it and it seems ok. The division error seems to be out of left field. Do you a clue? Any suggestions where I should look.

    thanks
     
  11. lloyddean macrumors 6502a

    Joined:
    May 10, 2009
    Location:
    Des Moines, WA
    #11
    He gets it but won't follow the path to enlightenment.

    I'm 53 but I'm still learning and applying it as well.
     
  12. Maserati7200 macrumors 6502a

    Maserati7200

    Joined:
    Mar 17, 2009
    Location:
    11230, Midwood, Brooklyn, NY, USA, North America
    #12
    my god, after reading this thread, I'm glad I don't write code for a living... :eek:
     
  13. farmerdoug thread starter macrumors 6502a

    Joined:
    Sep 16, 2008
    #13
  14. lloyddean macrumors 6502a

    Joined:
    May 10, 2009
    Location:
    Des Moines, WA
    #14
    You get enough 'novice' mind readers together and eventually someone is going to have enough information to combine with their interpretation of your question in order to give you a 'useful' answer.

    The fact is things could go quicker and you'd get more relevant response if you provided more complete questions and useful information with which to work.

    I'm trying to be helpful but nothings happening ...
     
  15. jared_kipe macrumors 68030

    jared_kipe

    Joined:
    Dec 8, 2003
    Location:
    Seattle
    #15
    What platform are you compiling for?

    Its like its putting 5400 into an odd size or something at compile time. Thus its not obeying normal arithmetic. or 264600 is getting converted to whatever type the compiler chose for 5400 and it gives weird results....
     
  16. farmerdoug thread starter macrumors 6502a

    Joined:
    Sep 16, 2008
  17. lloyddean macrumors 6502a

    Joined:
    May 10, 2009
    Location:
    Des Moines, WA
    #17
  18. jared_kipe macrumors 68030

    jared_kipe

    Joined:
    Dec 8, 2003
    Location:
    Seattle
    #18
    so.. you're compiling c code for an intel mac to run?

    Very odd then. I cannot duplicate it with any combination of types.

    Do you get any compiler warnings?
     
  19. farmerdoug thread starter macrumors 6502a

    Joined:
    Sep 16, 2008
    #19
    Jared

    Yes, very odd. Haven't got a clue. pagesize is defined as

    #define rows 10
    #define cols 45
    #define element 12
    #define pagesize rows*cols*element
     
  20. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #20
    Bad define. Very bad.

    Do a textual replacement on your original expression:
    Code:
    p/pagesize
    
    The result will be:
    Code:
    p/rows*cols*element
    
    The precedence of multiply and divide is the same, so figure out what the above evaluates to. (An exercise left for the reader.)

    Redo your define as:
    Code:
    #define pagesize (rows*cols*element)
    
    In general, always put parens around any macro body that contains an expression.
     
  21. jared_kipe macrumors 68030

    jared_kipe

    Joined:
    Dec 8, 2003
    Location:
    Seattle
    #21
    LOOOOOOOOOOOOLLLLLLL not odd anymore!

    p/pagesize = p/10*45*12= 14288400

    Its funny because I kept trying to figure out what was changing p or pagesize by a factor of 100. Well you took a factor of 10 out of pagesize and devided p by that factor of 10.
     
  22. farmerdoug thread starter macrumors 6502a

    Joined:
    Sep 16, 2008
  23. lloyddean macrumors 6502a

    Joined:
    May 10, 2009
    Location:
    Des Moines, WA
    #23
    farmerdoug,

    Remember this, or did you ignore it, from the last thread.

    Code:
    #define kPAGES                  (2000)
    #define kROWS                   (10)
    #define kCOLUMNS                (45)
    #define kBYTE_COUNT_PER_COLUMN  (12 * sizeof(char))
    #define kBYTE_COUNT_PER_ROW     (kCOLUMNS * kBYTE_COUNT_PER_COLUMN)
    #define kBYTE_COUNT_PER_PAGE    (kROWS * kBYTE_COUNT_PER_ROW)
    
    char* allocate_memory(void)
    {
        void*   ptr = calloc((kPAGES * (kROWS * kCOLUMNS)), kBYTE_COUNT_PER_COLUMN);
        if ( NULL == ptr )
        {
            printf("no memory");
        }
    
        return (char*)ptr;
    }
    
    //n = number of items to sort
    void sort(char* array, int n, int row, int column)
    {
        char    tmp[kBYTE_COUNT_PER_PAGE];
    
        #define INDEX(PP,RR,CC) ((PP * kBYTE_COUNT_PER_PAGE) + ((RR * kBYTE_COUNT_PER_ROW) + (CC * kBYTE_COUNT_PER_COLUMN)))
        #define DUMP(NN) for(int i=0; i<NN; i++) {printf("%s  \n ",&array[INDEX(i,0,3)]);}
    
        DUMP(n);
    
        printf("\n");
    
        for ( int j = (n - 1); j >= 0; j-- )
        {
            for ( int k = 1; k <= j; k++ )
            {
                if ( atoi(array + (k - 1)*kPAGES + row*kROWS + column*kCOLUMNS) > atoi(array + (k)*kPAGES + row*kROWS + column*kCOLUMNS) )
                {
                    printf("\n");
    
                    memcpy(tmp, &array[INDEX(k - 1, 0, 0)], kBYTE_COUNT_PER_PAGE);
                    memcpy(&array[INDEX(k - 1, 0, 0)], &array[INDEX(k,0,0)], kBYTE_COUNT_PER_PAGE);
                    memcpy(&array[INDEX(k,0,0)], tmp, kBYTE_COUNT_PER_PAGE);
    
                    DUMP(n);
                }
            }
        }
    
       #undef INDEX 
       #undef DUMP
    }
    
    Note the use of parentheses to FORCE proper expansion and association of math operators during expansion.

    Again, please, please, PLEASE given complete definitions of ALL variables and macros in ANY and ALL code posts for the quickest most useful responses.

    Anyway have and nice weekend.

    EDIT: This hasn't been compiled and was done off the top me me head and may contain syntax errors
     
  24. farmerdoug thread starter macrumors 6502a

    Joined:
    Sep 16, 2008
    #24
    Lloyd

    No, I didn't remember it. Thanks for the help. Can't have a good weekend until this code is done LOL. Best.
     
  25. Sydde macrumors 68020

    Sydde

    Joined:
    Aug 17, 2009
    #25
    Always use parens, even when you think they might not be needed. Consider this little error I made not too long ago:

    Code:
      int   eventKeys[[NSApp currentEvent] modifierFlags];
       if ( eventKeys&NSShiftKeyMask != 0 ) {
          // extend the selection
       }
    The if statement did not execute correctly because "&" has a lower priority than "!=" - the fix was "( (eventKey&NSShiftKeyMask) != 0 )", though admittedly the "!= 0" part is kind of redundant.
     

Share This Page