Reputation: 43
I am writing a code in C which analyzes the constant factor of time complexity of all sorting techniques. I am including a statistical study of those constants. To do that I had to find the ratio of two positive double numbers. Surprisingly I am getting a negative result. Could anybody help me understand what I am missing here?
I started digging in wiki https://en.wikipedia.org/wiki/C_data_types and this https://www.geeksforgeeks.org/data-types-in-c/, but that does not seem to have the answer I am looking for.
#include <stdio.h>
int main(void) {
// your code goes here
int i=1500;
double j=9265.49;
double result=(double)j/((double)(i*i*i*i));
printf("%lf",result);
return 0;
}
The result is -0.000007 which is clearly wrong.
Upvotes: 0
Views: 67
Reputation: 153338
int overflow
i*i*i*i
is int
math and int
overflow1 which is undefined behavior (UB). @Eugene Sh.
In OP's case, i*i*i*i
--> became -1266441984
or so.
Avoid overflow in the multiplication. Perform the multiplication with wider math.
int main(void) {
int i = 1500;
double j = 9265.49;
// double result=(double)j/((double)(i*i*i*i));
double result = (double) j / ((double) i * i * i * i);
printf("%e", result);
return 0;
}
Output
1.830220e-09
See There are reasons not to use 1000 * 1000 * 1000 for additional insights about code such as i*i*i*i
.
1 When INT_MAX < 5062500000000
as with 32-bit int
.
Upvotes: 3
Reputation: 5952
Integer overflow:
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
int main(int argc, char *argv[]) {
int i = 1500;
int32_t i32 = 1500;
uint32_t u32 = 1500;
printf("i : %lf\n", (double)(i*i*i*i));
printf("i32: %lf\n", (double)(i32*i32*i32*i32));
printf("u32: %lf\n", (double)(u32*u32*u32*u32));
long int li = 1500;
int64_t i64 = 1500;
uint64_t u64 = 1500;
printf("li : %lf\n", (double)(li*li*li*li));
printf("i64: %lf\n", (double)(i64*i64*i64*i64));
printf("u64: %lf\n", (double)(u64*u64*u64*u64));
return(0);
}
Output on my Linux x86_64 with GCC 8:
$ ./dummy
i : -1266441984.000000
i32: -1266441984.000000
u32: 3028525312.000000
li : 5062500000000.000000
i64: 5062500000000.000000
u64: 5062500000000.000000
Upvotes: 1