How to split unsigned integer 256 and round to a closer value?

I need to divide the number 256 and round it to a closer value, for example, if input 255 I want to get 1, not 0. Now I use

int x = 150; int z = MulDiv(x, 1, 256); 

But I think that this is not the best way to achieve my goal, can anyone advise better.

+6
source share
4 answers

Use this:

 unsigned int x = 150; unsigned int z = (x + 128) >> 8; 

128 is the average, so after adding this rounding and 256=2^8 so that you can use the bit shift operation instead of division.

NOTE: this method only works for positive values.

If you need this for positive and negative values, you will need the following:

 int x = -150; int z = (x >= 0 ? (x + 128) : (x - 128)) / 256; 

NOTE: the bit-shift for signed values ​​has some specific and not always trustworthy, so you cannot use this: int z = (x < 0) ? (x - 128) / 256 : (x + 128) >> 8; int z = (x < 0) ? (x - 128) / 256 : (x + 128) >> 8;

+7
source

This will work for both positive and negative integers (and zero too):

 int eps = x < 0 ? -128 : 128 int y = (x + eps) / 256; 

The -pedantic version is -pedantic and f[oo|ai]lsafe :

 if (x < INT_MIN + 128 || x > INT_MAX - 128) { fputs("nasal demons!\n", stderr); abort(); } int eps = x < 0 ? -128 : 128; int y = (x + eps) / 256; 
+4
source

For proper rounding to the nearest of the signed values, you can do this:

 y = (x >= 0 ? (x + 128) : (x - 128)) / 256; 
+1
source

To handle extremely large and small values ​​correctly, you can use

 int divideAndRound256(int x) { if(x > INT_MAX - 128) return (x - 128) / 256 + 1; else if(x < INT_MIN + 128) return (x + 128) / 256 - 1; else if(x < 0) return (x - 128) / 256; else return (x + 128) / 256; } 

Or for simply unsigned values

 unsigned int divideAndRound256(unsigned int x) { if(x > UINT_MAX - 128) return ((x - 128) >> 8) + 1; else return (x + 128) >> 8; } 
0
source

Source: https://habr.com/ru/post/953828/


All Articles