Commit c32e5ca
Changed files (3)
testing
tests
util
testing/tests/001_safemath.c
@@ -9,7 +9,7 @@ void entry(void) {
assert( (-1^1) == -2 ); /* All safemath code assumes 2's complement. Assert it here, too. */
- /* Validate correct addition and subtraction behaviour */
+ /* Validate correct basic addition and subtraction behaviour */
assert( S_OK( u64_add( 3, 2, &res ))); assert( res == 5 );
assert( S_OK( u32_add( 3, 2, (u32*)&res ))); assert( res == 5 );
assert( S_OK( u16_add( 3, 2, (u16*)&res ))); assert( res == 5 );
@@ -30,19 +30,52 @@ void entry(void) {
assert( S_OK( s16_sub( 3, 2, (s16*)&res ))); assert( res == 1 );
assert( S_OK( s8_sub( 3, 2, (s8 *)&res ))); assert( res == 1 );
- /* Unsigned overflow */
+ /* Catch potential off-by-one implementation errors */
+ /* Unsigned */
+ assert( S_OK( u64_add( u64_MAX - 1, 1, &res ))); assert( res == u64_MAX );
+ assert( S_OK( u32_add( u32_MAX - 1, 1, (u32*)&res ))); assert( (u32)res == u32_MAX );
+ assert( S_OK( u16_add( u16_MAX - 1, 1, (u16*)&res ))); assert( (u16)res == u16_MAX );
+ assert( S_OK( u8_add( u8_MAX - 1, 1, (u8 *)&res ))); assert( ( u8)res == u8_MAX );
+
+ assert( S_OK( u64_sub( u64_MIN + 1, 1, &res ))); assert( res == u64_MIN );
+ assert( S_OK( u32_sub( u32_MIN + 1, 1, (u32*)&res ))); assert( (u32)res == u32_MIN );
+ assert( S_OK( u16_sub( u16_MIN + 1, 1, (u16*)&res ))); assert( (u16)res == u16_MIN );
+ assert( S_OK( u8_sub( u8_MIN + 1, 1, (u8 *)&res ))); assert( ( u8)res == u8_MIN );
+
+ /* Signed */
+ assert( S_OK( s64_add( s64_MAX - 1, 1, (s64*)&res ))); assert( (s64)res == s64_MAX );
+ assert( S_OK( s32_add( s32_MAX - 1, 1, (s32*)&res ))); assert( (s32)res == s32_MAX );
+ assert( S_OK( s16_add( s16_MAX - 1, 1, (s16*)&res ))); assert( (s16)res == s16_MAX );
+ assert( S_OK( s8_add( s8_MAX - 1, 1, (s8 *)&res ))); assert( ( s8)res == s8_MAX );
+
+ assert( S_OK( s64_sub( s64_MAX - 1, -1, (s64*)&res ))); assert( (s64)res == s64_MAX );
+ assert( S_OK( s32_sub( s32_MAX - 1, -1, (s32*)&res ))); assert( (s32)res == s32_MAX );
+ assert( S_OK( s16_sub( s16_MAX - 1, -1, (s16*)&res ))); assert( (s16)res == s16_MAX );
+ assert( S_OK( s8_sub( s8_MAX - 1, -1, (s8 *)&res ))); assert( ( s8)res == s8_MAX );
+
+ assert( S_OK( s64_sub( s64_MIN + 1, 1, (s64*)&res ))); assert( (s64)res == s64_MIN );
+ assert( S_OK( s32_sub( s32_MIN + 1, 1, (s32*)&res ))); assert( (s32)res == s32_MIN );
+ assert( S_OK( s16_sub( s16_MIN + 1, 1, (s16*)&res ))); assert( (s16)res == s16_MIN );
+ assert( S_OK( s8_sub( s8_MIN + 1, 1, (s8 *)&res ))); assert( ( s8)res == s8_MIN );
+
+ assert( S_OK( s64_add( s64_MIN + 1, -1, (s64*)&res ))); assert( (s64)res == s64_MIN );
+ assert( S_OK( s32_add( s32_MIN + 1, -1, (s32*)&res ))); assert( (s32)res == s32_MIN );
+ assert( S_OK( s16_add( s16_MIN + 1, -1, (s16*)&res ))); assert( (s16)res == s16_MIN );
+ assert( S_OK( s8_add( s8_MIN + 1, -1, (s8 *)&res ))); assert( ( s8)res == s8_MIN );
+
+ /* Overflow */
+ /* Unsigned */
assert( S_FAILED( u64_add( u64_MAX, N, &res )));
assert( S_FAILED( u32_add( u32_MAX, N, (u32*)&res )));
assert( S_FAILED( u16_add( u16_MAX, N, (u16*)&res )));
assert( S_FAILED( u8_add( u8_MAX, N, (u8 *)&res )));
- /* Unsigned underflow */
- assert( S_FAILED( u64_sub( u64_MIN, N, &res )));
- assert( S_FAILED( u32_sub( u32_MIN, N, (u32*)&res )));
- assert( S_FAILED( u16_sub( u16_MIN, N, (u16*)&res )));
- assert( S_FAILED( u8_sub( u8_MIN, N, (u8 *)&res )));
+ assert( S_FAILED( u64_add( u64_MAX, 1, &res )));
+ assert( S_FAILED( u32_add( u32_MAX, 1, (u32*)&res )));
+ assert( S_FAILED( u16_add( u16_MAX, 1, (u16*)&res )));
+ assert( S_FAILED( u8_add( u8_MAX, 1, (u8 *)&res )));
- /* Signed overflow */
+ /* Signed */
assert( S_FAILED( s64_add( s64_MAX, N, (s64*)&res )));
assert( S_FAILED( s32_add( s32_MAX, N, (s32*)&res )));
assert( S_FAILED( s16_add( s16_MAX, N, (s16*)&res )));
@@ -52,15 +85,46 @@ void entry(void) {
assert( S_FAILED( s16_sub( s16_MAX, -N, (s16*)&res )));
assert( S_FAILED( s8_sub( s8_MAX, -N, (s8 *)&res )));
- /* Signed underflow */
+ assert( S_FAILED( s64_add( s64_MAX, 1, (s64*)&res )));
+ assert( S_FAILED( s32_add( s32_MAX, 1, (s32*)&res )));
+ assert( S_FAILED( s16_add( s16_MAX, 1, (s16*)&res )));
+ assert( S_FAILED( s8_add( s8_MAX, 1, (s8 *)&res )));
+ assert( S_FAILED( s64_sub( s64_MAX, -1, (s64*)&res )));
+ assert( S_FAILED( s32_sub( s32_MAX, -1, (s32*)&res )));
+ assert( S_FAILED( s16_sub( s16_MAX, -1, (s16*)&res )));
+ assert( S_FAILED( s8_sub( s8_MAX, -1, (s8 *)&res )));
+
+ /* Underflow */
+
+ /* Unsigned */
+ assert( S_FAILED( u64_sub( u64_MIN, N, &res )));
+ assert( S_FAILED( u32_sub( u32_MIN, N, (u32*)&res )));
+ assert( S_FAILED( u16_sub( u16_MIN, N, (u16*)&res )));
+ assert( S_FAILED( u8_sub( u8_MIN, N, (u8 *)&res )));
+ assert( S_FAILED( u64_sub( u64_MIN, 1, &res )));
+ assert( S_FAILED( u32_sub( u32_MIN, 1, (u32*)&res )));
+ assert( S_FAILED( u16_sub( u16_MIN, 1, (u16*)&res )));
+ assert( S_FAILED( u8_sub( u8_MIN, 1, (u8 *)&res )));
+
+ /* Signed */
assert( S_FAILED( s64_sub( s64_MIN, N, (s64*)&res )));
assert( S_FAILED( s32_sub( s32_MIN, N, (s32*)&res )));
assert( S_FAILED( s16_sub( s16_MIN, N, (s16*)&res )));
assert( S_FAILED( s8_sub( s8_MIN, N, (s8 *)&res )));
+ assert( S_FAILED( s64_sub( s64_MIN, 1, (s64*)&res )));
+ assert( S_FAILED( s32_sub( s32_MIN, 1, (s32*)&res )));
+ assert( S_FAILED( s16_sub( s16_MIN, 1, (s16*)&res )));
+ assert( S_FAILED( s8_sub( s8_MIN, 1, (s8 *)&res )));
+
assert( S_FAILED( s64_add( s64_MIN, -N, (s64*)&res )));
assert( S_FAILED( s32_add( s32_MIN, -N, (s32*)&res )));
assert( S_FAILED( s16_add( s16_MIN, -N, (s16*)&res )));
assert( S_FAILED( s8_add( s8_MIN, -N, (s8 *)&res )));
+ assert( S_FAILED( s64_add( s64_MIN, -1, (s64*)&res )));
+ assert( S_FAILED( s32_add( s32_MIN, -1, (s32*)&res )));
+ assert( S_FAILED( s16_add( s16_MIN, -1, (s16*)&res )));
+ assert( S_FAILED( s8_add( s8_MIN, -1, (s8 *)&res )));
+
terminate(0);
}
testing/tests/002_round.c
@@ -4,50 +4,26 @@
#define N 13
void entry(void) {
-
- u64 v1 = N + 1;
- u32 v2 = N + 1;
- u16 v3 = N + 1;
- u8 v4 = N + 1;
u64 result = N - 1;
- assert( S_OK(
- u64_round_up( v1, N, &result )
- ));
-
- assert( S_OK(
- u32_round_up( v2, N, (u32*)&result )
- ));
-
- assert( S_OK(
- u16_round_up( v3, N, (u16*)&result )
- ));
-
- assert( S_OK(
- u8_round_up( v4, N, (u8*)&result )
- ));
-
- v1 = -1;
- v2 = -1;
- v3 = -1;
- v4 = -1;
-
- assert( S_FAILED(
- u64_round_up( v1, N, &result )
- ));
-
- assert( S_FAILED(
- u32_round_up( v2, N, (u32*)&result )
- ));
+ /* Basic functionality test */
+ assert( S_OK( u64_round_up( N+1, N, &result ))); assert( result == 2*N);
+ assert( S_OK( u32_round_up( N+1, N, (u32*)&result ))); assert( result == 2*N);
+ assert( S_OK( u16_round_up( N+1, N, (u16*)&result ))); assert( result == 2*N);
+ assert( S_OK( u8_round_up( N+1, N, (u8 *)&result ))); assert( result == 2*N);
- assert( S_FAILED(
- u16_round_up( v3, N, (u16*)&result )
- ));
+ assert( S_OK( u64_round_down( 2*N-1, N, &result ))); assert( result == N);
+ assert( S_OK( u32_round_down( 2*N-1, N, (u32*)&result ))); assert( result == N);
+ assert( S_OK( u16_round_down( 2*N-1, N, (u16*)&result ))); assert( result == N);
+ assert( S_OK( u8_round_down( 2*N-1, N, (u8 *)&result ))); assert( result == N);
- assert( S_FAILED(
- u8_round_up( v4, N, (u8*)&result )
- ));
+ /* Overflow */
+ assert( S_FAILED( u64_round_up( u64_MAX, N, &result )));
+ assert( S_FAILED( u32_round_up( u32_MAX, N, (u32*)&result )));
+ assert( S_FAILED( u16_round_up( u16_MAX, N, (u16*)&result )));
+ assert( S_FAILED( u8_round_up( u8_MAX, N, (u8 *)&result )));
+ /* Rounding down to 0 is valid, so no underflow test */
terminate(0);
}
util/mathops.h
@@ -10,7 +10,7 @@
#define GEN_ROUND_UP(T) \
static inline Status T##_round_up( T number, T multiple, T *out ) { \
- if( multiple == 0 ) return S_FAILURE | ERR_ARG_3 | ERR_INVALID_ARGUMENT; \
+ if( multiple == 0 ) return S_FAILURE | ERR_ARG_2 | ERR_INVALID_ARGUMENT; \
T rem = number%multiple; \
\
if( rem == 0 ) { \
@@ -21,6 +21,12 @@
return S_SUCCESS; \
}
+#define GEN_ROUND_DOWN(T) \
+ static inline Status T##_round_down(T number, T multiple, T *out) { \
+ if( multiple == 0 ) return S_FAILURE | ERR_ARG_2 | ERR_INVALID_ARGUMENT; \
+ *out = number - (number%multiple); \
+ return S_SUCCESS; \
+ }
GEN_ROUND_UP(u8)
@@ -28,4 +34,9 @@ GEN_ROUND_UP(u16)
GEN_ROUND_UP(u32)
GEN_ROUND_UP(u64)
+GEN_ROUND_DOWN(u8)
+GEN_ROUND_DOWN(u16)
+GEN_ROUND_DOWN(u32)
+GEN_ROUND_DOWN(u64)
+
#endif