I'm trying to write a code for modulus, but when I do it for negative numbers I don't get the right result, my code:
double mod (double X, double Y)
{
double result = X;
if (X>0){
do
{
result = result - Y;
}while(result >= Y);
}
if (X<0){
do
{
result = result + Y;
}while(0 >= result);
}
}
When you do something like mod(-5,2) it should return -1 but it returns 1, why does it return 1 when it can't be greater than 0?
In my mind I thought it works like -5 + 2 = -3 + 2 = -1. For positive it would be 5 - 2 = 3 - 2 = 1.
Thanks.
EDIT: I am trying to do this without using CMATH using my own math library.
EDIT: My return result is in a later part of the program and does show output. This just a block of the entire program itself.
Examine this part of code only:
if (X<0){
do
{
result = result + Y;
}while(0 >= result);
}
Let's say that X is -5, and result is 0.
do loop will be executed:
1. pass - result = -3
2. pass - result = -1
3. pass - result = -1 + 2 = 1
3. pass will be executed as result from 2. pass is still less than zero.
You need to change your loop condition to while(0 >= result + Y)
You are missing
return result;
consider the integer sequence
-7 -6 -5 -4 -3 -2 -1 0 1 2 3 4 5 6 7
when taking mod(5,2) we are taking multiple of 2 less than or equal to 5 then return difference with 5. ie here 1 (5-4)
for negative numbers according to this concept
for mod(-5, 2). number which is lesser than -5 that is divisible by 2 is -6(not -4; -4 > -5). and its difference is (-5 - -6) which is 1.
That is what happening in your code
Related
My program is to sum an arithmetic sequence from 1 to n like
-1 2 -3 4 -5 6 -7 etc...
But
n (1 ≤ n ≤ 10^15).
And when I execute this program, I am faced with that the sum variable is overflowing although I use data type long long
#include <iostream>
#include <cstring>
using namespace std;
int main()
{
long long n;
cin >>n;
if (n%2!=0)
{
long long sump = ((n-1)/4.0) * (2+(n-1));
long long sumn = ((n+1)/4.0) * (-1-n);
long long sum = sump + sumn;
cout << sum << endl;
}
else
{
long long sump = ((n)/4.0) * (2+(n));
long long sumn = ((n)/4.0) * (-1-(n-1));
long long sum = sump + sumn;
cout << sum << endl;
}
}
If you see such big numbers in questions, then most often you cannot solve that by brute force, running big loops and the like.
You need to find an analytical or mathematical solution.
Even, if you do not know the solution, you may look at example values.
If you look at your series, then you can see something like the below:
Index Sign Series Sum
0 1 0 0
1 -1 -1 -1
2 1 2 1
3 -1 -3 -2
4 1 4 2
5 -1 -5 -3
6 1 6 3
7 -1 -7 -4
8 1 8 4
9 -1 -9 -5
10 1 10 5
As you can see,
if n is even, then the result is n/2
if n is odd then the result is -((n/2)+1)
And this can be easily implemented . . .
int sum_down(int x)
{
if (x >= 0)
{
x = x - 1;
int y = x + sum_down(x);
return y + sum_down(x);
}
else
{
return 1;
}
}
What is this smallest integer value of the parameter x, so that the returned value is greater than 1.000.000 ?
Right now I am just doing it by trial and error and since this question is asked via a paper format. I don't think I will have enough time to do trial and error. Question is, how do you guys visualise this quickly such that it can be solved easily. Thanks guys and I am new to programming so thanks in advance!
The recursion logic:
x = x - 1;
int y = x + sum_down(x);
return y + sum_down(x);
can be simplified to:
x = x - 1;
int y = x + sum_down(x) + sum_down(x);
return y;
which can be simplified to:
int y = (x-1) + sum_down(x-1) + sum_down(x-1);
return y;
which can be simplified to:
return (x-1) + 2*sum_down(x-1);
Put in mathematical form,
f(N) = (N-1) + 2*f(N-1)
with the recursion terminating when N is -1. f(-1) = 1.
Hence,
f(0) = -1 + 2*1 = 1
f(1) = 0 + 2*1 = 2
f(2) = 1 + 2*2 = 5
...
f(18) = 17 + 2*f(17) = 524269
f(19) = 18 + 2*524269 = 1048556
Your program can be written this way (sorry about c#):
public static void Main()
{
int i = 0;
int j = 0;
do
{
i++;
j = sum_down(i);
Console.Out.WriteLine("j:" + j);
} while (j < 1000000);
Console.Out.WriteLine("i:" + i);
}
static int sum_down(int x)
{
if (x >= 0)
{
return x - 1 + 2 * sum_down(x - 1);
}
else
{
return 1;
}
}
So at first iteration you'll get 2, then 5, then 12... So you can neglect the x-1 part since it'll stay little compared to the multiplication.
So we have:
i = 1 => sum_down ~= 4 (real is 2)
i = 2 => sum_down ~= 8 (real is 5)
i = 3 => sum_down ~= 16 (real is 12)
i = 4 => sum_down ~= 32 (real is 27)
i = 5 => sum_down ~= 64 (real is 58)
So we can say that sum_down(x) ~= 2^x+1. Then it's just basic math with 2^x+1 < 1 000 000 which is 19.
A bit late, but it's not that hard to get an exact non-recursive formula.
Write it up mathematically, as explained in other answers already:
f(-1) = 1
f(x) = 2*f(x-1) + x-1
This is the same as
f(-1) = 1
f(x+1) = 2*f(x) + x
(just switched from x and x-1 to x+1 and x, difference 1 in both cases)
The first few x and f(x) are:
x: -1 0 1 2 3 4
f(x): 1 1 2 5 12 27
And while there are many arbitrary complicated ways to transform this into a non-recursive formula, with easy ones it often helps to write up what the difference is between each two elements:
x: -1 0 1 2 3 4
f(x): 1 1 2 5 12 27
0 1 3 7 15
So, for some x
f(x+1) - f(x) = 2^(x+1) - 1
f(x+2) - f(x) = (f(x+2) - f(x+1)) + (f(x+1) - f(x)) = 2^(x+2) + 2^(x+1) - 2
f(x+n) - f(x) = sum[0<=i<n](2^(x+1+i)) - n
With eg. a x=0 inserted, to make f(x+n) to f(n):
f(x+n) - f(x) = sum[0<=i<n](2^(x+1+i)) - n
f(0+n) - f(0) = sum[0<=i<n](2^(0+1+i)) - n
f(n) - 1 = sum[0<=i<n](2^(i+1)) - n
f(n) = sum[0<=i<n](2^(i+1)) - n + 1
f(n) = sum[0<i<=n](2^i) - n + 1
f(n) = (2^(n+1) - 2) - n + 1
f(n) = 2^(n+1) - n - 1
No recursion anymore.
How about this :
int x = 0;
while (sum_down(x) <= 1000000)
{
x++;
}
The loop increments x until the result of sum_down(x) is superior to 1.000.000.
Edit : The result would be 19.
While trying to understand and simplify the recursion logic behind the sum_down() function is enlightening and informative, this snippet tend to be logical and pragmatic in that it does not try and solve the problem in terms of context, but in terms of results.
Two lines of Python code to answer your question:
>>> from itertools import * # no code but needed for dropwhile() and count()
Define the recursive function (See R Sahu's answer)
>>> f = lambda x: 1 if x<0 else (x-1) + 2*f(x-1)
Then use the dropwhile() function to remove elements from the list [0, 1, 2, 3, ....] for which f(x)<=1000000, resulting in a list of integers for which f(x) > 1000000. Note: count() returns an infinite "list" of [0, 1, 2, ....]
The dropwhile() function returns a Python generator so we use next() to get the first value of the list:
>>> next(dropwhile(lambda x: f(x)<=1000000, count()))
19
I am looking for a solution for cycling through consecutive numbers based on an input value. Similar to modulo, but different for negative numbers. Is there a better solution compared to the inefficient code below? Here is some input/output examples:
Numbers range 0 to 2
-2 -> 1
-1 -> 2
0 -> 0
1 -> 1
2 -> 2
3 -> 0
4 -> 1
//Inefficient Code example
int getConsecutiveVal(int min, int max, int input) //Inclusive in this scenario
{
while (input>max)
input -= (1+max-min);
while (input<min)
input += (1+max-min);
return input;
}
//Incorrect Code example since func(0,2,-1) returns 2
int getConsecutiveVal(int min, int max, int input)
{
return (input % (1+max-min))+min;
}
To be able to increment or decrement, I used the following function. It's more than 1 line, but fewer math operations. It's similar in spirit to the original poster's format. Tested for positive and negative cases.
int16_t cycleIncDec(int16_t x, int16_t dir, int16_t xmin, int16_t xmax) {
// inc/dec with constrained range
// the supplied xmax must be greater than xmin
x += dir;
if (x > xmax) x = xmin;
else if (x < xmin) x = xmax;
return x;
}
Output of cycleIncDec() with various start values and step sizes
x: 11: +1 0 1 2 3 4 5 6 0 1 2 3
x: 4: -1 3 2 1 0 -1 -2 -3 -4 -5 -6 -7
x: -8: -1 -13 -12 -11 -10 -9 -8 -13 -12 -11 -10 -9
x:-190: -2 -192 -194 -196 -198 -200 -170 -172 -174 -176 -178 -180
In principle, you need the modulo operator. The problem is that in C it doesn't work as expected for negative numbers.
If you know the minimum input value, you can just add a positive number x big enough to transform all negative numbers to positive. It won't affect the result if x % R = 0 (in your example R=3.)
In your example, if you add, say, 3*10 to all inputs and perform the modulo operation you'll get the desired result:
mod(3*10+[-2 -1 0 1 2 3 4], 3)
= 1 2 0 1 2 0 1
(the above is matlab notation and is specialized to the example you have presented. I'll leave it to you to extend it to arbitrary min/max)
A specific formula for the case you have presented:
You have suggested using
((input+abs(input)*(1+max-min)) % (1+max-min))+min
However, this formula does not work. For two reasons:
First, if input=0, the abs() returns 0 and you get the minimum value as output (This is not always what your explicit while-based loop produces)
Second, you forgot to subtract min from the input before the operation.
So the correct formula is the following (using x for input):
(x - xmin + (1+abs(x))*(1+xmax-xmin)) % (1+xmax-xmin) + xmin
You can call % twice to get you the right behaviour, since a%b, for positive b, is guaranteed to lie in [-b+1, b+1].
int getConsecutiveVal(int min, int max, int input)
{
int range_len = (1 + max - min);
input -= min;
return (((input % range_len) + range_len) % range_len) + min;
}
I am fairly new to C++, and am struggling through a problem that seems to have a solid solution but I just can't seem to find it. I have a contiguous array of ints starting at zero:
int i[6] = { 0, 1, 2, 3, 4, 5 }; // this is actually from an iterator
I would like to partition the array into groups of three. The design is to have two methods, j and k, such that given an i they will return the other two elements from the same group of three. For example:
i j(i) k(i)
0 1 2
1 0 2
2 0 1
3 4 5
4 3 5
5 3 4
The solution seems to involve summing the i with its value mod three and either plus or minus one, but I can't quite seem to work out the logic.
This should work:
int d = i % 3;
int j = i - d + ( d == 0 );
int k = i - d + 2 - ( d == 2 );
or following statement for k could be more readable:
int k = i - d + ( d == 2 ? 1 : 2 );
This should do it:
int j(int i)
{
int div = i / 3;
if (i%3 != 0)
return 3*div;
else
return 3*div+1;
}
int k(int i)
{
int div = i / 3;
if (i%3 != 2)
return 3*div+2;
else
return 3*div+1;
}
Test.
If you want shorter functions:
int j(int i)
{
return i/3*3 + (i%3 ? 0 : 1);
}
int k(int i)
{
return i/3*3 + (i%3-2 ? 2 : 1);
}
Well, first, notice that
j(i) == j(3+i) == j(6+i) == j(9+i) == ...
k(i) == k(3+i) == k(6+i) == k(9+i) == ...
In other words, you only need to find a formula for
j(i), i = 0, 1, 2
k(i), i = 0, 1, 2
and then for the rest of the cases simply plug in i mod 3.
From there, you'll have trouble finding a simple formula because your "rotation" isn't standard. Instead of
i j(i) k(i)
0 1 2
1 2 0
2 0 1
for which the formula would have been
j(i) = (i + 1) % 3
k(i) = (i + 2) % 3
you have
i j(i) k(i)
0 1 2
1 0 1
2 0 2
for which the only formula I can think of at the moment is
j(i) = (i == 0 ? 1 : 0)
k(i) = (i == 1 ? 1 : 2)
If the values of your array (let's call it arr, not i in order to avoid confusion with the index i) do not coincide with their respective index, you have to perform a reverse lookup to figure out their index first. I propose using an std::map<int,size_t> or an std::unordered_map<int,size_t>.
That structure reflects the inverse of arr and you can extra the index for a particular value with its subscript operator or the at member function. From then, you can operate purely on the indices, and use modulo (%) to access the previous and the next element as suggested in the other answers.
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 ;).