从PTA阶乘和题目出发,聊聊C语言里long long int和double的选用边界(附测试用例)

张开发
2026/4/18 3:16:30 15 分钟阅读

分享文章

从PTA阶乘和题目出发,聊聊C语言里long long int和double的选用边界(附测试用例)
从PTA阶乘和题目出发聊聊C语言里long long int和double的选用边界附测试用例在编程竞赛和算法练习中阶乘计算是一个看似简单却暗藏玄机的问题。许多初学者在PTA、LeetCode等平台遇到阶乘相关题目时常常因为数据类型选择不当而遭遇WAWrong Answer。本文将从一道经典的PTA阶乘序列求和题目切入深入探讨C语言中long long int和double这两种数据类型在数值计算中的边界问题。1. 阶乘增长的恐怖速度与数据类型选择阶乘函数n!的增长速度远超指数函数这种爆炸式增长特性使得即使是中等大小的n值也会产生惊人的大数。让我们先看几个具体的例子5! 12010! 3,628,80015! 1,307,674,368,00020! ≈ 2.4×10¹⁸这种快速增长意味着我们必须谨慎选择存储阶乘值的数据类型。在C语言中常见的选择有int通常32位范围约±2.1×10⁹long long int通常64位范围约±9.2×10¹⁸double64位浮点数可表示约±1.8×10³⁰⁸但有精度损失注意long类型在32位和64位系统上表现不同在编程竞赛中建议明确使用long long保证一致性。2. long long int的精确边界测试long long int是C语言中常用的有符号64位整数类型其理论最大值为2⁶³-1≈9.2×10¹⁸。让我们通过实际代码测试它能精确存储的最大阶乘值#include stdio.h #include limits.h void test_long_long_limit() { long long fact 1; int n 1; while(fact LLONG_MAX / n) { fact * n; printf(%2d! %lld\n, n, fact); n; } printf(\nOverflow occurs at %d! (calculated %lld, actual %lld)\n, n, fact * n, fact * n); } int main() { test_long_long_limit(); return 0; }运行结果通常会显示1! 1 2! 2 3! 6 ... 20! 2432902008176640000在大多数系统上long long int可以精确存储到20!而21!就会导致溢出。这是因为20! ≈ 2.43×10¹⁸ 9.2×10¹⁸ (LLONG_MAX)21! ≈ 5.1×10¹⁹ 9.2×10¹⁸3. double类型的精度与取舍当n超过20时我们必须转向浮点数类型如double。虽然double可以表示更大的数值范围但需要注意两个关键问题精度损失浮点数采用科学计数法存储有效数字有限约15-17位十进制整数表示使用%.0f输出时会进行四舍五入让我们通过代码比较long long和double的差异#include stdio.h void compare_factorials() { long long ll_fact 1; double d_fact 1.0; for(int i 1; i 30; i) { ll_fact * i; d_fact * i; printf(%2d! | long long: %-20lld | double: %-20.0f\n, i, ll_fact, d_fact); } } int main() { compare_factorials(); return 0; }观察输出可以发现大约从21!开始两种类型的计算结果开始出现差异。虽然double能表示更大的数值但对于大整数其精度会逐渐降低。4. 实战建议与测试用例基于以上分析我们得出以下实用建议n ≤ 20优先使用long long int保证精确计算n 20使用double但要注意结果可能有精度损失使用%.0f输出时会四舍五入不适合需要精确值的场景下面提供一组测试用例供验证n正确结果 (long long)double结果 (%.0f)是否匹配5153153是1040379134037913是1514016026363131401602636313是2025613274941118203132561327494111820288否25-7034535277573963776-对于PTA原题中输入不超过12的要求long long int完全足够。但在实际编程中理解这些边界条件对于避免隐蔽的错误至关重要。

更多文章