Detect overflow and carry when working with 16b values [duplicate] - c

This question already has answers here:
Detecting signed overflow in C/C++
(13 answers)
Closed 8 years ago.
I'm working with signed 16 bit wide variables.
When adding, subtracting etc, can i detect the carry and overflow the following way:
I store the result in a 32bit wide variable, and then check the 17th bit (bits from 0-16 represent the value, and if there's carry or overflow the 17h bit should be 1 - overflow)?
If it's one then it's an overflow/carry, if it's zero - it isn't.
Can carry happen without overflow, or vice versa, when working with 16b values?
I searched StackOverflow, but i was unable to find a clear answer to my question.

upd:
One can use approach, when operands are testing against the limits (declared in the limits.h) when doing the operation. E.g. look at this "safe" addition function:
int safe_add(int x, int y)
{
if(y < 0)
return save_sub(x, -y);
if(x > (INT_MAX - y))
{
printf("overflow\n");
return INT_MAX;
}
return x + y;
}
int save_sub(int x, int y)
{
if(y < 0)
return save_add(x, -y);
if(x > (INT_MIN + y))
{
printf("underflow\n");
return INT_MIN;
}
return x - y;
}
Note: these methods have at least one bug: they may fail if invoked on the largest negative integer, INT_MIN.

Related

Converting float negative values to integer value in c launguage [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 3 years ago.
Improve this question
I want to convert float negative values to unsigned int values. Is it possible?
For example:
float x = -10000.0;
int y;
y = x;
When we assign x value to y, can the negative value be stored in an integer?
If not, how can we store the negative values into integer variables?
can the negative (float f) value be stored in an integer?
Yes, with limitations.
With a signed integer type like int16_t i, i = f is well defined for
-32768.999... to 32767.999...
With an unsigned integer type like unt16_t u, u = f is well defined for
-0.999... to 65535.999...
The result is a truncated value (fraction thrown away). All other float values result in undefined behavior.
If not, how can we store the negative values into integer variables?
Best to use wide signed integer types and test for range limitations.
In any case, the fraction of the float is lost. A -0.5f can be stored in an unsigned, yet the value becomes 0u.
The below performs some simply tests to insure y is in range.
#include <limits.h>
float x = ...;
int y = 0;
if (x >= INT_MAX + 1u) puts("Too pos");
else if (x <= INT_MIN - 1.0) puts("Too neg");
else y = (int) x;
Note the tests above are illustrative as they lack high portability.
Example: INT_MIN - 1.0 in inexact in select situations.
To cope, with common 2's complement int, the below is better reformed. As 2's complement, INT_MIN is a power of 2 (negated) and usually in the range of float, thus making for an exact subtraction near the negative threshold. `
// if (x <= INT_MIN - 1.0)
if (x - INT_MIN <= - 1.0f)
Another alternative is to explore a union. Leave that for others to explain its possibilities and limitations.
union {
float f;
unsigned u;
} x;
float x = 10000.0;
int a;
a = (int)(x+0.5);

Comparing Floating Point Numbers [duplicate]

This question already has answers here:
What is the most effective way for float and double comparison?
(34 answers)
Closed 6 years ago.
Please before you think that I'm asking the same N% Question read it first and please pay Attention to it.
I'm working on a project where I have more functions which returns double and it may be possible that some of them are the same which is a good thing in my project and if is true then I need a double comparison to see if are equal.
I know that doing an equality comparison if( x == y ) is not a smart thing and we don't need to speak why, but we can check for < or > which is the part of this Question.
Does the language (standard) guarantee this, that the comparison < and > are 100%?
If yes then, the following program can be used:
#include <stdio.h>
int main(void){
double x = 3.14;
double y = 3.14;
if( x < y || x > y){
/* Are not Equal */
}else{
/* Are Equal, foo() will be called here\n" */
foo(x, y);
}
}
Does foo(x, y); get executed? BecauseX and Y should be equal here.
EDIT:
This question doesn't seek a way to compare two double, it is only the fact that should I use, or should I don't use < > instead of ==
I know that doing an equality comparison if( x == y ) is not a smart thing
This is simply not true. It may be the right thing to do or the wrong thing to do, depending on the particular problem.
if (x < y || x > y)
This has guaranteed exactly the same effect1 as
if (x != y)
and the opposite effect of
if (x == y)
When one is wrong, the other is wrong too. When one is right, the other is right as well. Writing an equality condition with < and > symbols instead of == or != doesn't suddenly make it smarter.
[1] Except maybe when one of the operands is a NaN.
some of them are the same ... and if is true then I need a double comparison to see if are equal.
OP is questioning two different ways for testing FP equality and wondering if they are the functionally alike.
Aside from maybe NaN, which is not well defined by C, (but well defined by IEEE 754), both comparisons are alike yet fail conically equivalence testing.
Consider this double code:
if (a==b) {
double ai = 1.0/a;
double bi = 1.0/b;
printf("%d\n", ai == bi);
} else {
printf("%d\n", 1);
}
Is the result always "1"? Below is an exception (mouse over to see)
Consider a=0.0; b=-0.0. Both are equal to each other, but their inverses typically are not the same. One being positive infinity, the other: negative infinity.
The question comes down to how equal do you need? Are NaN important? Using memcmp(&a, &b, sizeof a) is certainly a strong test and maybe too strong for on select systems FP numbers can have the same non-zero value, yet different encodings. If these differences are important, or maybe just the exceptional case above, is for OP to decide.
For testing if 2 different codes/functions were producing the same binary64 result, consider rating their Unit-in-the-Last-Place difference. Something like the following: compare unsigned long long ULP_diff() against 0, 1 or 2. depending on your error tolerance.
// not highly portable
#include <assert.h>
unsigned long long ULP(double x) {
union {
double d;
unsigned long long ull;
} u;
assert(sizeof(double) == sizeof(unsigned long long));
u.d = x;
if (u.ull & 0x8000000000000000) {
u.ull ^= 0x8000000000000000;
return 0x8000000000000000 - u.ull;
}
return u.ull + 0x8000000000000000;
}
unsigned long long ULP_diff(double x, double y) {
unsigned long ullx = ULP(x);
unsigned long ully = ULP(y);
if (x > y) return ullx - ully;
return ully - ullx;
}
If you want fractional number equality, you either have to use an epsilon comparison (ie. check if the numbers are close enough to one another within a specific threshold), or use some fixed-point arithmetic very carefully to avoid rounding errors.
And yes, this same question has been asked more times than necessary:
Most effective way for float and double comparison
Floating point equality and tolerances
You need to do more reading into how comparisons work, and specifically why floating point equality doesn't work. It's not an issue with the equals operator itself, as you appear to think (For arithmetic types [when no special values like NaN are involved], !(x > y || y > x) will always be the same as x == y. In fact, most compilers will optimize x < y || x > y to x != y), but rather because rounding error is a basic part of floating point operation in the first place. x == y does indeed work for floating point types, and you can do it freely. It becomes an issue after you do any arithmetic operation and then want to compare them, because it's unpredictable what the rounding error will do.
So essentially, yes. Compare equality all you want unless you are actually doing anything with the doubles. If you are just using them as an index or something of the like, there shouldn't be a problem, as long as you know you are assigning them the same value. Using boolean identities won't save you from the basic functionality of floating-point numbers.
First of all your conditional is a little off. To check for non equality you want
( x < y || y < x)
not
(x < y || y > x )
which just checks the same thing twice, meaning x < y comes back as false.
Ignoring that small issue:
Yes > and < should be 100% in that it is almost always the same as the ==. The only difference is different behavior with Nan. But it doesn't fix your problem.
Here is a really contrived example.
#include <stdio.h>
void foo(double x, double y){
printf( "OK a:%f, b:%f\n",x,y);
}
void bar(double x, double y){
printf( "BAD a:%f, b:%f\n",x,y);
}
int main(void){
double x = 3.14;
double y = 3.14;
if( x < y || y < x){
/* Are not Equal */
bar(x, y);
}else{
/* Are Equal, foo() will be called here\n" */
foo(x, y);
}
for( int i = 0; i < 1000; i++) {
y = y + 0.1;
}
x = x + 100;
if( x < y || y < x){
bar(x, y);
}else{
/* Are Equal, foo() will be called here\n" */
foo(x, y);
}
}
Here is you output (hint its BAD)
$ ./a.exe
OK a:3.140000, b:3.140000
BAD a:103.140000, b:103.140000
Best practice I know for double equality is to check there closeness within some epsilon,
eps = 0.00000000001
if( abs( x - y ) < eps ) {
printf("EQUAL!");
}
#include <stdio.h>
int main(void){
double x = 3.14;
double y = 3.14;
if( x < y || x > y){
/* Are not Equal */
}else{
/* Are Equal, foo() will be called here\n" */
printf("yes");
}
}
prints yes

Detecting unsigned overflow when accumulating variables [duplicate]

This question already has answers here:
How do I detect unsigned integer overflow?
(31 answers)
Closed 7 years ago.
I have two unsigned 32 bit integers, call them x and y. I want to periodically increment the two uint32's by seemingly random uint32 values. x and y will accumulate and I want them to continue to accumulate until they hit their limit, at which point I want them to start back at 0 + the value they would have had added had they not overflowed.
Assume the code looks like:
//This would be called, say every 5 seconds
void increment_vals(uint32_t *x, uint32_t *y, uint32_t x_inc, uint32_t y_inc)
{
*x += x_inc;
*y += y_inc;
if (x overflowed || y overflowed)
{
*x = x_inc;
*y = y_inc;
}
}
So basically my question is: how do I know when x OR y has overflowed and need to to be reset? Should I just store x and y before incrementing and if the result is less than the original value then it must have overflowed? Is that guaranteed?
Thanks.
You could check for overflow before incrementing:
if(x_inc > (MAXINT - *x)) {
//about to overflow
}
I suggest
uint32_t xx = *x + x_inc;
if (xx < *x)
*x = 0;
else *x = xx;
I found this document quite helpful and descriptive in answering my question, particularly page 172:
"For unsigned integers, if the sum is smaller than either operand,
an overflow has occurred."

Test the subtraction of multiple unsigned int

After a few unsuccessful searches, I still don't know if there's a way to substract two unsigned int (or more) and detect if the result of this substraction is negative (or not).
I've try things like :
if(((int)x - (int)y) < 0)
But I don't think it's the best way.
Realize that what you intend by
unsigned int x;
unsigned int y;
if (x - y < 0)
is mathematically equivalent to:
unsigned int x;
unsigned int y;
if (y > x)
EDIT
There aren't many questions for which I can assert a definitive proof, but I can for this one. It's basic inequality algebra:
x - y < 0
add y to both sides:
x < y, which is the same as y > x.
You can do similarly with more variables, if you need:
x - y - z < 0 == x < y + z, or y + z > x
see chux's comment to his own answer, though, for a valid warning about integer overflow when dealing with multiple values.
Simply compare.
unsigned x, y, diff;
diff = x - y;
if (x < y) {
printf("Difference is negative and not representable as an unsigned.\n");
}
[Edit] OP change from "2 unsigned int" to "multiple unsigned int"
Confident doing N*(N-1)/2 compares would be needed if a wider integer width is not available for subtracting N unsigned.
With N > 2, simplest, if available, to use wider integers. Such as
long long diff;
// or
#include <stdint.h>
intmax_t diff;
Depending though on your platform, these type may or may not be wider than unsigned. Certainly not narrower.
Note: this issue similarly applies to multiple signed int too. Other compares are use though. But that is another question.

Bitwise overflow checking in c [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I am trying to write two functions that will check/prevent overflow in c (using only ! ~ | & ^ +) but cant get it. The first is will a certain twos compliment/signed int will fit in a certatin amount of bits: fitsB(int x, int n) where is the int and n is the size of bits to use. Also a function that will check to see if two ints will not overflow when added together: overflowInt(int x, int y). I can get it if they are unsigned ints but the negatives just make things harder for me. Anyone know how to?
There also is no casting and ints are always 32 bit
/*
* addOK - Determine if can compute x+y without overflow
* Example: addOK(0x80000000,0x80000000) = 0,
* addOK(0x80000000,0x70000000) = 1,
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 20
* Rating: 3
*/
int addOK(int x, int y) {
// Find the sign bit in each word
//if a and b have different signs, you cannot get overflow.
//if they are the same, check that a is different from c and b is different from c,
// if they are the same, then there was no overflow.
int z=x+y;
int a=x>>31;
int b=y>>31;
int c=z>>31;
return !!(a^b)|(!(a^c)&!(b^c));
}
x will fit in n bits if x < 2^(n-1).
The overflow question needs more information. Two ints will not overflow if you assign them to a long (or a double).
Using the above example (Adam Shiemke), you can find the maximum (positive) value and minimum value (negative) to get the range for n number of bits. 2^(n-1) (from Adam's example) and minus one for the maximum/positive number which can be represented in the n bits. For the minimum value, negate 2^(n-1) to get the minimum value x => -(2^(n-1)); (Note the >= not > for the minimum range). For example, for n = 4 bits, 2^(4-1) - 1 = 2^3 -1 = 7 so x <= 7 and x >= -8 = (-(2^(4-1)).
This assumes the initial input does not overflow a 32 bit quanity (Hopefully an error occurs in that condition) and the number of bits you are using is less then 32 (as you are adding 1 for the negative range and if you have 32 bits, it will overflow, see below for an explanation).
To determine if addition will overflow, if you have the maximum value, the x + y <= maximum value. By using algebra, we can get y <= maximum value - x. You can then compare the passed in value for y and if it does not meet the condition, the addition will overflow. For example if x is the maximumn value, then y <= 0, so y must be less then or equal to zero or the addition will overflow.

Resources