Floating Point Exception in C (SIGFPE): Root Causes & Fixes
A floating point exception (SIGFPE) can report an arithmetic fault, including integer division or remainder by zero and an unrepresentable signed quotient such as INT_MIN / -1. These integer operations have undefined behavior in C: a signal is possible, not guaranteed. On Linux x86/x86-64, SIGFPE is signal 8; shells such as Bash commonly report status 136 (128 + 8). Other platforms and execution tools may report failures differently.
Quick Fix Summary
Always validate divisors before performing division or modulo operations (if (divisor == 0) { ... }). For signed integers, also guard against INT_MIN / -1.

Signal & Exit Code Reference
The numbers below are Linux x86/x86-64 examples using the Bash convention 128 + signal number, not portable C exit codes. SIGSEGV is included for comparison; this article concerns SIGFPE. Undefined behavior does not guarantee a signal or a core dump.
| Signal Name | Signal # | Shell Exit Code (128 + N) | Trigger Condition & Meaning |
|---|---|---|---|
| SIGFPE | 8 | 136 | Arithmetic-fault signal. On Linux x86/x86-64, a hardware integer divide error commonly produces SIGFPE; enabled floating-point traps can also produce it. |
| SIGSEGV | 11 | 139 | Memory-access signal, shown for comparison. Invalid memory accesses may cause SIGSEGV, but undefined behavior in C does not guarantee it. |
Why This Error Happens
Integer Division Can Raise SIGFPE
On Linux x86/x86-64, an executed hardware integer divide instruction with a zero divisor or an unrepresentable quotient raises a divide-error exception. The kernel normally delivers SIGFPE. In C, these operations have undefined behavior: optimization, architecture, signal handlers, and execution environments can change the result. Do not use a crash or its absence to decide whether code is safe.
Floating-Point Results Depend on the Environment
On typical IEEE 754 implementations with floating-point traps disabled, a nonzero finite value divided by 0.0 produces an infinity, while 0.0 / 0.0 produces NaN. Enabled traps can instead raise SIGFPE. The GNU feenableexcept function is a nonstandard extension, not a portable C requirement. Check the implementation and floating-point environment rather than assuming every division by zero behaves alike.
Guard an Unrepresentable Signed Quotient
On two's-complement implementations, INT_MIN / -1 cannot be represented as an int; INT_MIN % -1 is also undefined when the quotient is unrepresentable. On a typical 32-bit int, INT_MIN is -2147483648 and INT_MAX is 2147483647. Guard this pair before division or remainder, as well as guarding a zero divisor. Promoting to another type is only safe when that type can actually represent the result.
Top Root Causes & Specific Code Fixes
1. Integer Division or Modulo by Zero
Computing a / b or a % b when b evaluates to 0 (e.g. uninitialized input, empty array count, or loop counter reaching zero).
int count = 0;
int total = 100;
int average = total / count; // Undefined behavior; may raise SIGFPEint count = 0;
int total = 100;
int average = (count != 0) ? (total / count) : 0; // Safe check2. Signed Integer Overflow: INT_MIN / -1
On two's-complement implementations, INT_MIN / -1 has an unrepresentable signed quotient. This is undefined behavior in C and may raise SIGFPE on Linux x86/x86-64.
#include <limits.h>
int a = INT_MIN;
int b = -1;
int c = a / b; // Undefined behavior; may raise SIGFPE#include <limits.h>
int a = INT_MIN;
int b = -1;
if (b == 0 || (a == INT_MIN && b == -1)) {
return -1; // Reject invalid or unrepresentable division
}
int c = a / b;3. Unchecked Dynamic Modulo Operations
A zero divisor in val % size is undefined behavior. A negative size is not itself an arithmetic fault, but rejecting nonpositive capacities prevents invalid bucket or array indexing.
int capacity = 0;
int bucket = key % capacity; // Undefined behavior; may raise SIGFPEint capacity = 0;
if (capacity <= 0) {
return -1;
}
int bucket = key % capacity;Complete Broken and Corrected Programs
Compare the source before running it. The broken program is intentionally incorrect; its behavior can depend on the compiler and platform.
Read the broken program
#include <stdio.h>
int main(void) {
printf("=== Demonstrating Floating Point Exception ===\n");
int numerator = 100;
int denominator = 0; // Invalid divisor
printf("Attempting integer division: %d / %d...\n", numerator, denominator);
// Undefined behavior: may raise SIGFPE on Linux x86/x86-64
int result = numerator / denominator;
printf("Result: %d\n", result);
return 0;
}Open broken program in compilerRead the corrected program
#include <stdio.h>
#include <limits.h>
int safe_divide(int a, int b, int *out_result) {
if (b == 0) {
return -1; // Error: division by zero
}
// Protect against INT_MIN / -1 signed overflow
if (a == INT_MIN && b == -1) {
return -2; // Error: signed integer overflow
}
*out_result = a / b;
return 0; // Success
}
int main(void) {
printf("=== Safe Integer Division Demo ===\n");
int test_cases[][2] = {
{100, 5},
{100, 0},
{INT_MIN, -1},
{42, 7}
};
int num_tests = sizeof(test_cases) / sizeof(test_cases[0]);
for (int i = 0; i < num_tests; i++) {
int a = test_cases[i][0];
int b = test_cases[i][1];
int result = 0;
int status = safe_divide(a, b, &result);
if (status == 0) {
printf("[OK] %d / %d = %d\n", a, b, result);
} else if (status == -1) {
printf("[GUARDED] Division by zero rejected for %d / %d\n", a, b);
} else if (status == -2) {
printf("[GUARDED] INT_MIN / -1 overflow rejected for %d / %d\n", a, b);
}
}
printf("All divisions validated safely without SIGFPE crashes.\n");
return 0;
}Open corrected program in compilerExpected output from the corrected program
Reference output, not a live execution result. This example assumes a 32-bit int; the displayed INT_MIN value can differ on other implementations.
=== Safe Integer Division Demo ===
[OK] 100 / 5 = 20
[GUARDED] Division by zero rejected for 100 / 0
[GUARDED] INT_MIN / -1 overflow rejected for -2147483648 / -1
[OK] 42 / 7 = 6
All divisions validated safely without SIGFPE crashes.Debugging Techniques and Commands
gcc -g main.c -o app && gdb -batch -ex "run" -ex "bt" ./app
Runs the program in GDB and prints the exact source file and line number that triggered the SIGFPE arithmetic trap.
gcc -Wall -Wextra -Wdiv-by-zero main.c
GCC detects literal division by zero at compile time and emits warnings before code is ever executed.
gcc -fsanitize=undefined -g main.c -o app && ./app
Instruments compiled binary to log detailed runtime diagnostics for integer division by zero and signed integer overflows.
Frequently Asked Questions
Why is it called a floating-point exception when I only divided integers?
SIGFPE covers arithmetic exceptions, not only floating-point operations. For example, Linux on x86/x86-64 can deliver it for a hardware integer divide error. Signal numbers and exact behavior depend on the platform.
Does floating-point division (float/double) raise SIGFPE in C?
It depends on the implementation and floating-point environment. Typical IEEE 754 implementations produce infinity or NaN with traps disabled; enabled traps may raise SIGFPE. GNU feenableexcept is nonstandard.
Can I catch SIGFPE with signal() or sigaction() in C?
A handler can be installed, but returning normally after a computational exception is not a portable recovery technique and may repeatedly fault or have undefined behavior. Prevent invalid arithmetic before executing it; do not rely on a handler or siglongjmp to make undefined C arithmetic safe.