I get different outputs when i use different compilers - c

I was trying to solve a problem with using C. But I got different outputs in different compilers. First I tried gcc and there was no mistake but when I use clang the output changed.
PROBLEM:
Given five positive integers, find the minimum and maximum values that can be calculated by summing exactly four of the five integers. Then print the respective minimum and maximum values as a single line of two space-separated long integers.
Sample Input: 1 2 3 4 5
Sample Output: 10 14
10 = 1 + 2 + 3 + 4 | 14 = 2 + 3 + + 4 + 5
The Output when I use clang: 1 14
Here is the code:
#include <stdio.h>
void miniMaxSum(int *a, int b) {
int sums[5] = { b, b, b, b, b };
int min = *a, max = *a;
for (int j = 0; j < 5; j++) {
sums[j] -= *(a + j);
if (sums[j] < min)
min = sums[j];
if (toplamlar[j] > max)
max = sums[j];
}
printf("%d %d\n", min, max);
}
int main() {
int numbers[5] = { 0, 0, 0, 0, 0 };
int sum;
for (int i = 0; i < 5; i++) {
scanf("%d ", &numbers[i]);
toplam += numbers[i];
}
miniMaxSum(numbers, sum);
return 0;
}
EDIT: Sorry, I changed the variables name to English sake of understanding, but I forgot the toplam (sum) and toplamlar (sums).

Assuming you translated some of the variable names to English for non Turkish speakers, the variable sum (toplam) is uninitialized leading to undefined behavor. A common symptom for undefined behavior is different behavior on a different system / compiler.
Note that you can simplify your code by just searching for the minimum and maximum values in the array:
#include <stdio.h>
void miniMaxSum(const int *a, int sum) {
int min = a[0], max = a[0];
for (int j = 1; j < 5; j++) {
if (sums[j] < min)
min = sums[j];
if (sums[j] > max)
max = sums[j];
}
printf("%d %d\n", sum - max, sum - min);
}
int main() {
int numbers[5] = { 0, 0, 0, 0, 0 };
int sum = 0;
for (int i = 0; i < 5; i++) {
scanf("%d ", &numbers[i]);
sum += numbers[i];
}
miniMaxSum(numbers, sum);
return 0;
}

Related

multiplying number from 1 to N while adding 2 every time

I have to write a C program that multiplies numbers from 1 to N.
N is scanned. Before multiplication, I have to increase each number by 2.
For example: N = 3 => (1+2)(2+2)(3+2) = 60
I have to only use while loop and print and scan function.
Example program:
Enter the value of N: 4
The result of multiplication: 360
This is my code and I am not sure what is wrong with this. Please help.
#include <stdio.h>
int N;
int count=1, ii, result;
printf("Enter the value of N:");
scanf("%d", &N);
while (count<=N)
{
count ii = count + 2;
ii = ii * ii ; //three
count++;
}
result = ii;
printf("The result of multiplication: %d", result);
return 0;
}
If you're looking for that series as a sum:
const int N = 3;
int c = 1;
for (int i = 1; i <= N; ++i) {
c *= (i + 2);
}
Or in a more C-esque form:
const int N = 3;
int c = 1;
for (int i = 0; i < N; ++i) {
c *= (i + 1 + 2);
}
int main()
{
int N;
int count=1, ii = 1, result;
printf("Enter the value of N:");
scanf("%d", &N);
while (count<=N)
{
ii = ii * ( count + 2 };
count++;
}
result = ii;
printf("The result of multiplication: %d", result);
return 0;
}

Converting array to 8-bit codes in c

I have an array of 200 elements. I want to divide this array into 25 parts and find the RMS values ​​of these parts and print 0 if it is less than 20, 1 if it is greater.
Example
signal1[200]
Output
data[8]={0,1,0,0,1,0,1,1)
I find code for RMS calculation
#include <stdio.h>
#include <math.h>
double rms(double* v, int n)
{
int i;
double sum = 0.0;
for (i = 0; i < n; i++)
sum += v[i] * v[i];
return sqrt(sum / n);
}
int main(void)
{
double v[] = {3,-3,7,1,-3,9,8,1,3,2,-6,-4,-1,-6,7,-6,-6,-7,-6,-1,-4,9,-1,-7,9,48,-6,-39,-24,-9,10,-24,10,21,-28,-
39,-21,-18,-8,1,-42,-24,30,-48,43,23,-1,8,-27,-4,47,5,2,-27,-1,13,18,-11,-13,49,-47,39,42,30,-41,-24,-17,18,-
37,22,-40,16,-1,28,22,41,39,-17,20,-31,-47,25,0,-2,41,11,12,36,31,8,-32,-26,39,-48,-1,-34,48,21,0,-3,-9,4,-10,-
9,0,-8,7,7,5,-7,3,0,10,3,6,-1,-1,7,-9,-8,-7,-2,7,6,-9,-10,3,-8,16,13,-21,-7,-49,49,-34,-40,-13,-30,-1,-16,46,42,-
45,24,-23,-8,5,45,-8,49,-20,20,17,4,20,17,-33,-38,50,-33,-47,6,39,17,-31,-13,-4,49,-35,36,15,-12,-31,-7,-2,-
8,2,-6,-2,2,-5,-4,2,-5,7,10,5,-3,2,-8,9,8,7,-5,2,-10,-2,-4,-7,-7};
printf("%f\n", rms(v, sizeof(v) / sizeof(double)));
return 0;
}
can you help me please ?
Simply call the function rms with 25 elements at a time:
int main(void)
{
double v[] = {3,-3,7,1,-3,9,8,1,3,2,-6,-4,-1,-6,7,-6,-6,-7,-6,-1,-4,9,-1,-7,9,48,-6,-39,-24,-9,10,-24,10,21,-28,-
39,-21,-18,-8,1,-42,-24,30,-48,43,23,-1,8,-27,-4,47,5,2,-27,-1,13,18,-11,-13,49,-47,39,42,30,-41,-24,-17,18,-
37,22,-40,16,-1,28,22,41,39,-17,20,-31,-47,25,0,-2,41,11,12,36,31,8,-32,-26,39,-48,-1,-34,48,21,0,-3,-9,4,-10,-
9,0,-8,7,7,5,-7,3,0,10,3,6,-1,-1,7,-9,-8,-7,-2,7,6,-9,-10,3,-8,16,13,-21,-7,-49,49,-34,-40,-13,-30,-1,-16,46,42,-
45,24,-23,-8,5,45,-8,49,-20,20,17,4,20,17,-33,-38,50,-33,-47,6,39,17,-31,-13,-4,49,-35,36,15,-12,-31,-7,-2,-
8,2,-6,-2,2,-5,-4,2,-5,7,10,5,-3,2,-8,9,8,7,-5,2,-10,-2,-4,-7,-7};
int data[8], i;
for (i = 0; i < 8; i++) {
data[i] = rms(v + 25 * i, 25) > 20.0;
}
for (i = 0; i < 8; i++) {
printf(" %d", data[i]);
}
putchar('\n');
return 0;
}
The expression v + i gives you the address of the i:th element of v.

for loop unexpectedly jumping down in value

Goldbach's conjecture states that every even integer over 4 is the sum of two primes, I am writing a program in C to find these pairs. To do this it first finds all the primes less than a user given number. I have a for loop to iterate from 4 to the user given number and find the pairs within the loop body. When that loop gets to about around 40, suddenly jumps back down by about 30 and then continues to iterate up (with user input 50 it jumped from 38 to 9, with input 60 it jumped from 42 to 7). I can't figure out why this is happening. Here is my code:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <sys/types.h>
#include <unistd.h>
struct pair{
int a;
int b;
}pair_t;
int main(){
int N;
int numPrimes = 1;
int *primes = malloc(100*sizeof(int));
int isPrime = 1;
primes[0] = 2;
int timesRealloc = 0;
int availableSlots = 100;
printf("Please enter the largest even number you want to find the Goldbach pair for: \n");
scanf("%d", &N);
struct pair pairs[N/2 + 4];
int j = 0;
int i;
for (i = 3; i <= N; i+=2){
j = 0;
isPrime = 1;
while (primes[j] <= sqrt(i)) {
if (i%primes[j] == 0) {
isPrime = 0;
break;
}
j++;
}
if (isPrime == 1){
primes[numPrimes] = i;
numPrimes++;
}
if (availableSlots == numPrimes){
timesRealloc++;
availableSlots += 100;
primes = realloc(primes, availableSlots*sizeof(int));
}
}
printf("The largest prime I found was %d\n", primes[(numPrimes-1)]);
int k;
for (i=4; i<=N; i+=2){
printf("i is %d, N is %d\n", i, N);
if (i > N){ break; }
for (j=0; j<numPrimes; j++){
for (k=0; k<numPrimes; k++){
int sum = primes[j] + primes[k];
if(sum == i){
pairs[i].a = primes[j];
pairs[i].b = primes[k];
}
}
}
}
for (i=4; i<=N; i+=2){
printf("%d is the sum of %d and %d\n", i, pairs[i].a, pairs[i].b);
}
return 0;
}
You attempt to be space efficient by compressing the pairs array to just hold every other (even) number and start from 4 instead of zero. However, you miscalculate its size and then when you go to use it, you treat it like it hasn't been compressed and that there's a slot for every natural number.
The code suffers from having the prime array calculation in main() along with the other code, this is best separated out. And when it looks for pairs, it doesn't quit when it finds one, nor when it starts getting sums greater than the target. My rework below attempts to address all of these issues:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <stdbool.h>
#define INITIAL_SLOTS (100)
struct pair {
int a;
int b;
} pair_t;
int compute_primes(int limit, unsigned **primes, int size) {
int numPrimes = 0;
(*primes)[numPrimes++] = 2;
for (int i = 3; i <= limit; i += 2) {
bool isPrime = true;
for (int j = 0; (*primes)[j] <= i / (*primes)[j]; j++) {
if (i % (*primes)[j] == 0) {
isPrime = false;
break;
}
}
if (isPrime) {
(*primes)[numPrimes++] = i;
}
if (numPrimes == size) {
size *= 2;
*primes = realloc(*primes, size * sizeof(unsigned));
}
}
return numPrimes;
}
int main() {
int N;
printf("Please enter the largest even number you want to find the Goldbach pair for: \n");
scanf("%d", &N);
unsigned *primes = calloc(INITIAL_SLOTS, sizeof(unsigned));
int numPrimes = compute_primes(N, &primes, INITIAL_SLOTS);
printf("The largest prime I found was %d\n", primes[numPrimes - 1]);
struct pair pairs[(N - 4) / 2 + 1]; // compressed data structure
for (int i = 4; i <= N; i += 2) {
int offset = (i - 4) / 2; // compressed index
bool found = false;
for (int j = 0; ! found && j < numPrimes; j++) {
for (int k = 0; ! found && k < numPrimes; k++) {
int sum = primes[j] + primes[k];
if (sum == i) {
pairs[offset].a = primes[j];
pairs[offset].b = primes[k];
found = true;
} else if (sum > i) {
break;
}
}
}
}
for (int i = 4; i <= N; i += 2) {
int offset = (i - 4) / 2; // compressed index
printf("%d is the sum of %d and %d\n", i, pairs[offset].a, pairs[offset].b);
}
free(primes);
return 0;
}
OUTPUT
> ./a.out
Please enter the largest even number you want to find the Goldbach pair for:
10000
The largest prime I found was 9973
4 is the sum of 2 and 2
6 is the sum of 3 and 3
8 is the sum of 3 and 5
10 is the sum of 3 and 7
12 is the sum of 5 and 7
14 is the sum of 3 and 11
...
9990 is the sum of 17 and 9973
9992 is the sum of 19 and 9973
9994 is the sum of 53 and 9941
9996 is the sum of 23 and 9973
9998 is the sum of 31 and 9967
10000 is the sum of 59 and 9941
>

Adding common factors in C

I'm just trying to add all common factors of 3 and 5, stopping at a sum of 1000. I keep getting an expected expression on line 15:18. Is there anyone that can find any new errors or help? It would be much appreciated. Thanks.
#include<stdio.h>
#include<stdlib.h>
/*Multiples of 3 and 5
If we list all natural numbers below 10 that are multiples of 3 or 5, we get 3, 5, 6
and 9. The sum of these multiples is 23.
Find the sum of all the multiples of 3 or 5 below 1000.*/
int cd_function(int n, int sum)
{
if(sum >= 1000)
return 0;
if(n%3 == 0 || n%5 == 0)
sum + return cd_function(n, sum);
}
int main(void)
{
int i, iter, sum = 0;
for(i = 0; i < cd_function(iter, sum); i++)
sum++;
return 0;
}
#include<stdio.h>
#include<stdlib.h>
Most people will add a space here:
#include <stdio.h>
#include <stdlib.h>
.
int cd_function(int n, int sum)
{
if(sum >= 1000)
return 0;
if(n%3 == 0 || n%5 == 0)
sum + return cd_function(n, sum);
}
There is two ways, to have this functions add n to sum: Either by passing sum as pointer (reference), this would be done this way:
void cd_function(int n, int * sum) {
// if (*sum >= 1000) - no need to test this here
if (!n%3 || !n%5) {
*sum += stuff;
}
}
or by having the function return the new sum:
int cd_function(int n, int sum) {
// if (sum >= 1000) - no need to test this here
if (!n%3 || !n%5) {
return sum + stuff;
} else {
return sum;
}
}
Now, sum + return cd_function(n, sum); is wrong, YSC already told so in his comment. So you should either use *sum += n; or return sum + n; (i.e. replace stuff by n above).
int main(void)
{
int i, iter, sum = 0;
Since you don't need iter, get rid of it:
int i, sum = 0;
for(i = 0; i < cd_function(iter, sum); i++)
sum++;
a. If you want to sum some[tm] is, then you shouldn't increment sum in each iteration.
for (i = 0; i < cd_function(iter, sum); i++)
;
b. Then you should get a proper exit condition. You wanted to sum everything until you reach a sum >= 1000, so write that in the condition:
for (i = 0; sum < 1000; i++)
/* ??? i < cd_function(iter, sum) */;
c. Depending on the implementation of cd_function you choose from above, you would now either call
cd_function(i, &sum);
or
sum = cd_function(i, sum);
d. And finally, you should add curly brackets, even there is only one statement:
for (i = 0; sum < 1000; i++) {
// option 1
cd_function(i, &sum);
// option 2
sum = cd_function(i, sum);
}
rest is fine:
return 0;
}

Return the sub-array of the maximum sum

In the book "elements of programming interviews", I came across, the problem of returning the subarray of the maximum sum. I tried their solution and I don't think we need to keep track of the minimum sum to get the array of the maximum sum:
I wrote another version of it maximumSumMine where I removed the minSum and it worked fine, the output in the comments
What is the purpose of tracking minSum, do we really need it?
#include <stdio.h>
#include <limits.h>
typedef struct range {
int start;
int end;
int maxSum;
} range;
void print(int *a, int start, int end) {
for (int i = start; i <= end; i++) {
printf("%d ", a[i]);
}
printf("\n");
}
// Book's code as it is
range maximumSum(int *a, int n) {
range r;
r.start = 0; r.end = 0;
int minSum = 0, sum = 0, minIndex = -1, maxSum = INT_MIN;
for (int i = 0; i < n; i++) {
sum += a[i];
if (sum < minSum) {
minSum = sum;
minIndex = i;
}
if (sum - minSum > maxSum) {
maxSum = sum - minSum;
r.start = minIndex + 1;
r.end = i + 1;
}
}
return r;
}
range maximumSumMine(int *a, int n) {
range r;
r.start = 0; r.end = 0;
int sum = 0, minIndex = -1, maxSum = INT_MIN;
for (int i = 0; i < n; i++) {
sum += a[i];
if (sum < 0) {
sum = 0;
minIndex = i + 1;
}
if (sum > maxSum) {
maxSum = sum;
r.start = minIndex;
r.end = i;
}
}
return r;
}
void unitTests() {
// Example 1
int a[5] = {-2, 5, 1, -1, 4};
range r = maximumSum(a, 5);
print(a, r.start, r.end); // output 5 1 -1 4 0
// Example 2
int b[5] = {2, -5, 5, -1, 3};
r = maximumSum(b, 5);
print(b, r.start, r.end); // 5 -1 3 1
// Example 1
r = maximumSumMine(a, 5);
print(a, r.start, r.end); // output 5 1 -1 4
// Example 2
r = maximumSum(b, 5);
print(b, r.start, r.end); // 5 -1 3 1
}
int main() {
unitTests();
return 0;
}
You need the minimum sum because the algorithm involves computing prefix sums:
sums[i] = a[0] + a[1] + ... + a[i]
So for each i, the maximum sum you can get that ends at a[i] is sums[i] - min(sums[j < i]).
The book code implements this without actually using an array, as you can simply keep track of the minimum and the current prefix sum.
If you only take the max of the prefix sums under the conditions that you do, it will not work for negative maximum sums: you will always output 0 if the maximum sum is negative, because you will set your prefix sum to 0 when it becomes negative.
Sometimes, ignoring negative maximum sums can be perfectly fine, other times not. I've seen both versions given as programming assignments / questions.
Example:
a = {-1, -2, -3}
book output = -1
your output = 0

Resources