Pascal's Triangle program not working - c

I'm very new to C, although I've done a decent amount of Java before. I'm making a basic Pascal's Triangle program and I've been looking at it for an hour trying to get it working. All the logic seems correct to me but I'll probably die before I realize what's wrong. Here's the program:
#include <stdio.h>
#include <stdlib.h>
double fact(int num);
int main()
{
int row_index = 0;
printf("Enter the row index : ");
scanf("%d",&row_index);
printf("\n");
int i;
double output1 = 0;
double output2 = 0;
double output3 = 0;
double output4 = 0;
double output5 = 0;
int output6 = 0;
for(i = 0; i <= (row_index + 1); i++)
{
output1 = fact(row_index);
output2 = fact(i);
output3 = row_index - i;
output4 = fact(output3);
output5 = output1 / (output2 * output4);
output6 = (int)(output5);
printf("%i ",output6);
}
return 0;
}
double fact(int num)
{
double result;
int i;
for(i = 1; i <= num; ++i)
{
result = result * i;
}
return result;
}
The compiler is giving me no errors, and each every time I input a number it gives this as output:
Enter the row index : 6
-2147483648 -2147483648 -2147483648 -2147483648 -2147483648 -2147483648 -2147483648 -2147483648

In double fact(int num), the variable result should be explicitly initialized. Also, I would suggest you to define both the return value of the function and variable result to int type.
See (Why) is using an uninitialized variable undefined behavior?.

At a glance, there seems to be several issues.
First:
double fact(int num)
{
double result;
int i;
for(i = 1; i <= num; ++i)
{
result = result * i;
}
return result;
}
result is not initialized to anything. Maybe you need to initialize it to 1?
for(i = 0; i <= (row_index + 1); i++)
{
output2 = fact(i);
output3 = row_index - i;
output4 = fact(output3);
output5 = output1 / (output2 * output4);
}
the first time around, i == 0; which means output2 at best will be 0 (assuming its automatically initialized to 0). If output2 == 0, output5 might be undefined. I say might because of double-precision numbers it may actually not be exactly 0.

Related

Why are only the first 2 outputs correct in my binary to decimal converter programm?

I have to program a converter which takes the strings from numbers[] and outputs them as decimals.
I am looping through size and index to then add up the current index to the power of its position and then sum it all up. Like: 101 = 1^2 + 0^1 + 1^0
So I am currently stuck with this:
#include <stdio.h>
#include <math.h> // Kompilieren mit -lm : gcc -Wall -std=c11 dateiname.c -lm
int main() {
char* numbers[] = {
"01001001",
"00101010",
"010100111001",
"011111110100101010010111",
"0001010110011010101111101111010101110110",
"01011100110000001101"};
// Add here..
int strlen(char *str){
int len=0;
for(;str[len]!='\0';len++){}
return len;
}
int sum = 0;
int length = sizeof(numbers) / sizeof(numbers[0]);
for( int i = 0; i < length; i++ ){
int size = strlen(numbers[i]);
for (int j = 0; j < size; j++) {
if(numbers[i][j] == '1'){
sum += 1 * pow(2,j-1);
}else{
sum += 0 * pow(2,j-1);
}
}
printf("%s to the base of 2 \nequals %d to the base of 10 \n\n",numbers[i], sum);
sum = 0;
}
return 0;
}
The output of the first two loops is correct which is 01001001 = 73 and 00101010 = 42. But, as soon the length get bigger, my output is completely wrong; e.g. 010100111001 = 1253 instead of 1337 and 011111110100101010010111 = 7645567 instead of 8342167.
There are a number of issues with your code. First and foremost, as pointed out in the comments, you are processing your binary digits from left-to-right, whereas you should be doing that right-to-left.
Second, declaring a function inside another one (as you have done for your strlen) is not Standard C (though some compilers may allow it). If you really can't use the standard strlen function (provided in <string.h>), then move your definition to outside (and before) the body of main.
Third, you shouldn't be using the pow function (which takes and returns double values) for integer arithmetic. Just use a running int variable and multiply that by two each time the inner for loop runs.
Fourth, your "0001010110011010101111101111010101110110" value will overflow the int type on most machines (assuming that is 32 bits), so try using long long int (most likely 64 bits) where necessary.
Finally, there's no point in adding 0 * x to anything, whatever x is, so you can do away with the else block.
Here's a working version (using the standard strlen):
#include <stdio.h>
#include <string.h> // For "strlen" - we don't need math.h if we don't use "pow".
int main(void) // For strict compliance, you should add the "void" argument list
{
char* numbers[] = {
"01001001",
"00101010",
"010100111001",
"011111110100101010010111",
"0001010110011010101111101111010101110110",
"01011100110000001101" };
long long int sum = 0; // So we can use more than 32 bits!
size_t length = sizeof(numbers) / sizeof(numbers[0]);
for (size_t i = 0; i < length; i++) {
int size = (int)strlen(numbers[i]); // strlen gives a "size_t" type
long long int p = 1;
for (int j = size-1; j >= 0; j--) { // Start at the END of the string and work backwards!
if (numbers[i][j] == '1') {
sum += p;
}
// No point in adding zero times anything!
p *= 2; // Times by two each time through the loop
}
printf("%s to the base of 2 \nequals %lld to the base of 10 \n\n", numbers[i], sum);
sum = 0;
}
return 0;
}
sizeof(); // it will give you the size of datatype (in bytes), not the length of a string.
You have to use string function instead.
length = strlen(numbers[0]);
Your function is quite bad, complicated and uses pow. You do not need to know the length of the string.
It can be done much easier:
unsigned long long bstrtoint(const char *str)
{
unsigned long long result = 0;
while(*str)
{
result *= 2;
result += *str++ == '1';
}
return result;
}
or for any base (lower than number of digits)
//bad digits considered as zeroes
static const char digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUWXYZ";
unsigned long long strtoint(const char *str, unsigned base)
{
unsigned long long result = 0;
char *ppos;
while(*str)
{
result *= base;
result += (ppos = strchr(digits, toupper(*str++))) ? (ppos - digits < base) ? ppos - digits : 0 : 0;
}
return result;
}
Examples:
printf("%llu\n", bstrtoint("1111000011110000"));
printf("%llu\n", strtoint("0001010110011010101111101111010101110110", 2));
printf("%llu\n", strtoint("1dr45Xvy4", 36)); // base 36 number
https://godbolt.org/z/bsG5rfTsb
If you want to use your program layout and do it correctly:
int main(void) // For strict compliance, you should add the "void" argument list
{
char* numbers[] = {
"01001001",
"00101010",
"010100111001",
"011111110100101010010111",
"0001010110011010101111101111010101110110",
"01011100110000001101" };
unsigned long long sum = 0;
size_t length = sizeof(numbers) / sizeof(numbers[0]);
for (size_t i = 0; i < length; i++)
{
size_t size = strlen(numbers[i]); // strlen gives a "size_t" type
sum = 0;
for (size_t j = 0; j < size; j++)
{
sum *= 2;
if (numbers[i][j] == '1')
{
sum += 1;
}
}
printf("%s to the base of 2 \nequals %llu to the base of 10 \n\n", numbers[i], sum);
}
return 0;
}
but you do not have to integrate your string twice - strlen is not needed at all
int main(void) // For strict compliance, you should add the "void" argument list
{
char* numbers[] = {
"01001001",
"00101010",
"010100111001",
"011111110100101010010111",
"0001010110011010101111101111010101110110",
"01011100110000001101" };
unsigned long long sum = 0;
size_t length = sizeof(numbers) / sizeof(numbers[0]);
for (size_t i = 0; i < length; i++)
{
sum = 0;
for (size_t j = 0; numbers[i][j] != 0; j++)
{
sum *= 2;
if (numbers[i][j] == '1')
{
sum += 1;
}
}
printf("%s to the base of 2 \nequals %llu to the base of 10 \n\n", numbers[i], sum);
}
return 0;
}

Printf outputting a bunch of zeros

I'm new to C, so I apologize if the answer to this is painfully obvious! I mean to loop through two 2D arrays, passing correspondingly indexed members as arguments to my chineseRemainder routine, i.e. for each iteration, array1[i] and array2[i] should be passed to the routine, where i = i. I am expecting the output of a call to printf to be a certain set of numbers -- instead I am getting all zeros. Here is the main routine, where I call the CR function. **edit I gave xp and xq arbitrary int values, since they do not seem to be the problem, and giving them such values gives the same output.
int main(){
int xp, xq, p = 61, q = 3;
int i, j;
reverseInteger();
for(i = 0; i < 32; ++i){
for(j = 0; j < 10; ++j){
xq = 4;
xp = 1;
printf("%i\n", chineseRemainder(xq, xp, p, q));
}
}
return 0;
}
For troubleshooting's sake, I dumped the contents of xq and xp to make sure those assignments were going through: they are. The problem must be with the CR routine, because it is printing zero even when I pass any set of integers to it. So, here is that function, and its dependencies:
float power(int base, int exp) {
int i;
float result = 1;
if (exp == 0)
result = 1;
else if (exp == 1)
result = base;
else if(exp > 1){
for (i = 0; i < exp; ++i)
result *= base;
}
else
result = 1/power(base, -exp);
return result;
}
float powerMod(int q, int e, int p){
float result;
result = (int)power(q, e) % p;
return result;
}
typedef struct arrayInside{
int array[30][10];
} arrayInside;
arrayInside codesInside;
struct arrayInside reverseInteger(){
int i, j, number;
for(i = 0; i < 30; ++i){
j = 10;
number = (aryConversion(q3[i], 3));
do {
codesInside.array[i][j-1] = number % 10;
--j;
number = number / 10;
}
while (number);
codesInside.array[i][0] = 0;
};
return codesInside;
}
int chineseRemainder(int xq, int xp, int p, int q){
int tp;
int ceiling = (p*q-1)/2;
tp = ((int)(q * (powerMod(q, -1, p))*xp + p * powerMod(p, -1, q) * xq) % (p*q));
if(tp > ceiling)
tp-=p*q;
return tp;
}
Your chineseRemainder actually returns 0 every time. Look at this -
((int)(q * (powerMod(q, -1, p))*xp + p * powerMod(p, -1, q) * xq) % (p*q));
powerMod(q, -1, p) is zero. So multiplying and adding it also going to give zero. Your function actually returns zero. There is nothing wrong. You probably need to check the logic or change the data types.

Homework-Subscripted value is neither array nor pointer nor vector

I am copying a program whose purpose is to generate and bubble sort a list of random numbers. This is the code:
#include <stdio.h>
#define MAX 10
int a;
int rand_seed=10;
int rand()
{
rand_seed = rand_seed * 1103515245 + 12345;
return (unsigned int)(rand_seed / 65536) % 32768;
}
void main()
{
int i,t,x,y;
//fill array
for (i = 0; i < MAX;i++)
{
a = rand();
printf("%d\n",a);
}
/* bubble sort the array */
for (x = 0; x < MAX-1; x++)
for (y = 0; y < MAX -x - 1; y++)
if (a > a[y+1]) {
t = a;
a = a[y+1];
a[y+1] = t;
}
printf("----------------\n");
for( i = 0; i < MAX;i++)
printf("%d\n",a);
}
I know it's offensive to post the whole thing here but I don't know where the problem is.
I believe your compiler already had the offensive line pointed out. In the code
if (a > a[y+1])
you're trying to use a as an array, while it was defined as an int, earlier
int a;
If you want a to be an array, you have to define it as an array, and populate each member using rand() or similar.
I am pretty sure you wanted a to be an array. In that case try this out:
int a[10];
for (i = 0; i < MAX;i++) {
a[i] = rand();
printf("%d\n",a[i]);
}
And also this part would be changed into:
if (a[y] > a[y+1]) {
t = a[y];
a[y] = a[y+1];
a[y+1] = t;
}

learning the basics of C programming which can clear my doubts on arrays and strings

I am new to C so this question may seem a bit stupid :P .
I have an array arr[] which stores numbers from 100 to 999.
Now, I have to take each element of the array and subtract the subsequent digits.
For example if I have a number in that array as 1234 then I need another array that stores 1,2,3,4 distinctly so that I can perform 1-2= -1, 2-3 =-1, 3-4= -1.
So if I change a data like 1234 to char through typecasting then how to store this char into an array and then break it into 1,2,3,4 so that I can call it in a for loop by arr[i].
#include <stdio.h>
#include<string.h>
int main()
{
int t,n,w;
int mod = 1000007;
scanf("%d",&t);
while(t--)
{
scanf("%d %d",&n,&w);
int start = 1;
int end = 10;
int i,j,z;
for(i=0;i<=n-2;i++)
{
start = start*10;
end = end*100;
}
end--;
char arr[10000];
for(i= start;i<=end;i++)
{
scanf("%c",&arr[i]);
}
int len = strlen(arr);
int count = 0;
int Value=0;
for(i=0;i<len;i++)
{
char b[10000];
b[0] = arr[i] + '0';
char arr2[10000];
int g = strlen(b);
for(j=0;j<g;j++)
{
strncpy(arr2, b + j, j+1);
}
int k = strlen(arr2);
for(z=0;z<k;z++)
{
int u = arr2[z] - '0';
int V = arr2[z+1] - '0';
if(u>V)
{
Value = Value + (u-V);
}
else
{
Value = Value + (V-u);
}
}
if (Value == w)
{
count++;
}
}
int ans = count % mod;
printf("%d",ans);
}
return 0;
}
Actually its a question from codechef.com called weight of numbers in the easy section of the practice problems
you can split number by digits in this way
int num = 123;
int digits[3];
for (int i = 2; i >= 0; i--)
{
digits[i] = num % 10;
num /= 10;
}
Also if you'll cast num to char that wouldn't help you. You'll just get some character if you try to print it. Nothing more will change.

All Integers have the same value

So I am working on some homework, in which I have to create a global array of 500 random integers between 0 and 99. Then, I have to count how many are greater than 75, and how many are less than 50.
Here is my code:
#include <stdlib.h>
#include <stdio.h>
static int ARRAY[500];
static char str[1];
void main() {
int i = 0;
for (i = 0; i < 500; i++) {
int r = rand() % 99;
ARRAY[i] = r;
}
int gt75 = count75();
int lt50 = count50();
printf("%d\n", str, gt75);
printf("%d\n", str, lt50);
}
int count75() {
int i = 0, counter = 0;
for (i = 0; i < 500; i++) {
int n = ARRAY[i];
if (n > 75) {
counter += 1;
}
}
return counter;
}
int count50() {
int i = 0, counter = 0;
for (i = 0; i < 500; i ++) {
int n = ARRAY[i];
if (n < 50) {
counter += 1;
}
}
return counter;
}
However, after compiling and running my program, I get the following output:
4225008
4225008
This can't be right, as the list should only have 500 elements in the first place. What am I doing wrong?
You have two errors.
First, int r = rand() % 99; should be int r = rand() % 100; Otherwise you just get numbers between 0 and 98.
Second, your printf statements are odd. They should be:
printf("Greater than 75: %d\n", gt75);
printf("Less than 50: %d\n", lt50);
In the current printf statements, the str is cast to an int, which is interpreting the str pointer as an int, thus your strange output.
You're printing a char array with printf using "%d", which is for printing integers. Use "%s" for printing char arrays:
printf("%s\n", str, gt75);
Or, if you're trying to print the value of gt75 as an integer:
printf("%d\n", gt75);
I do not know why you would pass str in this case, though.
When you use "%d", you are telling printf to interpret the input as an int. Since str is actually a char array, it does not output correctly. Instead, you're printing the memory location of str, which is the value of an array.
You are always printing the value of str, which is not an int.

Resources