I'm trying to understand C++ numerical properties. Thus, I am interested by the underflow phenomenon. Can anyone give me an example of an underflow and how to handle it?
-
1`0U-1`. By putting a UB tag, though, I assume you mean signed underflow. – chris Jul 12 '13 at 08:15
-
@chris (let's assume 32-bit unsigned for the sake of argument) technically, there's no under/overflow there: the result of 0U-1 is 4294967295, not -1. 4294967295 fits in a 32-bit unsigned int and therefore doesn't overflow. By contrast, the result of -2147483648-1 is -2147483649 which doesn't fit on a signed 32-bit int and therefore overflows/underflows. – R. Martinho Fernandes Jul 12 '13 at 08:33
-
@R.MartinhoFernandes, I knew I should have typed out those extra characters, even if I got lazy and just used `INT_MIN`. Either way would probably be less than the note I had to tag on, too. That's kind of depressing. – chris Jul 12 '13 at 08:38
-
1The use of “numerical” makes me think the question is about floating-point underflow, which is not undefined behavior (inasmuch as the compiler chooses to provide IEEE 754 floating-point semantics). – Pascal Cuoq Jul 12 '13 at 09:08
-
@PascalCuoq it is about doubles underflow – WildThing Jul 12 '13 at 09:10
2 Answers
An example of floating-point underflow is:
double d = DBL_MIN / 3.0;
A conforming IEEE 754 implementation should set d
to a “subnormal”, that is, a number that is so close to zero that precision is reduced. You will find plenty of information on Wikipedia.
Some implementations may “Flush to Zero”. The consequence in the example above is to set d
to zero.
An underflow is the result of larger negative exponents not being available to represent the number. It is sometimes possible to avoid them by “normalizing” the computation, which amounts to somehow computing on x1*2N, x2*2N, … instead of x1, x2, … for an N of your choice.
Floating-point underflow is not undefined behavior. You can, if you wish, use “FPU exceptions” to detect it either by polling or by receiving SIGFPE. Note that “FPU exceptions” have nothing in common with C++ exceptions except the name.

- 79,187
- 7
- 161
- 281
-
-
2@WildThing All five basic IEEE 754 operations except sqrt (that is, +, -, *, /) can cause underflow. They cause underflow each time the mathematical result would be between `-DBL_MIN*(1-DBL_EPSILON/4)` and `DBL_MIN*(1-DBL_EPSILON/4)` (give or take a fraction of an ULP). – Pascal Cuoq Jul 12 '13 at 09:30
-
-
1@WildThing For sane implementations of these function, the rule “They cause underflow each time the mathematical result would be between …” applies. The sine of a subnormal is a subnormal, for instance. The nature of floating-point (very probably) means that there are no normal doubles `x` such that `sin(x)` or `cos(x)` is a subnormal, but this is assuming a sane implementation. – Pascal Cuoq Jul 12 '13 at 09:36
-
1FPU exception have nothing in common with C++ exception: but it seems we can connect them on some OS http://stackoverflow.com/questions/2769814/how-do-i-use-try-catch-to-catch-floating-point-errors/10895180#10895180 (I did not try though) – aka.nice Jul 12 '13 at 10:01
-
`sin(DBL_MIN)` underflows, if underflow is determined before rounding. – Eric Postpischil Jul 12 '13 at 10:27
-
2Although `DBL_MIN/2` underflows, this underflow is dismissed (is not flagged and effectively never exists) if default underflow handling is enabled, because the result is exact. In the default mode, exact results never underflow. In contrast, `DBL_MIN/3` or `DBL_MIN/(2./3)` would always raise the underflow flag. – Eric Postpischil Jul 12 '13 at 10:30
-
int main()
{
short int x ;
for(x=0;;x++)
{
printf("%d \n",x);
if(x < 0)
break;
}
}
o/p
---
---
--
32761
32762
32763
32764
32765
32766
32767
-32768
Assuming you are asking the underflow concept in signed no. Here the concept is the signed no is works like a circle once you reached the half of the circle it will go in -ve half of that circle and it will continue and never ends. it start for 0-32767 (+ve) -32768 to -1 (-ve) half.
This is the responsibility of programmer to handle this situation.Compiler won't raise any error if you underflow.
Hope this helps.

- 1,718
- 2
- 13
- 24
-
2"Here the concept is the signed no is works like a circle once you reached the half of the circle it will go in -ve half of that circle and it will continue and never ends." Not really, no. Usually if the result of an operation cannot be represented in the given type (like in your example, the number 32768 on a 16-bit signed integer) the behaviour is undefined. – R. Martinho Fernandes Jul 12 '13 at 08:38
-
-
-
@R. Martinho Fernandes :Thanks for the clarification but how I am getting -ve once it reaches the half of the circle.What standard says about this. Kindly clarify this doubt. – pradipta Jul 12 '13 at 08:59
-
@pradipta the standard says *nothing*. Anything is valid, from getting you a negative value to getting you [an infinite loop](http://stackoverflow.com/questions/7682477/why-does-integer-overflow-on-x86-with-gcc-cause-an-infinite-loop) to [starting a game of NetHack](http://everything2.com/title/%2523pragma). That's what it means for the behaviour to be undefined. – R. Martinho Fernandes Jul 12 '13 at 09:03
-
1@R.MartinhoFernandes, Mysticial's question is the only thing I ever think about when saying it matters :) And I might have taken "says nothing" a bit too literally, but *If during the evaluation of an expression, the result is not mathematically defined or not in the range of representable values for its type, the behavior is undefined.* – chris Jul 12 '13 at 09:07
-
-
1@R.MartinhoFernandes The program in the question does not invoke undefined behavior on most compilation platforms because `x++` is evaluated as `x = (short)((int)x + 1);`. It only invokes implementation-defined behavior in the conversion to short. See the quiz part of http://blog.frama-c.com/index.php?post/2013/07/11/Arithmetic-overflows-in-Fluorine – Pascal Cuoq Jul 12 '13 at 09:26
-
-
@PascalCuoq That may be true for C. C++ does not promote everything to `int`, so that is not relevant here. – R. Martinho Fernandes Jul 12 '13 at 09:31
-
@R. Martinho Fernandes : But My code is in C only.It that an undefined behaviour. – pradipta Jul 12 '13 at 09:34
-
@pradipta The question was originally tagged “C” but it seemed to me the OP meant C++, as per the body of the question. Your C program is defined on compilation platforms where `int` can represent `SHRT_MAX + 1` – Pascal Cuoq Jul 12 '13 at 09:39
-
@PascalCuoq Actually, I went digging for the exact standard text and it's a bit less clear than I thought :/ I don't know what is true anymore. – R. Martinho Fernandes Jul 12 '13 at 09:47