What is the input range of (x >> 8) before overflow kicks in?

M

Mr. Ken

I am running such segment of codes, but errors kick in after maybe
absolute of x above 10^6.

What is the theoritical bound of x before I get errors?



double x;
int y;

x = ......;

y = ((int)x) >> 8;

Thanks.
 
O

Ondra Holub

Mr. Ken napsal:
I am running such segment of codes, but errors kick in after maybe
absolute of x above 10^6.

What is the theoritical bound of x before I get errors?



double x;
int y;

x = ......;

y = ((int)x) >> 8;

Thanks.

#include <limits>

if (x <= std::numeric_limits<int>::max() && x >=
std::numeric_limits<int>::min())
{
// x typecasted to int will fit into int
}
 
M

Mr. Ken

Ondra Holub said:
Mr. Ken napsal:

#include <limits>

if (x <= std::numeric_limits<int>::max() && x >=
std::numeric_limits<int>::min())
{
// x typecasted to int will fit into int
}

Thank you but it doesn't solve my problem since sometimes x is not shifted.

I am using y = (int)(x/256.0), which is nearly correct.

However I liked the ">>" due to its readability.
 
K

Kai-Uwe Bux

Mr. Ken said:
Thank you but it doesn't solve my problem since sometimes x is not
shifted.

If it does not solve your problem, then you did not explain you problem
correctly: you asked about the range of error-free behavior for the line

y = ( (int)x ) >> 8;

This line has well-define behavior if and only if the double x can be
converted to an int without overflow or underflow. The test suggested by
Ondra Holup ensures exactly that. What you do with the int-casted double
afterwards is immaterial.

I am using y = (int)(x/256.0), which is nearly correct.

However I liked the ">>" due to its readability.

Maybe you should fill us in on the precise requirements. If you tell us the
specs for the transformation x -> y, someone might be able to suggest code
that is more than "nearly" correct.


Best

Kai-Uwe Bux
 
O

Ondra Holub

Mr. Ken napsal:
Thank you but it doesn't solve my problem since sometimes x is not shifted.

I am using y = (int)(x/256.0), which is nearly correct.

However I liked the ">>" due to its readability.

Hi. I am not sure what you exactly need. (int)(x/256.0) is not the same
as ((int)x)/256; Former first divides x with 256 and then typecasts it
to int. Latter variant first typecasts x to int and then divides it
with 256.

So you can still check the result of x / 256.0 whether it fits to int.

BTW: x >> 8 is IMO not more readable than x / 256 and I bet every
compiler is able to change x / 256 to bit shift automatically (of
course when x is integer value).
 
P

peter koch

Kai-Uwe Bux wrote:
[snip]
[...]you asked about the range of error-free behavior for the line
(assuming double x)
y = ( (int)x ) >> 8;

This line has well-define behavior if and only if the double x can be
converted to an int without overflow or underflow.
[snip]

Are you sure? So far as I know shifts of integer types only have well
defined behaviour when the left argument is non-negative.

/Peter
 
K

Kai-Uwe Bux

peter said:
Kai-Uwe Bux wrote:
[snip]
[...]you asked about the range of error-free behavior for the line
(assuming double x)
y = ( (int)x ) >> 8;

This line has well-define behavior if and only if the double x can be
converted to an int without overflow or underflow.
[snip]

Are you sure? So far as I know shifts of integer types only have well
defined behaviour when the left argument is non-negative.

Ah, I should have said "not undefined" instead of "well-defined". You are
right: for negative integers, the resulting value is implementation defined
[5.8/3]. However, I would consider that still error-free behavior.


Best

Kai-Uwe Bux
 
S

Sylvester Hesp

Ondra Holub said:
BTW: x >> 8 is IMO not more readable than x / 256 and I bet every
compiler is able to change x / 256 to bit shift automatically (of
course when x is integer value).

Of course when x is an _unsigned_ integer. -1 / 256 == 0, but on most
implementations, -1 >> 8 == -1 due to the use of the arithmetic shift right
on a signed int (and an implementation using a logical shift left can't even
use that instruction for dividing signed integers ;)). This leads to the
need for extra (perhaps relatively expensive, of course depending on the
platform) checks, therefore a regular divide instruction rather than a shift
can be chosen to "optimize" the expression.

- Sylvester
 
M

Mr. Ken

Kai-Uwe Bux said:
If it does not solve your problem, then you did not explain you problem
correctly: you asked about the range of error-free behavior for the line

y = ( (int)x ) >> 8;

This line has well-define behavior if and only if the double x can be
converted to an int without overflow or underflow. The test suggested by
Ondra Holup ensures exactly that. What you do with the int-casted double
afterwards is immaterial.



Maybe you should fill us in on the precise requirements. If you tell us the
specs for the transformation x -> y, someone might be able to suggest code
that is more than "nearly" correct.


Best

Kai-Uwe Bux

Sorry for my bad communication.
Basically the C++ will be converted to hardware with logic gates. I will use
maybe 35-bits
for integers in 2's complement formats.

In C++ sims, I would define everything in "double" and x may end up be

z = sign * (0.0, 1.0, ...8191.0);
x = z * pow(2.0, 21);

y = ((int)x) >> 8.

y will be scaled down version of x. And ">>" is the usual operator we use in
the company.

I would like to know the exact z when y becomes erronous.
 

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

No members online now.

Forum statistics

Threads
473,754
Messages
2,569,521
Members
44,995
Latest member
PinupduzSap

Latest Threads

Top