Compare two unsigned 8 bit int

Hi I have a simple question but in a situation.
How can I compare two 8 bit int a, and b, in the situation <, >, = these comparison are defined only on the signed int.

Example
1. 00000000 vs 00000001. The left one is less than the right one, whatever are they signed or unsigned. Also unsigned comparison < or > work here.
2. 00000000 vs 10000000 The left one as unsigned is less than the right one. But the signed comparison tells us 00000000 > 10000000.


More detailed and the reason for this question.
I am programming with SIMD, AVX2. __mm256i is a vector with 32 * 8 bit int.
I could use the SIMD signed comparison _mm256_cmpgt_epi8.
But the unsigned comparison function _mm256_cmpgt_epu8_mask is only compile-able on Server CPU.
I want to use the signed comparison to mock up the unsigned comparison, to the correct answer.

EDIT:
Hmm Cast is also not possible. Because in this situation, <, > are only defined for signed.
(unsigned char)n < (unsigned char)m so not working in this situation.
Last edited on
1
2
3
4
5
6
7
8
#include <iostream>
int main()
{
    int m = 22;
    int n = 132;
    std::cout <<"tested as signed: "<< ((signed char)n < (signed char)m ? "n < m" : "n >= m");
    std::cout << "\ntested as unsigned: "((unsigned char)n < (unsigned char)m ? "n < m" : "n >=m");
}
Last edited on
Hi nuderobmonkey
Sorry for the lacking statement.
Hmm Cast is also not possible. Because in this situation, <, > are only defined for signed.
(unsigned char)n < (unsigned char)m so not working in this situation.
Last edited on
What about using a bitmask? But I'm not very experienced in working with such.
Here I have a suggestion, but I'm not sure if it will work correctly.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

// checks if a is lower then b for unsigned ints
bool lower_than( int a, int b) 
{
    static int bitmask = 1;
    constexpr bitmask <<= 7;

    // Info whether the 8th bit is set.
    bool bit_a_is_set = false;
    bool bit_b_is_set = false;
    if ( a & bitmask) bit_a_is_set = true;
    if ( b & bitmask) bit_b_is_set = true;

    if (!bit_a_is_set && !bit_b_is_set) return a < b;
    if (bit_a_is_set && !bit_b_is_set) return false;  // !(a < b)
    if (!bit_a_is_set && bit_b_is_set) return true;  // a < b);

    // Here both numbers would be negative:
    // If I'm right, we could just flip the > to get a <
    return a > b; 
}

// Checks if a is greater than b for unsigned ints.
bool greater_than( int a, int b)
{
    if ( !lower_than(a, b)  &&  a != b  )
        return true;
    else
        return false;
}

'==' and '!=' should the same for signed and unsigned.
Last edited on
can you do something really simple like square both values into a u16 bit int and compare those (do you have all the comparisons for 16bit defined?)

can you do bitwise logic on signed values on this system? Or can you access nibbles on this system? Has anyone had this problem before, and solved it online / in a dedicated forum? Is inline assembly for this system available?

there has to be a way to do this in no more than 3 or 4 operations; do you care about speed at all for this?





1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <iostream>
#include <cstdint>
#include <bitset>
using namespace std;

bool lessThan( uint8_t a, uint8_t b )
{
   constexpr uint8_t left  = 1 << 7;
   constexpr uint8_t right = left - 1;

   int8_t a7 = a >> 7, b7 = b >> 7;
   if ( a7 < b7 ) return true; 
   if ( b7 < a7 ) return false;

   int8_t ar = a & right, br = b & right;
   return ar < br;
}

bool greaterThan( uint8_t a, uint8_t b )
{
   return lessThan( b, a );
}

int main()
{
   uint8_t a = 0, b = 128;
   cout << lessThan( a, b ) << '\n';
   cout << greaterThan( a, b ) << '\n';
}
<, >, = these comparison are defined only on the signed int.
They are defined for unsigned integer types also. Are you using some other data type? Can you show us your code?
This was the OP's justification:

I could use the SIMD signed comparison _mm256_cmpgt_epi8.
But the unsigned comparison function _mm256_cmpgt_epu8_mask is only compile-able on Server CPU.
Topic archived. No new replies allowed.