How can underflow, overflow be tested for using C++?

O

Oplec

Hello,

How can underflow and overflow of the basic arithmetic types be tested
for using standard C++?

For instance, if two long doubles are multiplied together, test whether
or not the result is too large to fit in a long double?

Thank you for your time, Oplec.
 
S

Samuele Armondi

Oplec said:
Hello,

How can underflow and overflow of the basic arithmetic types be tested
for using standard C++?

For instance, if two long doubles are multiplied together, test whether
or not the result is too large to fit in a long double?

Thank you for your time, Oplec.
Use the numeric_limits<> template defined in the <limits> header. Here is an
example:

#include <limits>
#include <iostream>

int main()
{
short a = 17000;
short b = 3;
//short c = a * b; on my machine this would produce an overflow
short c;
if ((a * b) > std::numeric_limits<short>::max() )
std::cout << "overflow" << std::endl;
else
{
std::cout << "max short value = " << std::numeric_limits<short>::max() <<
std::endl;
c = a * b;
std::cout << c << std::endl;
}
return 0;
}

hth,
S. Armondi
 
O

Oplec

Samuele said:
Use the numeric_limits<> template defined in the <limits> header. Here is an
example:

#include <limits>
#include <iostream>

int main()
{
short a = 17000;
short b = 3;
//short c = a * b; on my machine this would produce an overflow
short c;
if ((a * b) > std::numeric_limits<short>::max() )
std::cout << "overflow" << std::endl;
else
{
std::cout << "max short value = " << std::numeric_limits<short>::max() <<
std::endl;
c = a * b;
std::cout << c << std::endl;
}
return 0;
}

hth,
S. Armondi

It appears from your code example that it is possible to test for
overflow, but only before storing the result for use. Is that the case?
Wouldn't a*b result in a temporary of the same type as the larger of a
or b, and wouldn't that be the same as using c = a*b; in the condition
statement?

I apperciate your help, and just want to make sure I understand it.

Thank you for your time, Oplec.
 
H

heinz baer

std::numeric_limits<short>::max()

Yuck. This construct seems like a result of a contest to see how many
special characters can be forced into one statement; I count 6 not
including duplicates. At some point C++ should take into consideration
the amount of time it takes a human mind to read the syntax. The C
method SHRT_MAX takes no time at all.
std::numeric_limits<short>::max() while perfectly logical looks like
some kind of machine code. Wonder what would have been wrong with just
#define SHRT_MAX as this gobbly gook to keep source code readable.
 
J

Jerry Coffin

[ ... ]
std::numeric_limits<short>::max() while perfectly logical looks like
some kind of machine code. Wonder what would have been wrong with just
#define SHRT_MAX as this gobbly gook to keep source code readable.

There's still <climits> with which you can use SHRT_MAX.

Despite its length and difficulty of typing (both of which I agree with
you about) the templated versions have some advantages at times. Just
for example, consider a situation where you're writing a templated
class, and you want to get the numeric limit of whatever type you've
been passed as a template parameter:

template <class T>
class X {

std::numeric_limits<T>::max()

still works perfectly well, even though you have no idea whether you
should be using SHRT_MAX, LONG_MAX, one of the U*_MAX, or what...
 
D

Davlet Panech

Samuele Armondi said:
Use the numeric_limits<> template defined in the <limits> header. Here is an
example:

#include <limits>
#include <iostream>

int main()
{
short a = 17000;
short b = 3;
//short c = a * b; on my machine this would produce an overflow
short c;
if ((a * b) > std::numeric_limits<short>::max() )
std::cout << "overflow" << std::endl;

I don't entirely understand why this works. I presume (a*b) gets promoted to
a wider type. Why is that?

Anyhow, the following won't work:

// (assuming 32-bit arch)
long a = 0x7FFFFFFF;
long b = 3;
// the following is false
if ((a * b) > std::numeric_limits<long>::max() )

D.
 
R

Rob Williscroft

Oplec wrote in @twister01.bloor.is.net.cable.rogers.com:
Hello,

How can underflow and overflow of the basic arithmetic types be tested
for using standard C++?

For instance, if two long doubles are multiplied together, test whether
or not the result is too large to fit in a long double?

Thank you for your time, Oplec.

For multiplication of ints do:

#include <iostream>
#include <ostream>
#include <iomanip>
#include <limits>
#include <cmath>

bool multiply( int &c, int a, int b)
{
c = a * b;
double d = (
std::log(std::abs(double(a)))
+
std::log(std::abs(double(b)))
)
/
log(2)
;
return d < std::numeric_limits< int >::digits;
}


int main()
{
using namespace std;
int const M = -numeric_limits<int>::max();
int r;

cout << boolalpha << hex;

cout << multiply( r, M / 4, M / 4 ) << ": " << r << endl;
cout << multiply( r, 10, 4 ) << ": " << r << endl;
cout << multiply( r, (M/8) + 1, 2 ) << ": " << r << endl;
cout << multiply( r, (M/2) + 1, 4 ) << ": " << r << endl;
}

You can do that without the double-precision math using bit scaning,
as int( std::log(1 << N)/std::log(2)) == N.

For floating point you may want to take the log's base 10 (std::log10())
and check the results is less than
std::numeric_limits:< FloatType >::max_exponent10 for no-overflow and
greater than std::numeric_limits:< FloatType >::min_exponent10 for
no-underflow.

HTH

Rob.
 
S

Samuele Armondi

Oplec said:
It appears from your code example that it is possible to test for
overflow, but only before storing the result for use. Is that the case?
Wouldn't a*b result in a temporary of the same type as the larger of a
or b, and wouldn't that be the same as using c = a*b; in the condition
statement?

I apperciate your help, and just want to make sure I understand it.

Thank you for your time, Oplec.

To be honest, I don't really know... I assume the compiler would allocate a
type big enough to hold the result. I guess only testing would answer your
question!!
HTH,
S. Armondi
 
Joined
May 27, 2010
Messages
2
Reaction score
0
Samuele Armondi said:
"Oplec" <[email protected]> wrote in message
news:[email protected]...
> Samuele Armondi wrote:
>
> > Use the numeric_limits<> template defined in the <limits> header. Here

is an
> > example:
> >
> > #include <limits>
> > #include <iostream>
> >
> > int main()
> > {
> > short a = 17000;
> > short b = 3;
> > //short c = a * b; on my machine this would produce an overflow
> > short c;
> > if ((a * b) > std::numeric_limits<short>::max() )
> > std::cout << "overflow" << std::endl;
> > else
> > {
> > std::cout << "max short value = " << std::numeric_limits<short>::max()

<<
> > std::endl;
> > c = a * b;
> > std::cout << c << std::endl;
> > }
> > return 0;
> > }
> >
> > hth,
> > S. Armondi

>
> It appears from your code example that it is possible to test for
> overflow, but only before storing the result for use. Is that the case?
> Wouldn't a*b result in a temporary of the same type as the larger of a
> or b, and wouldn't that be the same as using c = a*b; in the condition
> statement?
>
> I apperciate your help, and just want to make sure I understand it.
>
> Thank you for your time, Oplec.
>


To be honest, I don't really know... I assume the compiler would allocate a
type big enough to hold the result. I guess only testing would answer your
question!!
HTH,
S. Armondi

I'm not convinced std::numeric_limits<short>::max() is difficult to read. Took me less than a second, as it should anyone who works in c++ . Typing it is a little annoying I guess.

back to this problem, there are overflow registers that can be accessed, but this will be pretty platform dependent. I am looking into how to do this on OS X
 
Joined
May 27, 2010
Messages
2
Reaction score
0
even easier than I thought.

Code:
#include <iostream>
#include <math.h>

using namespace std;

int main (int argc, char * const argv[]) {

	double val = 1000;
	
	while(!isinf(val)) {
		
		cout << "val is " << val << endl;
		val = val * 10;
	}
	
	cout << "val is " << val << endl;
	string line;
	getline(cin, line);
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,057
Latest member
KetoBeezACVGummies

Latest Threads

Top