I am given an array of N elements and I need to find the index P within this array where
sum of values in the rage 0 to P is equal to sum of values in the range P+1 to N-1.
The values of each element in the array can range to -2147483648 to 2147483647 and
N can be max 10000000.
Given this how do I ensure there is no overflow when adding each values to find the index P ?
To insure no overflow, use int32_t and int64_t.
The range of values [-2147483648 ... 2147483647] matches the int32_t range. You could also use int64_t for this, but an array of 10000000 deserves space considerations.
As the sum of any 10,000,000 values does not exceed the range of int64_t, perform all your additions using int64_t.
#include <stdint.h>
size_t foo(const int32_t *value, size_t N) {
int64_t sum = 0;
...
sum += value[i];
...
}
BTW: Confident that a solution can be had that does not require addition 64-bit addition.
[Edit] Failed to derive simple int32_t only solution, but came up with:
size_t HalfSum(const int32_t *value, size_t N) {
// find sum of entire array
int64_t ArraySum = 0;
size_t P;
for (P = 0; P < N; P++) {
ArraySum += value[P];
}
// compute sum again, stopping when it is half of total
int64_t PartialSum = 0;
for (P = 0; P < N; P++) {
PartialSum += value[P];
if ((PartialSum * 2) == ArraySum) {
return P;
}
}
return N; // No solution (normally P should be 0 ... N-1)
}
Use 64 bit integers for your calculations. The best type to use is int64_t since long is no guaranteed to be 64 bits (you have to #include <stdint.h> to make it available).
Edit: Pascal Cuoq is right: long long does provide the 64-bit guarantee as well and doesn't need an include (it can be longer than 64 bits, though), so it's just the long type that you have to avoid if you want to be portable.
In the worst case scenario, P+1 = N-1. Since the max value of an ynumber can only be 2147483647 or -2147483647 for any single number, It means that in the worst cases possible, P would be the max or min of long. In the other cases, P will still be a long integer. Because of this, you should only need to use a long in the worst case scenario (since if your worse case expected outcome is that P is the largest possible number that any single number can be is a long.
To make sure you don't have to use anything larger, pair up negative values with postive ones so that you stay below the overflow of a long.
Imagine we have 3 numbers, a b and c. If a + b overflows the long datatype, we know that c will not be P.
Now imagine that we have 4 numbers, a, b, c, d such that a + b + c = d (meaning d is P), if a + b would overflow long, it means
1) c cannot be P
2) there is a combination of a + b + c such that the data type of long would not need to be overflowed.
For instance, a is max long, b is max long, c is min long, and d is 0, then a + c + b = d would be the correct combination of operations in order to not use a data type larger than long, and we can try a + c because we know c cannot be P since a + b would overflow long > maximum possible value of P.
Related
So I'm doing a practice Capture The Flag problem, The problem reads:
I was trying to implement RSA in C but I forgot the modulus. But I think this might be good enough already?
And then there is this code written in C attached to the question:
#include <stdio.h>
int main()
{
unsigned long long int flag1 = <redacted>;
flag1++;
unsigned long long int flag2 = <redacted>;
unsigned long long int ct1 = 1;
unsigned long long int ct2 = 1;
for (int i = 0; i<65537; i++)
{
ct1 = ct1 * flag1;
ct2 = ct2 * flag2;
}
printf("%llu\n",ct1);
printf("%llu\n",ct2);
}
/*OUTPUT:
7904812928421683021
16220282676865089917
*/
I want to get the flag, that is I want to find the values of flag1 and flag2 which outputted ct1(7904812928421683021) and ct2(16220282676865089917) after running in the program. Therefore I want to get the values of flag1 and flag 2 which is indicated by 'redacted' in the program.
I've done some research and found that 65537 is the public key exponent also in the question it states that they forgot the modulus. I've been sitting at this problem for hours now and still couldn't find anything particularly useful. I'm a beginner at cryptography so any help would be greatly appreciated.
If anyone of you could help it would mean a lot.
Thank you.
By appearances, unsigned long long int is 64 bits in the C implementation being used, so the arithmetic is performed modulo 264.
The loop that multiplies by flag1 or flag2 65537 times computes flag165537 modulo 264 and flag265537 modulo 264. We are given the results 7904812928421683021 and 16220282676865089917. To find flag1 and flag2 prior to the loop, we want to compute the inverse function.
By a generalization of Fermat’s little theorem, a𝜑(n) ≡ 1 mod n, where 𝜑 is Euler’s totient function. This means that exponentiating modulo n by 𝜑(n) is the same as exponentiating modulo n by 0, which means that exponentiation modulo n works modulo 𝜑(n) in the exponent. In other words, ab ≡ ac mod n if b ≡ c mod 𝜑(n).
The way this is useful to us is that when we have ab mod n, if we can find a c such that bc ≡ 1 mod 𝜑(n), then we can compute (ab)c mod n = abc mod n = a1 mod n = a mod n.
The Wikipedia page for Euler’s totient function tells us 𝜑(n) = n•product(1−1/p for prime p|n). (That product is the multiplication of 1−1/p for each prime p that divides n.) Since our n is 264, the only prime that divides it is 2, for which 1−1/2 = ½, so 𝜑(264) = 264•½ = 263.
Then we need to find the c such that bc ≡ 1 mod 𝜑(n) for b = 65537 and 𝜑(n) = 263. This can be done with the extended Euclidean algorithm. However, since we only need to do it once, and the numbers involved are large enough to be awkward to do in common C implementations, we can simply ask Wolfram Alpha for 65537^-1 mod 2^64, for which it tells us 9,223,090,566,172,966,913.
Next, we need to be able to raise a number to the power of 9,223,090,566,172,966,913. As this would take too long to do by simple iterative multiplication, we can instead use the algorithm below:
#include <inttypes.h>
#include <stdint.h>
#include <stdio.h>
/* This routine computes x**e modulo 2^64 by multiplying a running product by
each x**p such that p is a power of two whose corresponding bit is set in
e. Thus, if e is 19, which is 10011 in binary, the powers of two
represented in it are 2^16, 2^1, and 2^0, so we multiply the running
product by x^(2^0), x^(2^1), and x^(2^16), yielding x^(2^0 + 2^1 + 2^16) =
x^19.
*/
static uint64_t pow_u64(uint64_t x, uint64_t e)
{
uint64_t y = 1; // Initialize running product to 1.
while (e) // Continue while bits remain in exponent.
{
if (e & 1) // If current bit is set, multiply by power of x.
y *= x;
x *= x; // Update to next x to a power-of-two.
e >>= 1; // Update e to move next bit into low position.
}
return y;
}
static void Do(uint64_t y)
{
uint64_t c = 9223090566172966913u;
printf("%" PRIu64 " ^ %" PRIu64 " = %" PRIu64 ".\n", y, c, pow_u64(y, c));
}
int main(void)
{
Do(7904812928421683021u);
Do(16220282676865089917u);
}
This produces the output:
7904812928421683021 ^ 9223090566172966913 = 7380380986431332173.
16220282676865089917 ^ 9223090566172966913 = 5716833052698820989.
from which we see the values of flag1 and flag2 before the loop are 7,380,380,986,431,332,173 and 5,716,833,052,698,820,989.
Since flag1 was incremented with ++ after it was initialized by <redacted>, we subtract 1 to get the initial value, 7,380,380,986,431,332,172. flag2 was directly initialized with 5,716,833,052,698,820,989.
Here is a code snippet:
unsigned int m,n,a;
long long int c,p=0,q=0;
scanf("%u%u%u",&m,&n,&a);
while(m>0){
m-=a;
p++;
}
while(n>0){
n-=a;
q++;
}
c=p*q;
printf("%lld",c);
The above code does not work for any input. That is, it seems like it has crashed,though I could not understand where I'm mistaken. I guess the part with %lld in the printf has problems. But Ido not know how to fix it. I'm using code blocks.
Some expected outputs for corresponding inputs are as follows:
Input: 6 6 4
Output: 4
Input: 1000000000 1000000000 1
Output: 1000000000000000000(10^18).
APPEND:
So, I'm giving the link of the main problem below. The logic of my code seemed correct to me.
https://codeforces.com/contest/1/problem/A
As it's been pointed out in comments/answers the problem is that m and n is unsigned so your loops can only stop if m and n are a multiple of a.
If you look at the input 6 6 4 (i.e. m=6 and a=4), you can see that m first will change like m = 6 - 4 which leads to m being 2. So in the next loop m will change like m = 2 - 4 which should be -2 but since m is unsigned it will wrap to a very high positive number (i.e. UINT_MAX-1) and the loop will continue. That's not what you want.
To fix it I'll suggest you drop the while loops and simply do:
unsigned int m,n,a;
long long unsigned int c,p=0,q=0;
scanf("%u%u%u",&m,&n,&a);
p = (m + a - 1)/a; // Replaces first while
q = (n + a - 1)/a; // Replaces second while
c=p*q;
printf("%lld",c);
One problem with this solution is that the sum (m + a - 1) may overflow (i.e. be greater than UINT_MAX) and therefore give wrong results. You can fix that by adding an overflow check before doing the sum.
Another way to protect against overflow could be:
p = 1; // Start with p=1 to handle m <= a
if (m > a)
{
m -= a; // Compensate for the p = 1 and at the same time
// ensure that overflow won't happen in the next line
p += (m + a - 1)/a;
}
This code can then be reduced to:
p = 1;
if (m > a)
{
p += (m - 1)/a;
}
while(m>0){
m-=a;
p++;
}
will run until m is equal to 0, since it cannot be negative because it is unsigned. So if m is 4 and a is 6, then m will underflow and get the maximum value that m can hold minus 2. You should change the input variables to signed.
4386427 shows how you can use math to remove the loops completely, but for the more general case, you can do like this:
while(m > a) {
m-=a;
p++;
}
// The above loop will run one iteration less
m-=a;
p++;
Of course, you need to do the same thing for the second loop.
Another thing, check return value of scanf:
if(scanf("%u%u%u",&m,&n,&a) != 3) {
/* Handle error */
}
Using an unsigned type isn't always the best choice to represent positive values, expecially when its modular behavior is not needed (and maybe forgotten, which leads to "unexpected" bugs). OP's use case requires an integral type capable of store a value of maximum 109, which is inside the range of a 32-bit signed integer (a long int to be sure).
As 4386427's answer shows, the while loops in OP's code may (and should) be avoided anyways, unless a "brute force" solution is somehow required (which is unlikely the case, given the origin of the question).
I'd use a function, though:
#include <stdio.h>
// Given 1 <= x, a <= 10^9
long long int min_n_of_tiles_to_pave_an_edge(long int x, long int a)
{
if ( x > a ) {
// Note that the calculation is performed with 'long' values and only after
// the result is casted to 'long long', when it is returned
return 1L + (x - 1L) / a;
}
else {
return 1LL;
}
}
int main(void)
{
// Given a maximum value of 10^9, a 32-bit int would be enough.
// A 'long int' (or 'long') is guaranteed to be capable of containing at
// least the [−2,147,483,647, +2,147,483,647] range.
long int m, n, a;
while ( scanf("%ld%ld%ld", &m, &n, &a) == 3 )
{
// The product of two long ints may be too big to fit inside a long.
// To be sure, performe the multiplication using a 'long long' type.
// Note that the factors are stored in the bigger type, not only the
// result.
long long int c = min_n_of_tiles_to_pave_an_edge(m, a)
* min_n_of_tiles_to_pave_an_edge(n, a);
printf("%lld\n",c);
}
}
I want to get the carry bit of adding two unsigned 64-bit integers in c.
I can use x86-64 asm if needed.
code:
#include <stdio.h>
typedef unsigned long long llu;
int main(void){
llu a = -1, b = -1;
int carry = /*carry of a+b*/;
llu res = a+b;
printf("a+b = %llu (because addition overflowed), carry bit = %d\n", res, carry);
return 0;
}
As #EugeneSh. observes, the carry is either 0 or 1. Moreover, given that a and b both have the same unsigned type, their sum is well defined even if the arithmetic result exceeds the range of their type. Moreover, the (C) result of the sum will be less than both a and b when overflow occurs, and greater otherwise, so we can use the fact that C relational operations evaluate to either 0 or 1 to express the carry bit as
carry = (a + b) < a;
That does not require any headers, nor does it depend on a specific upper bound, or even on a and b having the same type. As long as both have unsigned types, it reports correctly on whether the sum overflows the wider of their types or unsigned int (whichever is wider), which is the same as their sum setting the carry bit. As a bonus, it is expressed in terms of the sum itself, which I think makes it clear what's being tested.
Carry can be only 0 or 1. 1 if there was a wrapping-around and 0 otherwise.
The wrapping-around is happening in case a + b > ULONG_LONG_MAX is true . Note, this is in mathematical terms, not in terms of C, as if a + b is actually overflowing, then this will not work. Instead you want to rearrange it to be a > ULONG_LONG_MAX - b. So the value of carry will be:
carry = a > ULONG_LONG_MAX - b ? 1 : 0;
or any preferred style equivalent.
Don't forget to include limits.h.
I wrote some code to determine the nth Fibonacci number using the nice blog post given in the accepted answer to this question: Finding out nth fibonacci number for very large 'n'. I am doing this as a way of practising a more difficult recursion problem given on projecteuler but that is not really relevant. The method relies on changing the problem to a small linear algebra problem of the form
Fn = T^n F1
where F1 = (1 1)^t and Fn contains the nth and (n-1)th Fibonacci number. The term T^n can then be determined in O(log n) time. I implemented this succesfully and it seems to work fine. When I perform the matrix exponentiation I use %10000 so I get the last 4 digits only, which seems to work (I checked against some large Fibonacci numbers). However, I wanted to try to get more last digits by increasing the number 10000. This doesn't seem to work however. I no longer get the correct answer. Here is my code
#include<stdio.h>
#include<math.h>
#include<stdlib.h>
const unsigned long M = 10000;
unsigned long int * matProd(unsigned long int * A, unsigned long int * B){
unsigned long int * C;
C = malloc(4*sizeof(unsigned long int));
C[0] = ((A[0]*B[0]%M) + (A[1]*B[2]%M)) % M;
C[1] = ((A[0]*B[1]%M) + (A[1]*B[3]%M)) % M;
C[2] = ((A[2]*B[0]%M) + (A[3]*B[2]%M)) % M;
C[3] = ((A[2]*B[1]%M) + (A[3]*B[3]%M)) % M;
return C;
}
unsigned long int * matExp(unsigned long int *A, unsigned long int n){
if (n==1){
return A;
}
if (n%2==0){
return matExp(matProd(A,A),n/2);
}
return matProd(A,matExp(A,n-1));
}
unsigned long int findFib(unsigned long int n){
unsigned long int A[4] = {0, 1, 1, 1};
unsigned long int * C;
C = malloc(4*sizeof(unsigned long int));
C = matExp(A,n-2);
return (C[2]+C[3]);
}
main(){
unsigned long int n = 300;
printf("%ld\n",findFib(n));
}
There are probably several issues there with regards to proper coding conventions and things that can be improved. I thought changing to long int might solve the problem but this does not seem to do the trick. So basically the problem is that increasing M to for instance 1000000 does not give me more digits but instead gives me nonsense. What mistake am I making?
P.S. sorry for the poor math formatting, I am used to math.stackexchange.
The issue is probably that you are running on a system where long is 32-bits in size, as I believe is the case for Windows. You can check this by compiling and running printf("%d\n", sizeof(long)) which should output 4.
Since with M=1000000=10^6, the product of two numbers smaller than M can go up to 10^12, you get overflow issues when you are computing your matrix entries since unsigned long can hold up to at most 2^32-1 or roughly 4 * 10^9.
To fix this simply using unsigned long long as your type instead of unsigned long. Or better yet, uint64_t, which is guaranteed to be 64-bits in all platforms (and which will require #include <stdint.h>). This should make your code work for M up to sqrt(2^64)~10^9. If you need bigger than that you'll need to use a big integer library.
If the program works for M == 10000 but fails for M == 1000000 (or even for M == 100000) then that probably means that your C implementation's unsigned long int type is 32 bits wide.
If your matrix elements are drawn exclusively from Z10000, then they require at most 14 significant binary digits. The products you compute in your matrix multiplication function, before reducing modulo M, may therefore require up to 28 binary digits. If you increase M even to 100000, however, then the matrix elements require up to 17 binary digits, and the intermediate products require up to 34. The reduction modulo M is too late to prevent that overflowing a 32-bit integer and therefore giving you garbage results.
You could consider declaring the element type as uint64_t instead. If it's an overflow problem then that should give you enough extra digits to handle M == 1000000.
I was looking at another question (here) where someone was looking for a way to get the square root of a 64 bit integer in x86 assembly.
This turns out to be very simple. The solution is to convert to a floating point number, calculate the sqrt and then convert back.
I need to do something very similar in C however when I look into equivalents I'm getting a little stuck. I can only find a sqrt function which takes in doubles. Doubles do not have the precision to store large 64bit integers without introducing significant rounding error.
Is there a common math library that I can use which has a long double sqrt function?
There is no need for long double; the square root can be calculated with double (if it is IEEE-754 64-bit binary). The rounding error in converting a 64-bit integer to double is nearly irrelevant in this problem.
The rounding error is at most one part in 253. This causes an error in the square root of at most one part in 254. The sqrt itself has a rounding error of less than one part in 253, due to rounding the mathematical result to the double format. The sum of these errors is tiny; the largest possible square root of a 64-bit integer (rounded to 53 bits) is 232, so an error of three parts in 254 is less than .00000072.
For a uint64_t x, consider sqrt(x). We know this value is within .00000072 of the exact square root of x, but we do not know its direction. If we adjust it to sqrt(x) - 0x1p-20, then we know we have a value that is less than, but very close to, the square root of x.
Then this code calculates the square root of x, truncated to an integer, provided the operations conform to IEEE 754:
uint64_t y = sqrt(x) - 0x1p-20;
if (2*y < x - y*y)
++y;
(2*y < x - y*y is equivalent to (y+1)*(y+1) <= x except that it avoids wrapping the 64-bit integer if y+1 is 232.)
Function sqrtl(), taking a long double, is part of C99.
Note that your compilation platform does not have to implement long double as 80-bit extended-precision. It is only required to be as wide as double, and Visual Studio implements is as a plain double. GCC and Clang do compile long double to 80-bit extended-precision on Intel processors.
Yes, the standard library has sqrtl() (since C99).
If you only want to calculate sqrt for integers, using divide and conquer should find the result in max 32 iterations:
uint64_t mysqrt (uint64_t a)
{
uint64_t min=0;
//uint64_t max=1<<32;
uint64_t max=((uint64_t) 1) << 32; //chux' bugfix
while(1)
{
if (max <= 1 + min)
return min;
uint64_t sqt = min + (max - min)/2;
uint64_t sq = sqt*sqt;
if (sq == a)
return sqt;
if (sq > a)
max = sqt;
else
min = sqt;
}
Debugging is left as exercise for the reader.
Here we collect several observations in order to arrive to a solution:
In standard C >= 1999, it is garanted that non-netative integers have a representation in bits as one would expected for any base-2 number.
----> Hence, we can trust in bit manipulation of this type of numbers.
If x is a unsigned integer type, tnen x >> 1 == x / 2 and x << 1 == x * 2.
(!) But: It is very probable that bit operations shall be done faster than their arithmetical counterparts.
sqrt(x) is mathematically equivalent to exp(log(x)/2.0).
If we consider truncated logarithms and base-2 exponential for integers, we could obtain a fair estimate: IntExp2( IntLog2(x) / 2) "==" IntSqrtDn(x), where "=" is informal notation meaning almost equatl to (in the sense of a good approximation).
If we write IntExp2( IntLog2(x) / 2 + 1) "==" IntSqrtUp(x), we obtain an "above" approximation for the integer square root.
The approximations obtained in (4.) and (5.) are a little rough (they enclose the true value of sqrt(x) between two consecutive powers of 2), but they could be a very well starting point for any algorithm that searchs for the square roor of x.
The Newton algorithm for square root could be work well for integers, if we have a good first approximation to the real solution.
http://en.wikipedia.org/wiki/Integer_square_root
The final algorithm needs some mathematical comprobations to be plenty sure that always work properly, but I will not do it right now... I will show you the final program, instead:
#include <stdio.h> /* For printf()... */
#include <stdint.h> /* For uintmax_t... */
#include <math.h> /* For sqrt() .... */
int IntLog2(uintmax_t n) {
if (n == 0) return -1; /* Error */
int L;
for (L = 0; n >>= 1; L++)
;
return L; /* It takes < 64 steps for long long */
}
uintmax_t IntExp2(int n) {
if (n < 0)
return 0; /* Error */
uintmax_t E;
for (E = 1; n-- > 0; E <<= 1)
;
return E; /* It takes < 64 steps for long long */
}
uintmax_t IntSqrtDn(uintmax_t n) { return IntExp2(IntLog2(n) / 2); }
uintmax_t IntSqrtUp(uintmax_t n) { return IntExp2(IntLog2(n) / 2 + 1); }
int main(void) {
uintmax_t N = 947612934; /* Try here your number! */
uintmax_t sqrtn = IntSqrtDn(N), /* 1st approx. to sqrt(N) by below */
sqrtn0 = IntSqrtUp(N); /* 1st approx. to sqrt(N) by above */
/* The following means while( abs(sqrt-sqrt0) > 1) { stuff... } */
/* However, we take care of subtractions on unsigned arithmetic, just in case... */
while ( (sqrtn > sqrtn0 + 1) || (sqrtn0 > sqrtn+1) )
sqrtn0 = sqrtn, sqrtn = (sqrtn0 + N/sqrtn0) / 2; /* Newton iteration */
printf("N==%llu, sqrt(N)==%g, IntSqrtDn(N)==%llu, IntSqrtUp(N)==%llu, sqrtn==%llu, sqrtn*sqrtn==%llu\n\n",
N, sqrt(N), IntSqrtDn(N), IntSqrtUp(N), sqrtn, sqrtn*sqrtn);
return 0;
}
The last value stored in sqrtn is the integer square root of N.
The last line of the program just shows all the values, with comprobation purposes.
So, you can try different values of Nand see what happens.
If we add a counter inside the while-loop, we'll see that no more than a few iterations happen.
Remark: It is necessary to verify that the condition abs(sqrtn-sqrtn0)<=1 is always achieved when working in the integer-number setting. If not, we shall have to fix the algorithm.
Remark2: In the initialization sentences, observe that sqrtn0 == sqrtn * 2 == sqrtn << 1. This avoids us some calculations.
// sqrt_i64 returns the integer square root of v.
int64_t sqrt_i64(int64_t v) {
uint64_t q = 0, b = 1, r = v;
for( b <<= 62; b > 0 && b > r; b >>= 2);
while( b > 0 ) {
uint64_t t = q + b;
q >>= 1;
if( r >= t ) {
r -= t;
q += b;
}
b >>= 2;
}
return q;
}
The for loop may be optimized by using the clz machine code instruction.