Ok so I have never taken a C programming course and I have a general idea of what Arrays are, but I cant seem to figure out why this array has a certain output.
#include <stdio.h>
#include <time.h>
#include <stdlib.h> // include srand function
#pragma warning(disable : 4996)
#define Size 15
main() {
int a[Size];
int i;
double b1[Size], b2[Size];
srand( (unsigned)time( NULL ) ); // Use current time as seed
// apply (start) timestamp
for (i = 0; i < Size; i++)
{
a[i] = rand() % 100;
// initialize the array using random number between 0 and 99
b1[i] = a[i]/5;
printf("a[%d] = %d\n", i, a[i]);
printf("b1[%d] = %f\n", i, b1[i]);
b2[i] = a[i];
b2[i] = b2[i]/5;
printf("b2[%d] = %f\n", i, b2[i]);
}
// apply (end) timestamp
//compute the time elapsed and display time in seconds
}
For my homework I need to run this code and explain why b1 and b2 have same or different values. I cant seem to wrap my head around what is happening here:
for (i = 0; i < Size; i++)
{
a[i] = rand() % 100;
// initialize the array using random number between 0 and 99
b1[i] = a[i]/5;
printf("a[%d] = %d\n", i, a[i]);
printf("b1[%d] = %f\n", i, b1[i]);
b2[i] = a[i];
b2[i] = b2[i]/5;
printf("b2[%d] = %f\n", i, b2[i]);
}
If someone could explain what the code is doing here I would very much appreciate it.
Thanks!
Edit- This is the output once I run the program:
a[0] = 8
b1[0] = 1.000000
b2[0] = 1.600000
a[1] = 74
b1[1] = 14.000000
b2[1] = 14.800000
a[2] = 78
b1[2] = 15.000000
b2[2] = 15.600000
a[3] = 64
b1[3] = 12.000000
b2[3] = 12.800000
a[4] = 53
b1[4] = 10.000000
b2[4] = 10.600000
a[5] = 6
b1[5] = 1.000000
b2[5] = 1.200000
a[6] = 71
b1[6] = 14.000000
b2[6] = 14.200000
a[7] = 4
b1[7] = 0.000000
b2[7] = 0.800000
a[8] = 7
b1[8] = 1.000000
b2[8] = 1.400000
a[9] = 57
b1[9] = 11.000000
b2[9] = 11.400000
a[10] = 55
b1[10] = 11.000000
b2[10] = 11.000000
a[11] = 13
b1[11] = 2.000000
b2[11] = 2.600000
a[12] = 55
b1[12] = 11.000000
b2[12] = 11.000000
a[13] = 96
b1[13] = 19.000000
b2[13] = 19.200000
a[14] = 25
b1[14] = 5.000000
b2[14] = 5.000000
Because you implicitly convert int to double and both times do that different ways.
b1[i] = a[i] / 5 ;
/* ^ ^ int ^
* | +-- int
* +-- implicit convertion to double */
b2[i] = b2[i] / 5 ;
/* ^ double ^
* + int implicitly converted
* to double */
In first expression you divide int by int where you lose precision (i.e. 7 / 2 gives you 3, not 3.5),
In second expression you divide double by double. That doesn't lead to that.
Related
I am learning c and encountered maximum cost path question in which
Rules:
matrix is n x n size
Starting from the cell (bottommost leftmost cell), you want to go to the topmost
rightmost cell in a sequence of steps. In each step, you can go either right or up from
your current location.
I tried to solve using dynamic programming and this is the function I have written
computecost(int *utr,int n)//utr is the input matrix
{
int *str;
int i,j;
str=(int *)malloc(n*n*sizeof(int));
for(j=0;j<n;j++)//intialization of bottom row
{
str[n*(n-1)+j]=utr[n*(n-1)+j];
}
for(i=n-2;i>=0;i--)
{
for(j=0;j<n;j++)
{
str[n*i+j]=utr[n*i+j]+max(str[n*(i+1)+j],str[n*(i+1)+(j+1)]);
}
}
printf("%d",str[n*0+0]);
return 0;
}
and this is the input
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
scanf("%d",&str[n*i+j]);
}
}
but
for the matrix 5 x5
1 4 8 2 9
32 67 18 42 1
4 86 12 7 1
8 4 12 17 44
1 43 11 45 2
the desired output is 272 but I am getting 211.
the output matrix for my case
1 43 11 45 2
51 47 57 62 46
55 143 74 69 47
175 210 92 111 52
211 214 119 113 64
Can anyone help me?
You don't need dynamic programming for this since there are no overlapping sub-problems. Just use a simple recursion.
const int n = 5;
int mat[n][n] = {
{1,4,8,2,9},
{32,67,18,42,1},
{4,86,12,7,1},
{8,4,12,17,44},
{1,43,11,45,2}
}; // input matrix
int f(int x, int y, int sum){
if(x == 0 && y == 4)
return sum;
int p = 0, q = 0;
if(x - 1 >= 0)
p = f(x-1, y, sum + mat[x-1][y]);
if(y + 1 <= 4)
q = f(x, y+1, sum+mat[x][y+1]);
return max(p,q);
}
int main(){
int maxSum = f(4,0, mat[4][0]);
printf("%d\n", maxSum);
}
You were not very far to succeed.
In practice, you did not initialize correctly the bottom row.
Moreover, there was a little mistake in the iteration calculation.
This is the corrected code.
As said in a comment, it could be further simplified, by avoiding the use of a new array, simply updating the input array.
#include <stdio.h>
#include <stdlib.h>
int max (int a, int b) {
return (a > b) ? a : b;
}
int computecost(int *utr,int n) { //utr is the input matrix
int *str;
str = malloc (n*n*sizeof(int));
str[n*n - 1] = utr[n*n - 1];
for (int j = n-2; j >= 0; j--) { //intialization of bottom row {
str[n*(n-1)+j] = utr[n*(n-1)+j] + str[n*(n-1)+j+1]; // corrected
}
for (int i=n-2; i>=0; i--) {
str[n*i+n-1] = utr[n*i+n-1] + str[n*(i+1)+n-1];
for(int j = n-2; j >= 0; j--) {
str[n*i+j] = utr[n*i+j] + max(str[n*(i+1)+j],str[n*i + j+1]); // corrected
}
}
int cost = str[0];
free (str);
return cost;
}
int main() {
int A[25] = {
1,43,11,45,2,
8,4,12,17,44,
4,86,12,7,1,
32,67,18,42,1,
1,4,8,2,9
};
int ans = computecost (A, 5);
printf ("%d\n", ans);
return 0;
}
I am trying to continuously send array of 6 floats over MQTT protocol. I was sending them as ASCII characters using sprintf function. I decided to send them as raw bytes. I put these floats into a union to represent them as unsigned char. The problem is when any of these floats is integer value, their byte representation becomes null after the position of integer.
union {
float array[6];
unsigned char bytes[6 * sizeof(float)];
} floatAsBytes;
If all of floatAsBytes.array consist float values, there is no problem at all.
If I say floatAsBytes.array[0] = 0, floatAsBytes.bytes becomes null.
If I say floatAsBytes.array[3] = 4, I can see first 8 bytes however this time last 16 bytes becomes null.
Minimal example of my client side C-code
#define QOS 0
#define TIMEOUT 1000L
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <limits.h>
#include "MQTTClient.h"
union bitFloat{
float f[6];
unsigned char s[6*sizeof(float)];
};
void publish(MQTTClient client, char* topic, char* payload) {
MQTTClient_message pubmsg = MQTTClient_message_initializer;
pubmsg.payload = payload;
pubmsg.payloadlen = strlen(pubmsg.payload);
pubmsg.qos = QOS;
pubmsg.retained = 0;
MQTTClient_deliveryToken token;
MQTTClient_publishMessage(client, topic, &pubmsg, &token);
MQTTClient_waitForCompletion(client, token, TIMEOUT);
}
int main(){
MQTTClient client;
MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer;
MQTTClient_message pubmsg = MQTTClient_message_initializer;
MQTTClient_deliveryToken token;
int rc;
MQTTClient_create(&client, "MQTTADDRESS:MQTTPORT", "TestClient",
MQTTCLIENT_PERSISTENCE_NONE, NULL);
conn_opts.keepAliveInterval = 20;
conn_opts.cleansession = 1;
if ((rc = MQTTClient_connect(client, &conn_opts)) != MQTTCLIENT_SUCCESS)
{
printf("Failed to connect, return code %d\n", rc);
exit(-1);
}
int i;
while(1){
union bitFloat payload;
payload.f[0] = 4.53; payload.f[1] = 2.39; payload.f[2] = 28.96; payload.f[3] = -1.83; payload.f[4] = -27.0; payload.f[5] = 9.32;
publish(client, "MyTestTopic", payload.s);
sleep(1);
}
return 0;
}
Python script to receive messages and display them
# !/usr/bin/env python
import struct
import numpy as np
import paho.mqtt.client as mqtt
def on_message(client, userdata, message):
test1 = struct.unpack('<f', message.payload[0:4])[0]
test2 = struct.unpack('<f', message.payload[4:8])[0]
test3 = struct.unpack('<f', message.payload[8:12])[0]
test4 = struct.unpack('<f', message.payload[12:16])[0]
test5 = struct.unpack('<f', message.payload[16:20])[0]
test6 = struct.unpack('<f', message.payload[20:24])[0]
print(test1, test2, test3, test4, test5, test6)
client = mqtt.Client()
client.on_message = on_message
client.connect("MQTTADDRESS", MQTTPORT)
client.subscribe("MyTestTopic")
client.loop_forever()
This line
pubmsg.payloadlen = strlen(pubmsg.payload);
is wrong. You are using strlen on something that isn't a string. Due to use of strlen the length will be wrong as strlen only count til it sees a byte that are zero.
Example:
Consider payload.f[0] = 1;. The binary representation of 1.0 is 3f800000
On little endian systems this will be saved as 00 00 80 3f so using strlen will result in 0.
On big endian systems this will be saved as 3f 80 00 00 so using strlen will result in 2.
In other words - strlen is the wrong function.
You probably need
pubmsg.payloadlen = 6 * sizeof(float);
The code works as expected.
Here is a Minimal Complete Verifiable Example. I am guessing that you are doing something right this. When you provide your own code, it may show that I have misunderstood your question:
#include <stdio.h>
int main()
{
union {
float array[6];
unsigned char bytes[6 * sizeof(float)];
} floatAsBytes;
// load up array with some date
for(int i = 0; i < 6; i++) {
floatAsBytes.array[i] = 1.99 + i;
}
puts("\nfirst run:");
floatAsBytes.array[0] = 0;
// dump array
for(int i = 0; i< 6; i++) {
printf("float #%d: %f\n", i, floatAsBytes.array[i]);
}
// dump bytes
for(int i = 0; i < sizeof(float)*6; i++) {
if(i % sizeof(float) == 0)
printf("\n");
printf(" %2x",floatAsBytes.bytes[i]);
}
// second example
puts("\nSecond run:");
floatAsBytes.array[3] = 4;
// dump array
for(int i = 0; i< 6; i++) {
printf("float #%d: %f\n", i, floatAsBytes.array[i]);
}
// dump bytes
for(int i = 0; i < sizeof(float)*6; i++) {
if(i % sizeof(float) == 0)
printf("\n");
printf(" %2x",floatAsBytes.bytes[i]);
}
return 0;
}
Here is the output:
first run:
float #0: 0.000000
float #1: 2.990000
float #2: 3.990000
float #3: 4.990000
float #4: 5.990000
float #5: 6.990000
0 0 0 0
29 5c 3f 40
29 5c 7f 40
14 ae 9f 40
14 ae bf 40
14 ae df 40
Second run:
float #0: 0.000000
float #1: 2.990000
float #2: 3.990000
float #3: 4.000000
float #4: 5.990000
float #5: 6.990000
0 0 0 0
29 5c 3f 40
29 5c 7f 40
0 0 80 40
14 ae bf 40
14 ae df 40
Process finished with exit code 0
I am not seeing the behavior that you are describing. The code works as expected.
Trace the execution of the following program? What will be the final values of array be printed?
I have to trace the following C code and write the output. I ran the program and the output is different than what I expected. Most likely I traced it incorrectly but I can't find what I am doing wrong.
*I didn't write the code. The code was included in the question.
#include <stdio.h>
#include <math.h>
int main()
{
int a[7]={2,0,0,0,0,0,0};
int i=1;
for (i=1; i<7; i++)
{
if (i<3)
a[i] = a[i-1]+i+1; //when i=1, a[1]= a[1-1]+1+1 -> a[0]+1+1 -> 2+1+1=4
//a[1] is now 4
//when i=2, a[2]= a[2-1]+1+1 -> a[1]+1+1 -> 4+2+1=7
//a[2] is now 7
else if (i<5)
a[i] = a[i-2]+1; //when i=3, a[3]= a[3-2]+1 -> a[1]+1 -> 4+1=6
//a[3] is now 6 but it should be 11??? 11
//when i=4, a[4]= a[4-1]+1 -> a[2]+1 -> 7+1=8
//a[4] is now 8 but it should be 16??? 16
else
a[i] = a[i-2]*i-2; //when i=5, a[5]= a[5-2]*5-2 -> a[3]*3 -> 6*3= 18
//a[5] is now 18 but it should be 22???
//when i=6, a[6]= a[6-1]*6-2 -> a[5]*4 -> 18*4= 72
//a[6] is now 8 but it should be 29????
}
for (i=0; i<7; i++)
printf("a[%d] = %d\n",i,a[i]); //prints a[0] = 2 first because i=0 in the above loop
}
Actual Output:
a[0] = 2
a[1] = 4
a[2] = 7
a[3] = 11
a[4] = 16
a[5] = 22
a[6] = 29
I copied your code and ran it, this is my output:
a[0] = 2
a[1] = 4
a[2] = 7
a[3] = 5
a[4] = 8
a[5] = 23
a[6] = 46
I've tried to solve problem 2 on Project Euler in C. This is the first possible solution that came to my mind, and, in fact, it gives as an output the right answer. The problem is that each time I run my program it gives me a different output, which is either "2" or "4613732" that is the right answer. Sorry for my poor english, can you help me find out what's wrong?
#include <stdio.h>
int main(){
int n, n1 = 1, n2 = 2, sum = 2;
while(n<4000000){
n = n1 + n2; /*calculate the next number of the series*/
n1 = n2;
n2 = n;
if(n%2 == 0){
sum = sum + n; /*if the number it's even add it to the main sum*/
}
}
printf("The sum is %d\n", sum);
}
You didn't initialize n; when you get the right answer, it means you got lucky.
#include <conio.h>
#include <iostream>
using namespace std;
int evenFibSum(int i=1,int j=2)
{
const int max = 3999999;
int eventsum = 2;
int sum = 0;
while (sum < max)
{
sum = i + j;
i = j;
j = sum;
if (sum % 2 == 0)
eventsum +=sum;
}
return eventsum;
}
For more efficient solution apply following logic
Fibbonaci Series => 1 2 3 5 8 13 21 34 55 89 144
Index => 0 1 2 3 4 5 6 7 8 9 10
To get even fibbonanci addition I have to add following index values[1 4 7 10]
Here I am sensing some pattern
[1 4 7 10] => I need advance index by 3
so how to advance index by 3
// k = i+j = > 3 13 55
// i = k+j => 5 21 89
// j = k+i => 8 34 144
int evenFibSumx(int i=1,int j=2)
{
const int max = 3999999;
int eventsum = 2;
int k= 0;
while (1)
{
k = i + j;
i = k + j;
j = k + i;
if(i >= max)
break;
if (j%2 == 0)
eventsum +=j;
}
return eventsum;
}
int main()
{
std::cout << evenFibSum();
std::cout << evenFibSumx();
}
Apologies for posting a badly formed question prior to this attempt.
I'm trying to get a Gauss Seidel method to work in C, to check how much quicker it is than higher level interpreted languages (i.e python), but I'm having some issues with the results that I'm obtaining.
My input matrix is
Symmetric Positive-Definitive
& Diagonally dominant
so I believe it should converge.
The problem attempts to solve "Ax=b" ,
(Where 'A' = 'a[ ][ ]' ,'b' = 'b[ ]', and 'x'= 'x[ ]')
The final array 'check [ ]' is obtained via a dot product between 'a' and 'x' to see if it returns something close to 'b'.
The below code is fully executable.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main(void)
{
int i=0,j=0;
int num=0;
double h = 1.0/(3+1);
double h2 = pow(h,2);
double w=1.5, sum=0.0;
long double x[9],y[9], check[9];
long double tol = pow(10, -10);
long double a[9][9] = {{-4, 1, 0, 1, 0, 0, 0, 0, 0} ,
{1, -4, 1, 0, 1, 0, 0, 0, 0} ,
{0, 1, -4, 0, 0, 1, 0, 0, 0} ,
{1, 0, 0, -4, 1, 0, 1, 0, 0} ,
{0, 1, 0, 1, -4, 1, 0, 1, 0} ,
{0, 0, 1, 0, 1, -4, 0, 0, 1} ,
{0, 0, 0, 1, 0, 0, -4, 1, 0} ,
{0, 0, 0, 0, 1, 0, 1, -4, 1} ,
{0, 0, 0, 0, 0, 1, 0, 1, -4}};
long double b[9] = {0.000000,
0.000000,
0.000000,
0.000000,
0.125000,
0.000000,
0.000000,
0.000000,
0.000000 };
for(i=0;i<9;i++){ // initialise the arrays to 0
x[i]=0;
y[i]=2*tol;
}
for(i=0;i<9;i++){ // prints 'a' matrix, to check if its right
for(j=0;j<9;j++){
printf("a[%d][%d] = %LF ",i,j,a[i][j]);
}
printf("\n" );
}
printf("\n\n");
for(i=0;i<9;i++){ // prints b matrix
printf("b[%d] = %LF \n",i,b[i]);
}
do{ // the Gauss seidel Solver
for(i =0;i<9;i++){
for(j=0; j<9; j++){
if(i!=j){
sum += a[i][j]*x[j];
}
x[i] = (w/a[i][i])* (b[i] - sum + a[i][i]*x[i]) + (1-w)*x[i];
}
}
num=num+1;
}while (fabs(y[i]-x[i])>tol);
printf("\n\n\n");
for(i=0;i<9;i++){ // Prints the solution X
printf("x[%d] = %LF \n",i,x[i]);
}
printf("\n\n");
for(i=0;i<9;i++){ // Ititialises matrix
check[i]=0;
}
for (i = 0; i < 9; i++){ // performs a dot product of
// 'a' and 'x', to see if we get
// 'b' as the result
for(j = 0; j< 9; j++){
check[i]+= a[i][j] * x[j];
}
check[i] = check[i]/h2; // the 'b' matrix was multiplied by h2,
// hence to get it back, a division is necessary
printf("check[%d] = %LF\n",i,check[i]);
}
printf("num=%d\n",num );
return 0;
}
The output i.e 'x' that I get is:
x[0] = -0.000000
x[1] = -0.000000
x[2] = -0.000000
x[3] = -0.000000
x[4] = -0.421875
x[5] = -0.791016
x[6] = -1.423828
x[7] = -3.816650
x[8] = -11.702087
and the output for 'Check' I get is:
check[0] = 0.000000
check[1] = -4.500000
check[2] = -5.625000
check[3] = -14.625000
check[4] = -10.968750
check[5] = -42.328125
check[6] = 17.156250
check[7] = 18.421875
check[8] = 212.343750
Ideally, if everything works, check[4] should output 2 (the reason for which is given in a comment in the code when outputting 'check'), and every other element of check should be 0.
Any suggestions?
sum should be reinitialized to 0 inside the for-loop before starting the next row and the equation is incorrect. The equation you are using from the python implementation assumes that a[i][i]*x[i] was added to make the full dot-product, they used numpy to get the dot product instead of looping so they had no opportunity to do i != j. Also I'm not sure the equation in that implementation is the Gauss Seidel method, it looks more like Successive Over Relaxation because of the w and (1 - w). Anyway, here is my modified solution. I check for convergence using the error, |Ax - b| < tol for all entries. The for-loop is split into two as a small optimization. a[i][i] * x[i] is added to sum to get the current value for (Ax)i in the error check.
int converged;
do {
converged = 1;
for (i = 0; i < 9; i++) {
sum = 0;
for (j = 0; j < i; j++) {
sum += a[i][j] * x[j];
}
for (j = i + 1; j < 9; j++) {
sum += a[i][j] * x[j];
}
x[i] += w * ((b[i] - sum) / a[i][i] - x[i]);
if (fabs(sum + a[i][i] * x[i] - b[i]) > tol) {
converged = 0;
}
}
} while (!converged);
which gives the output:
x[0] = -0.007812
x[1] = -0.015625
x[2] = -0.007812
x[3] = -0.015625
x[4] = -0.046875
x[5] = -0.015625
x[6] = -0.007812
x[7] = -0.015625
x[8] = -0.007813
check[0] = 0.000000
check[1] = -0.000000
check[2] = -0.000000
check[3] = -0.000000
check[4] = 2.000000
check[5] = 0.000000
check[6] = -0.000000
check[7] = 0.000000
check[8] = 0.000000
num=31
For the benefit of those following along at home. I suggest reading with the wikipedia article on Gauss-Seigel. I will attempt to explain what the algorithm is doing, and provide C code that implements the algorithm.
The Python example in the wikipedia page uses this simple example for matrix A and B
| 10 -1 2 0 | | 6 |
A = | -1 11 -1 3 | B = | 25 |
| 2 -1 10 -1 | | -11 |
| 0 3 -1 8 | | 8 |
Those matrices represent the following system of equations
10*x1 - x2 + 2*x3 = 6
-x1 + 11*x2 - x3 + 3*x4 = 25
2*x1 - x2 + 10*x3 - x4 = -11
3*x2 - x3 + 8*x4 = 15
The solution that we're trying to find with Gauss-Seigel is
x1=1 x2=2 x3= -1 x4=1
So how does the algorithm work? Well first take a wild a guess at the answer, e.g.
x1=0 x2=0 x3=0 x4=0
Then plug those guesses into the equations and try to improve the guesses. Specifically, plug the values for x2,x3,x4 into the first equation, and then compute a new value for x1.
10*x1 - 0 + 0 = 6 ==> x1 = 6/10 = 0.6
Then plug the new value of x1, and the old values of x3,x4 into the second equation to get an improved guess for x2
-0.6 + 11*x2 - 0 + 0 = 25 ==> 11*x2 = 25.6 ==> x2 = 2.327273
And for x3 and x4
2*0.6 - 2.327273 + 10*x3 - 0 = -11 ==> 10*x3 = -9.872727 ==> x3 = -0.987273
3*2.327273 + 0.987273 + 8*x4 = 15 ==> 8*x4 = 7.030908 ==> x4 = 0.878864
So after one iteration of Gauss-Seigel, the improved guess at the answer is
x1=0.6 x2=2.327273 x3= -0.987273 x4=0.878864
The algorithm continues until either the solution converges or the maximum number of iterations is exceeded.
Here's what the code looks like in C. The counter k limits the number of iterations (just in case the solution doesn't converge). The Gauss-Seidel method is applied by evaluating each of the equations while skipping X[i]. Then the new value for X[i] is computed. The code displays the new values of X[], and the checks if the answer is good enough by evaluating each equation and verifying that the sum is within epsilon of B[i].
#include <stdio.h>
#include <math.h>
#define SIZE 4
double A[SIZE][SIZE] = {
{ 10, -1, 2, 0 },
{ -1, 11, -1, 3 },
{ 2, -1, 10, -1 },
{ 0, 3, -1, 8 }
};
double B[SIZE] = { 6, 25, -11, 15 };
double X[SIZE] = { 0, 0, 0, 0 };
int main( void )
{
int i, j, k, done;
double sum;
done = 0;
for ( k = 0; k < 100 && !done; k++ )
{
// perform the next iteration of Gauss-Seidel
for ( i = 0; i < SIZE; i++ )
{
sum = 0;
for ( j = 0; j < SIZE; j++ )
if ( j != i )
sum += A[i][j] * X[j];
X[i] = (B[i] - sum) / A[i][i];
}
// print the k'th iteration of X[]
printf( "%2d --", k );
for ( i = 0; i < SIZE; i++ )
printf( " %lf", X[i] );
printf( "\n" );
// check for convergence
done = 1;
for ( i = 0; i < SIZE; i++ )
{
sum = 0;
for ( j = 0; j < SIZE; j++ )
sum += A[i][j] * X[j];
if ( fabs( B[i] - sum ) > 1e-6 )
{
done = 0;
break;
}
}
}
}