i'm reading an article about integer security .
here's the link:
http://ptgmedia.pearsoncmg.com/images/0321335724/samplechapter/seacord_ch05.pdf
In page 166,there is said:
A computation involving unsigned operands can never overflow,because a
result that cannot be represented by the resulting unsigned integer
type is reduced modulo to the number that is one greater than the
largest value that can be represented by the resulting type.
What does it mean? appreciate for reply.
It means the value "wraps around".
UINT_MAX + 1 == 0
UINT_MAX + 2 == 1
UINT_MAX + 3 == 2
.. and so on
As the link says, this is like the modulo operator: http://en.wikipedia.org/wiki/Modulo_operation
No overflow?
"Overflow" here means "producing a value that doesn't fit the operand". Because arithmetic modulo is applied, the value always fits the operand, therefore, no overflow.
In other words, before overflow can actually happen, C++ will already have truncated the value.
Modulo?
Taking a value modulo some other value means to apply a division, and taking the remainder.
For example:
0 % 3 = 0 (0 / 3 = 0, remainder 0)
1 % 3 = 1 (1 / 3 = 0, remainder 1)
2 % 3 = 2 (2 / 3 = 0, remainder 2)
3 % 3 = 0 (3 / 3 = 1, remainder 0)
4 % 3 = 1 (4 / 3 = 1, remainder 1)
5 % 3 = 2 (5 / 3 = 1, remainder 2)
6 % 3 = 0 (6 / 3 = 2, remainder 0)
...
This modulo is applied to results of unsigned-only computations, with the divisor being the maximum value the type can hold. E.g., if the maximum is 2^16=32768, then 32760 + 9 = (32760 + 9) % (32768+1) = 0.
It means that you can't alter the sign of a unsigned calculation, but it can still produce unexpected results. Say we have an 8-bit unsigned value:
uint8_t a = 42;
and we add 240 to that:
a += 240;
it will not fit, so you get 26.
Unsigned math is clearly defined in C and C++, where signed math is technically either undefined or implementation dependent or some other "things that you wouldn't expect may happen" wording (I don't know the exact wording, but the conclusion is that "you shouldn't rely on the behaviour of overflow in signed integer values")
One more example to show unsigned data type wraps around instead of overflow:
unsigned int i = std::numeric_limits<unsigned int>::max(); // (say) 4294967295
Assigning a -ve number to the unsigned is not recommended but for the illustrative purpose, I'm using it below
unsigned int j = -1; // 4294967295 wraps around(uses modulo operation)
unsigned int j = -2; // 4294967294
Visualizing the unsigned (0 to max) range with respect to the modulo of max+1 (where max = 2^n):
Range : 0, 1, 2,......., max-2, max-1, max
.................................................................................
Last-to-First : -(max+1), -max, -(max-1),......., -3, -2, -1
First-to-Last : max+1, max+2, max+3,......., max+max-1, max+max, max+max+1
Modulo Addition Rule: (A + B) % C = (A % C + B % C) % C
[max + max + 1] % (max + 1) = [(max) + (max + 1)] % (max + 1)
= [(max % (max + 1)) + ((max + 1) % (max + 1))] % (max + 1)
= [(max % (max + 1)) + 0] % (max + 1)
= [max] % (max + 1)
= max
Related
What data type or what ways can I store large integers possibly greater than 10^18 and How can I efficiently improve my approach to the problem?
I am currently working on a problem that asks to find the sum of all divisors d(k) given that:
N N
S(N) = ∑ ∑ d(j*i)
i=1 j=1
with the largest value of N = 10^9 and largest divisor (10^9 * 10^9). Stored in:
long long int
The program solves and slows down at N = 10^3 and anything higher takes up to much memory and crashes.
I used a for loop for the values of i and j that calculates the values of d(k) > d(i * j) and store it in a vector:
{d(1 * 1), d(1 * 2), ... , d(i>N * j>N)}
Then a separate function that finds all divisors of d(k) then adds them up:
d(1) = 1
d(2) = 1 + 2 = 3
d(3) = 1 + 3 = 4
d(4) = 1 + 2 + 4 = 7
...
d(i>N * j>N)
S(N) = d(1) + d(2) + d(3) + d(4) + ... + d(i>N * j>N)
Any values of N greater than 10^5 gets displayed as S(N) mod 10^9.
I need a branchless number cycle code.
like this:
int i = 0;
i = (i + 1) % 4 //1
i = (i + 1) % 4 //2
i = (i + 1) % 4 //3
i = (i + 1) % 4 //0
i = (i + 1) % 4 //1
...
But it should work in the reverse order of the code above. (3 > 2 > 1 > 0 > 3 > ...)
I first tried "i = (i - 1) % 4".
But this worked differently than I wanted. (-1 > -2 > -3 > 0 > -1 > ...)
However, if I use the method of adding 4 when i is negative, this code is no longer branchless.
How can I implement the functionality which I want (without additional variables or arrays)?
(This article has been translated by Google Translate.)
The error happens because in C89 the remainder of negative numbers was underspecified and from C99, negative % positive will result in a negative number which is unlike in some programming languages such as Python, where (-1) % 4 would indeed result in 3.
But it is easy to circumvent. When you subtract 1, it is the same as adding -1. Since 0 - 1 will get to -1, we would have a negative remainder. To stay positive, instead of adding the negative -1 we can add a positive number that's congruent to -1 (mod m). The smallest positive such number is m - 1 for an m > 1. Therefore we can use:
#define MODULUS 4 // or any other moduli > 1
int i = 0;
i = (i + (MODULUS - 1)) % MODULUS; //3
i = (i + (MODULUS - 1)) % MODULUS; //2
i = (i + (MODULUS - 1)) % MODULUS; //1
i = (i + (MODULUS - 1)) % MODULUS; //0
i = (i + (MODULUS - 1)) % MODULUS; //3
You need to change your expression a bit. It should be:
i = ( i + 3 ) % 4;
In general, if you want a number in range [0,N-1] with such cycle then the equation should be:
i = (i + (N - 1)) % N;
You can see it working here(manually several times) and here (in loop):
int main()
{
int i = 0;
i = ( i + 3 ) % 4; //3
i = ( i + 3 ) % 4; //2
i = ( i + 3 ) % 4; //1
i = ( i + 3 ) % 4; //0
i = ( i + 3 ) % 4; //3
i = ( i + 3 ) % 4; //2
i = ( i + 3 ) % 4; //1
i = ( i + 3 ) % 4; //0
return 0;
}
You can use unsigned arithmetic, then the numbers won't become negative.
unsigned i = 0;
i = (i - 1) % 4 //3
i = (i - 1) % 4 //2
i = (i - 1) % 4 //1
i = (i - 1) % 4 //0
i = (i - 1) % 4 //3
Also, maybe more intuitive, you can use bitwise operations to implement a 2-bit counter.
unsigned i = 0;
i = (i - 1) & 3;
i = (i - 1) & 3;
i = (i - 1) & 3;
i = (i - 1) & 3;
i = (i - 1) & 3;
On machine code level, this is identical to the code above.
There are two cases:
Case 1: The modulo is a power of 2
In this case, you can simply use unsigned arithmetic with a bit mask:
unsigned i = ...;
i = (i - 1) & (modulo - 1);
When i = 0, subtracting 1 will yield a value with all bits set in unsigned arithmetic, and the mask operation & will yield the value modulo - 1.
Case 2: The modulo is not a power of 2
In this case, no fancy bit tricks work. You can only avoid going negative:
i = (i + modulo - 1) % modulo;
It is my understanding that rand() % a + b will return numbers between a and b including both a and b. I must be misunderstanding this though, because when I run the code below int r will return 2, 3, or 4. I, of course, am expecting it to return 2 or 3. I'm calling srand(time(NULL)); in main and I'm using
#include <time.h> and #include <stdlib.h>
Am I missing something?
int r = (rand() % 3) + 2;
if (r ==2)
g_fan.draw(r); // skin == 2
else
g_fan.draw(1 + r); //skin == 4
It is my understanding that rand() % a + b will return numbers between a and b including both a and b.
No. It will result in a number between b and (a+b-1), both including.
Range of values of rand() % a is 0 and a-1, both including.
Hence, the range of values of rand() % a + b is b and (a-1+b), both including.
To get random values between a and b, both including, use:
auto interval = (b-a+1);
auto result = a + rand() % interval;
let num be any number you get by calling rand() and if you do % with 3 , there is a possibility of getting one of these number 0, 1, 2.
therefore you are getting 2 ,3, 4 for :
int r = (rand() % 3) + 2;
int r = (rand() % 3) + 2;
The rand() % 3 will return a number between 0 and 2. When you add t2 to each number, that means it will return 2 to 4. The rand() % afunction in general returns a value form 0 to a - 1. When you do rand() % a + b, then the resulting value will range from 0 + b to a - 1 + b.
To get a value between 2 and 3, use:
int r = (rand() % 2) + 2;
The folloing rand() function gives a number from 0 to 2 - 1, which is 1. When you add 2 to each number, you get a range of 0 + 2, which is 2, to 2 - 1 + 2, which is 3.
I have a range of numbers from 100 to 999. I need to get every number separately of it and check whether it can be divided by 2. For example:
232
2 divided by 2 = 1 = true
3 divided by 2 = 1.5 = false
2 divided by 2 = 1 = true
and so on.
To get the first number all I have to do is to divide the entire number by 100.
int x = 256;
int k = x/100;
so x would hold a value of 2.
Now, is there a way to check those other ones? Because k = x/10; would already be 25.
Try this:
int x = 256;
int i = x / 100; // i is 2
int j = (x % 100) / 10; // j is 5
int k = (x % 10); // k is 6
maybe look into integer division and the modulo.
int k1 = (x / 10) % 10 // "10s"
int k2 = ( x / 100 ) % 10 // "100s"
//etc etc
Use modulo to get the last digit of the number, then divide by ten to discard the last digit.
Repeat while the number is non-zero.
What you need is the modulus operator %. It does a division and returns the reminder.
1 % 2 = 1
2 % 2 = 0
3 % 2 = 1
4 % 2 = 0
...
eg. take 232:
int num = 232;
int at_ones_place = num % 10;
int at_tens_place = ( num /10 ) % 10 ;
int at_hundreds_place = (num /100);
How is this code working for multiple of 5
bool isMultipleof5(int n)
{
/* If n is a multiple of 5 then we make sure that last
digit of n is 0 */
if ( (n&1) == 1 )
n <<= 1;
float x = n;
x = ( (int)(x*0.1) )*10;
/* If last digit of n is 0 then n will be equal to (int)x */
if ( (int)x == n )
return true;
return false;
}
It first makes n divisable by 2.
Next, it checks if it is divisable by 10 by multiplying with 0.1 and again with 10. The idea that if it is divisable by 10, you will get back to the original, and only then.
So, if the modifies n is divisable by 10 - it is certainly divisable by 5 as well, and since modified n is always divisable by 2, if it is divisable by 5 it will be divisable by 10, and the algorithm works.
NOTE: This is very unsuggested and especially might break with large values due to floating point precision issues. using the % operator should be prefered: return (n % 5) == 0
This is how the code works with some examples.
if ( (n&1) == 1 ) //Checks if the number is odd
n <<= 1; //Multiplies the number by 2 if odd
x = ( (int)(x * 0.1) //Divides the number 10 then truncates any decimal places
* 10 ) //Multiplies it back by 10
if ( (int)x == n ) //If the floating point value equals the (semi) original value its divisible by 5
return true;
return false; //Other wise false
Example:
15 & 1 == 1 //15 is odd
15 <<= 1; //n is now 30
30 / 10 = 3;
3 * 10 = 30; //x is now 30
30 == 30 //15 is a multiple of 5
17 & 1 == 1 //17 is odd
17 <<= 1; //n is now 34
34 / 10 = 3.4;
((int)3.4 = 3) * 10 = 30; //x is now 30
30 != 34 //17 is not a multiple of 5.
As others said though just simply use the mod operator %.
This is how it works:
Double the number. Now anything ending in 5 will be divisible 10 (and also divisible by 5). n <<= 1; (the check for oddness is unnecessary (n&1) == 1)
Divide it by 10, and cast away the fractional part. (int)(x*0.1)
Multiply it by 10, so now we have the same number as in step 1 only if the number in step 1 was already divisible by 10.
The use of floating point to divide by 10 makes this algorithm dangerous and probably incorrect for large values.
Try this
bool isMultipleof5(int n)
{
return (n%5) == 0;
}
A simpler way would be
bool isMultipleof5(int n)
{
return 0 == ( n % 5 ) ;
}
#define IS_MULTIPLE_OF_5(n) (((n)%5) ? 0 : 1)
I'd agree that (n % 5) == 0 would be an ideal solution, but that wasn't really the question.
This code works because it first checks if the input is odd. If it is, it multiplies by two. Since all odd multiples of 5 end with a 5, multiplying by 2 gives a number that ends with 0.
Then it checks if the last digit is 0. This can only happen if it started as a 0 (i.e. was even, we didn't change it) or if it was odd and ended in a 5 (we multiplied by 2). So, if it ends in 0 then the input must have been divisible by 5.
I'd add that this is also an awkward way to check the value of the last digit. I'd suggest n % 10 == 0 instead, but like others mentioned... you could have just used n % 5 == 0 in the first place ;).