Welcome to the MacNN Forums.

If this is your first visit, be sure to check out the FAQ by clicking the link above. You may have to register before you can post: click the register link above to proceed. To start viewing messages, select the forum that you want to visit from the selection below.

You are here: MacNN Forums > Software - Troubleshooting and Discussion > Developer Center > Why can't my computer divide correctly?

Why can't my computer divide correctly?
Thread Tools
Mac Enthusiast
Join Date: Feb 2000
Location: Storrs,Connecticut, USA
Status: Offline
Reply With Quote
Feb 17, 2001, 06:57 AM
 
I am writing a program where I need some random numbers between zero and a specific number. Easy, right? Well, suppose that I want numbers between 0 and n-1. I thought that I could just do this:

srand(time(NULL));
number = (int)(n*rand()/RAND_MAX);

And this way number would be between 0 and n-1. Well, I noticed that number always came out as 0 so I broke this into parts and looked at the variables in the debugger just to see what was happening. In this case it is really strange:

unsigned long int a,c;
double b;

srand(time(NULL));
a= rand();
c = RAND_MAX;
b = a/c;

A always ends up being a big positive number, c always ends up being 2^31-1 but when I step over the line b=a/c b ALWAYS ends up being 0. There is obviously something wrong here. I'm using a G4, is there some sort of known didvide bug in the processor or something. This is crazy. I can't divide anythine by RAND_MAX I always get 0 as my answer. I whipped out my calculator once and did the division on it. In that instance b should have been .3 something. This isn't some sort of continuous underflow error. I have no idea what is happening? I make a and c ints, unsigned ints, long unsigned ints, I can make b a double, a float, a long double and nothing helps. a/c is always zero. Yes, I do step past b such that a/c is stored to b. It's not like I stop on that line. I have made b a float and after the line b=a/c I put put:

printf("%f ",b);
fflush(stdout);

The output is always 0.000000. This is driving me crazy why can't my computer divide correctly?
     
Senior User
Join Date: Nov 2000
Status: Offline
Reply With Quote
Feb 17, 2001, 11:41 AM
 
This seems to divide correctly:
Code:
int first_result = 0; int end_result = 0; int rand_max = 50; int n = 5; srand(time(NULL)); first_result = n*rand(); end_result = (first_result / rand_max);
..for example. But that's on a G3, so who knows.

Code:
int n = 20; srand(time(NULL)); return (rand()%n);
..should return a result between 0 and n-1.

Hope it helps. If any of that's wrong..I wouldn't doubt it!

[typo(s)]

[This message has been edited by IamBob (edited 02-17-2001).]
     
Dalgo  (op)
Mac Enthusiast
Join Date: Feb 2000
Location: Storrs,Connecticut, USA
Status: Offline
Reply With Quote
Feb 17, 2001, 02:56 PM
 
Thanks I hadn't thought of:

int n = 20;
srand(time(NULL));
return (rand()%n);

I figured out what the problem was but I'm wondering if it is a compiler error. I was diving two ints. In my computer science class I was told that ALL division is done as a long double. In this case it seems that it was only returning the integer division, which was consistently zero. When I typecasted the numerator and denominator as floats it worked out fine. Is this something funky with the compiler or is this just how it always works?
     
Senior User
Join Date: Nov 2000
Status: Offline
Reply With Quote
Feb 17, 2001, 03:52 PM
 
I made up all the number since you didn't give any specifcs so I couldn't really do a full test.

I made a new cocoa project and used:
Code:
#import <Cocoa/Cocoa.h> @interface DivideTest : NSObject { IBOutlet id nstextview; } - (IBAction)divide id)sender; @end #import "DivideTest.h" @implementation DivideTest - (IBAction)divide id)sender { int rand_result = 0; int rand_max = 50; int n = 5; NSString *string = nil; srand(time(NULL)); rand_result = n*rand(); string = [NSString stringWithFormat:@"random: %d", rand_result]; [nstextview insertText: string ]; [nstextview insertText:@"\n"]; string = [NSString stringWithFormat:@"diveded by: %d", rand_max]; [nstextview insertText: string ]; [nstextview insertText:@"\n"]; string = [NSString stringWithFormat:@"equals: %d", (rand_result / rand_max)]; [nstextview insertText: string ]; [nstextview insertText:@"\n"]; } @end
Everything seemed to work. I'm not sure though. I'm still a self-taught novi.
     
Dedicated MacNNer
Join Date: Jun 2000
Location: Dundas, Ontario, Canada
Status: Offline
Reply With Quote
Feb 17, 2001, 04:14 PM
 
I think that I might know what is going on (but I am warning you that I am not sure). I think that what you said about integer division is correct. I do, however, think that this is language (or perhaps compiler) dependant as to how it handles integer division. In the case of objective C (and I assume that C handles this the same way), it appears to truncate the number to force-cast it to int to be inline with the types in the argument. For example, consider the code:
if ((num1/num2) ==1 ){return YES;}

If num1 and num2 are int, this will return true for the quotient of the argument (x) when: 1 =< x < 2

If num1 and num2 are float, this will return true only when the quotient of the argument is EXACTLY 1.

Hope that helps to clear things up. It is all a matter of who does the casting (you or the compiler) and at what point in execution.
Jeff.
Spectral Class
"Shedding Light on Innovation"
     
Dedicated MacNNer
Join Date: Jan 2001
Location: Virginia, US
Status: Offline
Reply With Quote
Feb 17, 2001, 07:11 PM
 
If both operands to / are integers, then integer division is used. If either operand is a float/double, then the operation is promoted to float/double division. This is defined by the C language.

As for getting a random number from 0 to N-1, random() % N is the simplest way to do it. From a theoretical standpoint it's not 100% correct unless N is evenly divisible into RAND_MAX+1, but unless you're doing a hardcore scientific application or something like that it's plenty good enough.

Also, keep in mind that n*random() will often exceed INT_MAX (since that's basically what RAND_MAX is), potentially "wrapping around" to give a negative value. You may want to force the division to happen first, like
(int)(n * (random() / (double)RAND_MAX))


[This message has been edited by lindberg (edited 02-17-2001).]
     
Dalgo  (op)
Mac Enthusiast
Join Date: Feb 2000
Location: Storrs,Connecticut, USA
Status: Offline
Reply With Quote
Feb 18, 2001, 07:55 AM
 
Thanks. I'll have to remember to typecast division like that from now on.
     
   
Thread Tools
Forum Links
Forum Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On
Top
Privacy Policy
All times are GMT -5. The time now is 12:24 PM.
All contents of these forums © 1995-2011 MacNN. All rights reserved.
Branding + Design: www.gesamtbild.com
vBulletin v.3.8.7 © 2000-2011, Jelsoft Enterprises Ltd., Content Relevant URLs by vBSEO 3.3.2