EUnderflow
Delphi Programming Language
Severity: MinorWhat Does This Error Mean?
EUnderflow is a floating-point exception raised when a calculation produces a result that is too small (too close to zero) to be represented normally by the float type. Unlike overflow (result too big), underflow means the result is a tiny fraction — so tiny the hardware cannot store it precisely. EUnderflow is a sub-class of EMathError and is much rarer than overflow in typical applications.
Affected Models
- All Delphi versions
- RAD Studio
- Scientific and engineering applications
Common Causes
- Dividing a very small floating-point number by a very large one, producing a result smaller than the minimum representable value
- Multiplying two very small floating-point numbers together — each small value multiplied gives an even smaller result
- Exponential decay calculations where Exp(-x) with a very large x produces a result indistinguishable from zero
- Iterative algorithms that converge to zero — each step multiplies by a small factor until the value underflows
- Receiving extremely small values from scientific data (physics simulations, signal processing) that fall below the float minimum
How to Fix It
-
Understand whether underflow actually matters for your application. A result that underflows to zero may be perfectly acceptable — a number so small it is effectively zero is often harmless.
In most business and financial applications, numbers never get small enough to underflow. This error is mainly a concern in scientific computing.
-
Mask EUnderflow if you want the FPU to silently substitute zero for underflowed values rather than raising an exception. Use SetExceptionMask from the Math unit.
Example: var Mask: TFPUExceptionMask; Mask := GetExceptionMask; Include(Mask, exUnderflow); SetExceptionMask(Mask);
-
For algorithms prone to underflow, work in logarithmic space. Instead of multiplying many small probabilities together (which quickly underflows), sum their logarithms instead.
Example in probability: instead of P = p1 * p2 * p3, use LogP = Ln(p1) + Ln(p2) + Ln(p3). Convert back at the end with Exp(LogP).
-
Scale your data to keep values in a more comfortable range for the float type. If you are working with values near 10^-300, multiply everything by 10^200, do the calculation, then divide at the end.
Careful scaling is a standard technique in numerical analysis to avoid both overflow and underflow.
-
Use Extended (80-bit) precision instead of Double or Single. Extended has a much smaller minimum value (about 3.4 × 10^-4932 compared to Double's 2.2 × 10^-308), giving more headroom before underflow.
Declare as: var SmallValue: Extended; — this is the largest and most precise native float type in Delphi on x86 platforms.
When to Call a Professional
EUnderflow is typically a code design issue in scientific or numeric computing. For most business applications it never occurs. If you are building engineering or physics software that regularly hits underflow, consider using alternative numeric representations like logarithms.
Frequently Asked Questions
What is the difference between underflow and 'result is zero'?
A regular zero is an exact result — the calculation genuinely produced zero. Underflow means the result was not zero, but it was so close to zero that the float type cannot distinguish it from zero. In most practical cases they behave the same — the result becomes zero and your program continues. The difference matters in precision-critical scientific software where losing that tiny value could accumulate into a significant error.
How common is EUnderflow in typical Delphi business applications?
Very rare. Most business logic deals with currencies, counts, and percentages — values that stay well within the comfortable middle range of floating-point representation. EUnderflow is almost exclusively seen in scientific simulations, statistical models, signal processing, and machine learning implementations. If you see EUnderflow in a business application, something unusual is happening with your data — check for corrupted input values.
Is denormalised floating-point related to EUnderflow?
Yes. When a float underflows, the CPU first tries to represent it as a 'denormalised' (or 'subnormal') number — a special format that allows very tiny values at the cost of precision. If even denormalised representation is not enough, the value flushes to zero. EUnderflow can be raised at either stage depending on FPU settings. Denormalised numbers also run slower on some CPUs, which can cause mysterious performance issues in tight numerical loops.