FOR LOOP not iterate beyond 800000

Discussion in 'Mac Programming' started by Nishad, Oct 10, 2007.

  1. Nishad macrumors newbie

    Joined:
    Aug 2, 2007
    #1
    hi all,

    i wrote a simple FOR LOOP program in cocoa-objective c (MAC os- compiler XCode). but it not working properly. the loop iterating only upto some value near to 714300( value change each time running). program is given below.

    Code:
    #import <Cocoa/Cocoa.h>
    
    int main(int argc, char *argv[])
    {
       unsigned long long i=1;
       
       for(i=1;i!=0;++i)
                printf("%llu\n",i);
    
          printf("finished");
          //printf("\n%llu",i++);
          
          //printf("\r%llu",i);
          
           return NSApplicationMain(argc,  (const char **) argv);
    }
    if first printf statement is replaced as printf("%llu-",i); it iterate beyond 1000000 but it run very slowly( take nearly one hour to reach 1000000). what is the problem with this program.

    with thanks and regards

    Nishad
     
  2. Sayer macrumors 6502a

    Sayer

    Joined:
    Jan 4, 2002
    Location:
    Austin, TX
    #2
    You are not supposed to call NSApplicationMain thousands of times. You only call it once to initialize the application, load nibs and get a run loop started.

    What in the world are you trying to do?
     
  3. sammich macrumors 601

    sammich

    Joined:
    Sep 26, 2006
    Location:
    Sarcasmville.
    #3
    You do realise that is an infinite loop? Why are you printing all the cardinal numbers? EDIT: ignore that if you know what you're doing, in case you don't...

    "i != 1" is not a terminating condition. If you wanted an infinite loop, just leave out that condition.

    Code:
    for(i=1; ;++i)
          printf("%llu\n",i);

    btw: sayer, the loop only covers the first printf statement.

    There isn't any wrong with that code. A little indentation consistency might also be handy.
     
  4. pilotError macrumors 68020

    pilotError

    Joined:
    Apr 12, 2006
    Location:
    Long Island
    #4
    Not sure what your trying to accomplish here, but...

    Typically, the center part of the for statement defines the termination condition. You only have i != 0 which is a condition it will never hit, which is why sammich correctly identified it as an infinite loop.

    If you want to loop from 1 to 800,000 inclusive, just set the upper bounds that you want to loop to. In the below example when i > 800000, the loop will stop and you will get the "Finished" print.

    Code:
       unsigned long long i=1;
       
       for(i=1; i <= 800000; i++)
                printf("%llu\n",i);
    
       printf("finished");
    
     
  5. huntercr macrumors 65816

    Joined:
    Jun 6, 2006
    #5

    What happens when it gets to your "magic" number ( 714300 ) ? Does it actually dump core?

    if I compile this under gcc without the return NSApplicationMain, it works for me. I get to more than 1,000,000 in under 30 seconds.

    I wonder if you are running into a buffering problem with your printf()s
    maybe? Try adding in a usleep(10); into the loop and see if that helps. It will slow your loop down somewhat but if it works, that will tell you something.
     
  6. toddburch macrumors 6502a

    Joined:
    Dec 4, 2006
    Location:
    Katy, Texas
    #6
    Why are you calling this
    Code:
    for ( i=1 ; i != 0 ; i++) ... 
    
    an infinite loop? i will eventually wrap, and the condition will be met. Right?

    I'll agree that it's a rather long loop (well, in this case, a long long loop ;) ) but finite nonetheless.

    Todd

    Edit: try it, but on a smaller scale...
    Code:
    #include <iostream>
    using namespace std ; 
    int main (int argc, char * const argv[], char * envp[] ) {
    	char i ; 
    	cout << "Hello, World!\n";
    	for (i= 1 ; i != 0 ; i++) ;
    	cout << "After infinite loop.  Duh.\n"; 
        return 0;
    }
     
  7. toddburch macrumors 6502a

    Joined:
    Dec 4, 2006
    Location:
    Katy, Texas
    #7
    Maybe this is the problem.

    If you are running under XCode, perhaps XCode keeping the output in a buffer for display, and XCode is running out of buffer, or a control for that buffer has maxed out. What happens when it stops? Certainly you are getting a message of some sorts.

    Todd
     
  8. sammich macrumors 601

    sammich

    Joined:
    Sep 26, 2006
    Location:
    Sarcasmville.
    #8
    You can't be serious?

    I've tried this loop using C in the terminal, and it takes 10s exactly to print out every million numbers. Without printing, it goes on forever. Take a humble 4.191 seconds to count to 1 billion (without printing).

    I sure hope you are just joking. Or perhaps you could enlighten me? How does counting to infinity get you back to zero? Won't it throw an error?
     
  9. toddburch macrumors 6502a

    Joined:
    Dec 4, 2006
    Location:
    Katy, Texas
    #9
    Surely you can't be serious that you think I'm not serious! I'm as serious as a heart attack.

    An unsigned long long is 8 bytes. If you can figure out how to count to infinitely in 8 bytes on Intel, AMD, IBM, (whoever's) hardware, please share.

    Otherwise, when the 8 byte value reaches X'FF FF FF FF FF FF FF FF', and you add 1, guess what happens? There's this concept of overflow, and you get ZERO as a result.

    The small sample I posted illustrates this. Substitute short, long, whatever, and it eventually ends.

    Seriously!

    Todd

    p.s. This is the definition I'm using for infinite loop: http://en.wikipedia.org/wiki/Infinite_loop
     
  10. MongoTheGeek macrumors 68040

    MongoTheGeek

    Joined:
    Sep 13, 2003
    Location:
    Its not so much where you are as when you are.
    #10
    Bignum :)

    The question though is what the compiler is configured to do when you increment the highest integer or what not there are a few possibilities.

    1) Arithmatic trap. The system throws an error at the operation.
    2) Overflow error. The program tries to write to the next higher memory location which causes an error.
    3) Overwrites other memory. There is no protection and the next higher spot in memory is incremented or overwritten. This will have different effects on Intel vs PPC. PPC has the potential to do bad things. Intel may just munge the number FFFF -> 0101 or it may overwrite the instruction before the number.
    4) Rolls over to either -Maxint or 0 depending on if the number is signed or un.
     
  11. hankolerd macrumors 6502

    hankolerd

    Joined:
    Sep 19, 2007
    Location:
    Seattle, WA
    #11
    just try something like this.

    // Start of program
    class test{
    public static void main(String Args[])
    {
    int i;
    for (i = 1; i != 0; i++)
    ;

    System.out.println(i);
    }
    }
    // End of program

    after about 5 seconds a 0 will print out.
    EDIT: I have spacing in there, but for some reason it's not showing up, sorry.
     
  12. kainjow Moderator emeritus

    kainjow

    Joined:
    Jun 15, 2000
    #12
    I love how all these threads with originally simple questions turn into complex debates. No wonder the OPs usually never reply ;)
     
  13. atszyman macrumors 68020

    atszyman

    Joined:
    Sep 16, 2003
    Location:
    The Dallas 'burbs
    #13
    Well it all depends on the '+' operator and whether or not it allows addition when an overflow occurs (like adding 1 to 0xffff ffff ffff ffff). Of course counting to the end of a 64-bit integer will take a really long time. At 4.91 seconds to count to 1 billion, it will take roughly 20 seconds to hit the fully loaded 32 bit value (a little over 4 billion). From there it will take 2^32 times as long to hit the end of a 64-bit integer to see if it actually wraps.

    2,872,067,269,205.48 years if you follow the math (that's without factoring in leap years so it's a bit of an overestimate, but who the hell is going to be around to prove me wrong?).
     
  14. Arisian macrumors 68000

    Arisian

    Joined:
    Sep 14, 2007
    Location:
    China
    #14
    its infinite.... and that makes me laugh
     
  15. atszyman macrumors 68020

    atszyman

    Joined:
    Sep 16, 2003
    Location:
    The Dallas 'burbs
    #15
    You are correct. Forgot software generally hits max and then goes to the value Inf.

    My guess is that sammich has done hardware logic design. There if you put together an n-bit counter when you reach the value of 2^n-1 the next value the counter outputs is zero. Software does not usually do this.

    However it would still take an exorbitantly long time to hit the max 64-bit value.
     
  16. Krevnik macrumors 68040

    Krevnik

    Joined:
    Sep 8, 2003
    #16
    Integers have no concept of 'Inf', floats do. Floats will not roll over, but everything I have done in C using integers roll over, and I have actually written plenty of code that abuses this fact on multiple architectures.

    It really depends a lot on the data type and the language. Integers in a register behave very much like an n-bit counter/register in hardware logic design, kinda because that is all an integer register /is/. :)

    I think the misconception here is that floating point numbers and integers behave the same. They don't.
     
  17. atszyman macrumors 68020

    atszyman

    Joined:
    Sep 16, 2003
    Location:
    The Dallas 'burbs
    #17
    I may stand corrected...

    I'm too lazy to actually try it, but at any rate it would probably be wise to move to either a short or a normal integer instead of an unsigned long to verify that the loop does actually exit when desired. The amount of time required for a long to "roll over" will probably be well past when the sun goes Supernova.
     
  18. notjustjay macrumors 603

    notjustjay

    Joined:
    Sep 19, 2003
    Location:
    Canada, eh?
    #18
    I remember the days when I built digital clocks and counters using discrete TTL logic chips. A 4-bit counter (like the 74163) would indeed reset to 0 when you hit the counter limits. But now I program in C++, and I expect chars, ints, etc. to behave exactly the same way. Never tried it with a floating point type. That said, although I expect the behaviour, I feel it's bad programming practice to count on it for any practical purpose (mostly because the "size" definition for char, int, etc. could change from platform to platform).

    Just the other day I solved a problem at work where the complaint was that a numeric value should be settable from 0-9 but should not "roll over", e.g. if you kept decreasing from 0 it should not be allowed to go to 9. But the code never attempted a rollover, it simply said:

    if (user pressed "decrease" button) number--;
    if (user pressed "increase" button) number++;

    if (number < 0) number = 0;
    if (number > 9) number = 9;

    Should work, right?

    As soon as I saw that number was defined as an unsigned int, I knew what the problem was. If the value was 0 and you subtracted one from it, you didn't get -1 ...
     
  19. Krevnik macrumors 68040

    Krevnik

    Joined:
    Sep 8, 2003
    #19
    Yes, a 64-bit long long like was used is mental suicide. Might as well just watch paint dry. :)

    As for why it is slowing down to a crawl, I think an earlier poster is spot-on... If the OP is running it from XCode, the run log will get huge from all the text being spammed into stdout and start slowing down.
     
  20. atszyman macrumors 68020

    atszyman

    Joined:
    Sep 16, 2003
    Location:
    The Dallas 'burbs
    #20
    Actually paint dries much faster...:)

    With a 4GHz CPU doing a single add every clock cycle it would take

    146.26 years and that doesn't include printing to the screen.

    Gotta love big counters...
     
  21. toddburch macrumors 6502a

    Joined:
    Dec 4, 2006
    Location:
    Katy, Texas
    #21
    It wraps. And you don't have to wait a bazillion years to see it. ;)

    Code:
    #include <iostream>
    using namespace std ; 
    int main (int argc, char * const argv[], char * envp[] ) {
    
    	int i ; 
    	unsigned long long k ; 
    	
    	cout << "length of k = " << sizeof(k) << "\n";
    
    	k = 0 ;  
    	for (i=0 ; i <= 64 ; i++) k = (i) ? k*2 : 1  ;  
    
    	k -= 1 ; 
    	cout << "2**64 - 1 = " << k << endl ; 	
    
    	k += 1 ; 
    	cout << "2**64 = " << k << endl ; 
    
    	k += 1 	; 
    	cout << "2**64 + 1 = " << k << endl ; 
    
        return 0;
    }
    Output:

    Code:
    [Session started at 2007-10-10 14:08:44 -0500.]
    length of k = 8
    2**64 - 1 = 18446744073709551615
    2**64 = 0
    2**64 + 1 = 1
    
    Todd
     
  22. atszyman macrumors 68020

    atszyman

    Joined:
    Sep 16, 2003
    Location:
    The Dallas 'burbs
    #22
    Well sure, if you want to cheat...:D
     
  23. Krevnik macrumors 68040

    Krevnik

    Joined:
    Sep 8, 2003
    #23
    Reminds me of a bug I found in some code I was tinkering with years ago (a PennMUSH add-on called HSpace)... It added the concept of ships/planets/etc to PennMUSH and I was customizing it for my own enjoyment. I found a bug in the code where the calculations for how damage bleeds through shields was flawed. If you set the max shields for a ship to be 0, it would cause a divide by zero error when calculating damage bleed through (NaN results because it was floating point). Because NaN +/-/*/etc any other floating point number was also NaN... the hull's armor value would become NaN.

    Long story short, the bug made any ships without shields invincible. Pretty interesting cheat. :)
     
  24. MongoTheGeek macrumors 68040

    MongoTheGeek

    Joined:
    Sep 13, 2003
    Location:
    Its not so much where you are as when you are.
    #24
    When I saw there was still discussion here it hit me that you might not have to wait 100 years for this to run. Compilers often unroll for loops and optimize away spurious statements. That could partially explain the OP's problem.
     
  25. Krevnik macrumors 68040

    Krevnik

    Joined:
    Sep 8, 2003
    #25
    A call to printf() wouldn't be considered spurious by the compiler (as it goes beyond the optimization context). Spurious statements are ones the compiler knows has no effect, such as i=i; If that was there instead of the for-loop, then yeah, the for-loop would be optimized away.

    I still think the poster talking about stdout buffers getting clogged had the right idea.
     

Share This Page