 |
 |
Why can't my computer divide correctly?
|
 |
|
 |
|
Mac Enthusiast
Join Date: Feb 2000
Location: Storrs,Connecticut, USA
Status:
Offline
|
|
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
|
|
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).]
|
|
|
| |
|
|
|
 |
|
 |
|
Mac Enthusiast
Join Date: Feb 2000
Location: Storrs,Connecticut, USA
Status:
Offline
|
|
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
|
|
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
|
|
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.
|
|
|
| |
|
|
|
 |
|
 |
|
Dedicated MacNNer
Join Date: Jan 2001
Location: Virginia, US
Status:
Offline
|
|
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).]
|
|
|
| |
|
|
|
 |
|
 |
|
Mac Enthusiast
Join Date: Feb 2000
Location: Storrs,Connecticut, USA
Status:
Offline
|
|
Thanks. I'll have to remember to typecast division like that from now on.
|
|
|
| |
|
|
|
 |
 |
|
 |
|
|
|
|
|

|
|
 |
Forum Rules
|
 |
 |
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
|
HTML code is Off
|
|
|
|
|
|
 |
 |
 |
 |
|
 |
|