判断1/n是否为无限小数:原浮点算法失效原因及解决方案咨询
Let’s break down your problem step by step, with practical explanations and fixes:
Why (1.0/3)*3 == 1 in Visual Studio
The issue comes down to binary floating-point precision limits. When you calculate 1.0/3, the result can’t be represented exactly as a double—it’s stored as an approximate value. However, double has ~15-17 decimal digits of precision, and when you multiply that approximation by 3, the tiny error from the division gets rounded back to exactly 1.0 within the double’s precision bounds.
This isn’t a compiler bug—it’s a fundamental trait of how binary floating-point numbers work. The approximation just happens to land back on the exact value of 1 after multiplication, tricking your equality check.
Can You Fix the Floating-Point Algorithm?
Short answer: No, not reliably. The floating-point approach is inherently flawed for this problem. For larger values of n, you’ll run into more edge cases: some finite decimals might not be stored exactly in double (leading to false negatives), while some infinite decimals might round back to exact values when multiplied by n (leading to false positives). There’s no way to account for all these inconsistencies with floating-point arithmetic here.
Is the Prime Factorization Method Harder to Implement?
Absolutely not—this method is mathematically correct and surprisingly straightforward to code. The rule is simple: a fraction 1/n has a finite decimal expansion if and only if all prime factors of n are 2 and/or 5 (or n = 1). Here’s a clean C++ implementation:
#include <iostream> #include <cstdlib> // For abs() int main() { int n; std::cin >> n; if (n == 0) { std::cout << "Please enter a non-zero integer." << std::endl; return 1; } // Negative signs don't affect decimal expansion, so we use absolute value n = std::abs(n); // Remove all factors of 2 while (n % 2 == 0) { n /= 2; } // Remove all factors of 5 while (n % 5 == 0) { n /= 5; } if (n == 1) { std::cout << "fixed number of digits after decimal point" << std::endl; } else { std::cout << "infinite number of digits after decimal point" << std::endl; } return 0; }
How This Works:
- We take the absolute value of
nbecause negative numbers don’t change whether the decimal is finite or infinite. - We repeatedly divide
nby 2 until it’s no longer divisible by 2. - We do the same for 5.
- If the remaining
nis 1, all prime factors were 2 and/or 5—so we have a finite decimal. Otherwise, there are other prime factors, leading to an infinite repeating decimal.
This method uses exact integer arithmetic, so there’s no risk of precision errors. It’s also more efficient than the floating-point approach in most cases.
内容的提问来源于stack exchange,提问作者Kotaka Danski

