Skip to content

Instantly share code, notes, and snippets.

@joshkunz
Created September 22, 2014 07:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save joshkunz/a0e2f1c95fa5b2e4ca10 to your computer and use it in GitHub Desktop.
Save joshkunz/a0e2f1c95fa5b2e4ca10 to your computer and use it in GitHub Desktop.
Arbitrary bit-width saturing addition and subtraction operations. Created for regher's Advanced Embedded Systems class.
#include "sat_ops.h"
#include <stdio.h>
/* Note: This code assumes that sizeof(myuint) == sizeof(myint). This assumption
* is made because the comment at the top of 'sat_ops.h' says that each pair
* will be in effect at the same time. I am sacrificing robustness to acheive
* a smaller footprint. */
#define UMIN ((myuint) 0)
#define UMAX ((myuint) (~UMIN))
#define UHIGH ((myuint) (~(UMAX >> 1)))
#define MIN ((mysint) UHIGH)
#define MAX ((mysint) (UMAX >> 1))
myuint sat_unsigned_sub(myuint a, myuint b) {
return b > a ? 0U : a - b;
}
myuint sat_unsigned_add(myuint a, myuint b) {
myuint sum = a + b;
return sum < a || sum < b ? UMAX : sum;
}
/* splitting this into a seperate function reduces my byte count by 16 bytes
* in GCC. */
static void signs(myuint *a, myuint *b, myuint *s,
myuint *out_a, myuint *out_b, myuint *out_s) {
*out_a = (*a & UHIGH);
*out_b = (*b & UHIGH);
*out_s = (*s & UHIGH);
}
mysint sat_signed_add(mysint a, mysint b) {
myuint usum = (myuint) a + (myuint) b;
myuint a_sign, b_sign, s_sign;
signs((myuint *) &a, (myuint *) &b, &usum, &a_sign, &b_sign, &s_sign);
if (!a_sign && !b_sign && s_sign) { return MAX; }
else if (a_sign && b_sign && !s_sign) { return MIN; }
return (mysint) usum;
}
mysint sat_signed_sub(mysint a, mysint b) {
myuint usub = (myuint) a - (myuint) b;
myuint a_sign, b_sign, s_sign;
signs((myuint *) &a, (myuint *) &b, &usub, &a_sign, &b_sign, &s_sign);
if (!a_sign && b_sign && s_sign) { return MAX; }
else if (a_sign && !b_sign && !s_sign) { return MIN; }
return (mysint) usub;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment