无浮点型代码出现Floating point exception的原因及解决方法
Hey there, let's figure out why your code is throwing that "Floating point exception" error and get it fixed properly. The error message is a bit misleading—you're not using floating-point variables, but the issue comes from a classic mistake in integer operations.
What's Causing the Error?
1. Division by Zero (Disguised as a Floating Point Exception)
Your loops start with i = 0 and j = 0, and immediately attempt modulo operations with these values:
- When
i = 0,bignum % iis equivalent to dividing by 0 (modulo is just the remainder of division). - Later, when
j = 0,i % jalso tries to divide by 0.
Most systems label integer division by zero as a "Floating point exception"—it's a legacy error classification, not a sign you're using floats incorrectly.
2. Broken & Extremely Inefficient Logic
Even if you fix the division by zero, your code will run practically forever (since you're looping up to 600+ billion) and has flawed prime checking:
- A prime number is only divisible by 1 and itself, but your inner loop checks all values from 0 to
i, which is unnecessary and incorrect. - By looping from 0 upwards, you'll overwrite
resultwith smaller prime factors first, so the final value won't be the largest one you need.
How to Fix It
Step 1: Eliminate Division by Zero
Start your loops at valid values (since 0 can't be a divisor or prime):
- For checking divisors, start at 2 (1 is a divisor but not a prime).
- For prime validation, start checking from 2 and only go up to the square root of the number (this cuts down the number of checks drastically).
Step 2: Optimize for the Largest Prime Factor
Instead of looping from 0 to bignum, use a smarter factorization approach: divide the original number by its smallest factors repeatedly until you're left with the largest prime factor. This is way faster than checking every number up to 600 billion.
Fixed Code Example
Here's a revised, efficient version that works correctly:
#include <stdlib.h> #include <stdio.h> #include <stdint.h> int main (int argc, char ** argv) { uint64_t bignum = 600851475143; uint64_t result = bignum; // Start with the original number // Remove all even factors first while (result % 2 == 0) { result /= 2; } // Check odd numbers up to the square root of the remaining value for (uint64_t i = 3; i * i <= result; i += 2) { // Divide out all instances of this divisor while (result % i == 0) { result /= i; } } // If result is greater than 2, it's the largest prime factor printf("The largest prime factor of the number %lu is %lu.\n", 600851475143, result); return 0; }
Quick Breakdown of the Fixed Code:
- We first strip out all even factors by dividing by 2 repeatedly.
- Next, we check odd numbers starting from 3, stopping at the square root of the remaining number (since any factor larger than that would have a corresponding smaller factor we already checked).
- For each divisor we find, we divide it out completely from the remaining number.
- If
resultis still greater than 2 after this process, it's the largest prime factor (since no smaller factors are left to divide it).
Compilation Tip
You don't need the -lm flag here—your code doesn't use any math library functions. Compile it with:
gcc -Wall -g 3.c -o 3
内容的提问来源于stack exchange,提问作者connoraw

