I can't get the correct value of 15136704000 for the third print line and I am not sure what the issue is. It works correctly when compiled via gcc on Linux but Windows keeps spitting out nonsense and I just would like to understand why.
Windows displays it as Which is 2251802112 inches away.

#include <stdio.h>

int main(void)
{
    const int five = 5;
    const int eight = 8;
    const int mi_to_in = 63360;

    int miles_to_moon = 238900;
    int km_to_moon = (float) eight / five * miles_to_moon;
    unsigned long inches_to_moon = (long) miles_to_moon * mi_to_in;

    printf("The moon is %d miles away.\n", miles_to_moon);
    printf("Which is equivalent to %d kilometers away.\n", km_to_moon);
    printf("Which is %lu inches away.\n", inches_to_moon);
}

推荐答案

正如@jamesdlin所 comments 的,表达式(long)miles_to_moon * mi_to_in在Windows上会导致算术溢出,因为long类型在这个系统上只有32位,包括它的64位版本.在这个计算中使用unsigned long long可以解决这个问题,实际上,在某些系统中使用long表示mi_to_in,使用miles_to_moon表示可移植性.

C标准在支持它们的系统上提供了固定长度的整数类型,如<stdin.h>中定义的int32_tint64_t.这些类型可以用于具有适当范围的变量,但为了更好的可移植性和简单性,您应该使用double进行此类计算:

#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;
}

输出:

The moon is 238900 miles away.
Which is equivalent to 384471 kilometers away.
Which is 15136704000 inches away.

然而,请注意,将一个近似数字乘以一个精确数字并不会提高精度,而上述输出中的有效位数可能表明这一点.四舍五入这些数字似乎更可取,但这将产生384500公里,而不是常用的384400公里.

更精确的平均半轴为384399公里,约238855英里,通常换算为238900英里.

四舍五入到指定的有效位数并不简单,C库中也没有标准函数来实现这一点.您可以使用snprintf%.3e生成指数格式的数字,并使用strtod转换回数字,但这既麻烦又低效.

C++相关问答推荐

C中出现分段错误后关闭文件

通过管道将一个子系统的标准输出发送到另一个子系统的标准输出

ESP32在vTaskDelay上崩溃

在编译时参数化类型定义

整型文字后缀在左移中的用途

在C语言中,指针指向一个数组

试图创建一个基本的Word克隆,但遇到了障碍

为什么这个分配做得不好呢?

Valgrind正在使用一个Fexecve电话报告不可能发生的事情

有没有办法减少C语言中线程的堆大小?

与外部SPI闪存通信时是否应禁用中断?

OMP并行嵌套循环

在NASM中链接Linux共享库时出错-';将R_ X86_64_;foo';

WSASocket在哪里定义?

使用 GCC 将一个函数中初始化的 struct 体实例通过指针传递到 C 中的另一个函数会产生不同的结果

全局变量 y0 与 mathlib 冲突,无法编译最小的 C 代码

在 C/C++ 中原子按位与字节的最佳方法?

这种 C 函数风格的名称是什么?

米斯拉映射到 klocwork 违规行为

在 C 语言中,为什么 10/3 应该给出 3.333 却给出 3.000? (保存 10 和 3 的变量被声明为double)