As commented by @jamesdlin, the expression (long)miles_to_moon * mi_to_in
causes an arithmetic overflow on Windows because the type long
only has 32 bits on this system, including on its 64-bit version. Using unsigned long long
for this computation would solve the problem, and you should actually use long
for mi_to_in
and miles_to_moon
for portability to some systems.
The C Standard provides fixed length integer types such as int32_t
and int64_t
defined in <stdin.h>
on systems that support them. These types could be used for these variables with the proper range, but for better portability and simplicity, you should use double
for such computations:
#include <stdio.h>
int main() {
double mi_to_in = 63360; /* exact figure */
double mi_to_km = 1.60934; /* exact figure */
double miles_to_moon = 238900; /* average distance approximation */
double km_to_moon = miles_to_moon * mi_to_km;
double inches_to_moon = miles_to_moon * mi_to_in;
printf("The moon is %.0f miles away.\n", miles_to_moon);
printf("Which is equivalent to %.0f kilometers away.\n", km_to_moon);
printf("Which is %.0f inches away.\n", inches_to_moon);
return 0;
}
Output:
The moon is 238900 miles away.
Which is equivalent to 384471 kilometers away.
Which is 15136704000 inches away.
Note however that multiplying an approximate figure by an exact one does not increase the precision, which the number of significant digits in the above output might suggest. Rounding these figures seems preferable, yet this would produce 384500 km, which is not the commonly used figure 384400 km.
A more precise average semi-axis is 384399 km, approximately 238855 miles, commonly converted to 238900 mi.
Rounding to a specified number of significant digits is not simple and there is no standard function in the C library to do it. You can use snprintf
with %.3e
to produce the digits in exponential format, and convert back using strtod
, but is cumbersome and inefficient.