C calling a print function in main - c

I am really new to C and am writing a code that creates a struct with an array of employee information. As you can see in my code, there's employees (there's actually 4 but I cut it down to 1 here for space), and each employee has corresponding info. (Just FYI I left out some stuff in order to save space, like declaring the struct workerT).
I made another function (prntWorker) that should print all the employees and their information, but I don't know how what perimeters to use when I call it in main(). No matter what perimeters I use, CodeBlocks returns that there's too few arguments. I'm sorry I know this is a novice question, but I would greatly appreciate any help!
The goal is "given an array of workerT structs that holds siz elements, print all employee information found in the array element list[indx]
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_ROSTER 10 //roster of employees
typedef struct workerT_struct {
char name[81]; //employee name
char title[81]; //employee title
int empID; //unique ID for employee
int empStatus;
int year100_salary; //before-tax salary, in cents
int year100_401k; //annual contribution to retirement, in cents
double taxRate; //fraction used to determine payroll taxes
int month100_paycheck; //monthly paycheck, in cents
} workerT;
void initWorkerArray(workerT list[], int siz);
void prntWorker(workerT list[], int siz, int indx);
int main()
{
workerT roster[MAX_ROSTER];
prntWorker(roster, MAX_ROSTER, 0); //FIXME
return 0;
}
void initWorkerArray(workerT list[], int siz) {
int i = 0;
for (i = 0; i < 4; ++i) {
strcpy(list[0].name, "Buggy, Orson");
strcpy(list[0].title, "Director/President");
list[0].empID = 1;
list[0].empStatus = 1;
list[0].year100_salary = 12015000;
list[0].year100_401k = 950000;
list[0].taxRate = 0.45;
strcpy(list[1].name, "Czechs, Imelda");
strcpy(list[1].title, "Chief Financial Officer");
list[1].empID = 2;
list[1].empStatus = 1;
list[1].year100_salary = 8020000;
list[1].year100_401k = 960000;
list[1].taxRate = 0.39;
strcpy(list[2].name, "Hold, Levon");
strcpy(list[2].title, "Customer Service");
list[2].empID = 6;
list[2].empStatus = -1;
list[2].year100_salary = 8575000;
list[2].year100_401k = 1133000;
list[2].taxRate = 0.39;
strcpy(list[3].name, "Andropov, Picov");
strcpy(list[3].title, "Shipping Coordinator");
list[3].empID = 7;
list[3].empStatus = 1;
list[3].year100_salary = 4450000;
list[3].year100_401k = 375000;
list[3].taxRate = 0.31;
}
for (i = 4; i < siz; ++i) {
strcpy(list[i].name, "none");
strcpy(list[i].title, "none");
list[i].empID = -1;
list[i].empStatus = -1;
list[i].year100_salary = 0;
list[i].year100_401k = 0;
list[i].taxRate = 0.0;
}
return;
}
void prntWorker(workerT list[], int siz, int indx) {
int i = 0;
for (i = 0; i < siz; ++i) {
printf("%s ", list[indx].name);
printf("%s ", list[indx].title);
printf("%d ", list[indx].empID);
printf("%d ", list[indx].empStatus);
printf("%d ", list[indx].year100_salary);
printf("%d ", list[indx].year100_401k);
printf("%lf ", list[indx].taxRate);
printf("%d ", list[indx].month100_paycheck);
}
return;
}

Several issue here:
You never call initWorkerArray to initialize the array:
int main()
{
workerT roster[MAX_ROSTER];
initWorkerArray(roster, MAX_ROSTER); // add this call
prntWorker(roster, MAX_ROSTER, 0);
return 0;
}
Inside of initWorkerArray, the first for loop is not needed, as you're updating specific indexes in your array.
You never initialize month100_paycheck, either in the second for loop or for the initial fields, so this field contains garbage:
list[0].month100_paycheck = 0;
...
list[1].month100_paycheck = 0;
...
list[2].month100_paycheck = 0;
...
list[3].month100_paycheck = 0;
...
for (i = 4; i < siz; ++i) {
....
list[i].month100_paycheck = 0;
}
Then in prntWorker, you're not using the loop index i to iterate through the list. You're using the parameter indx instead, which you don't really need:
void prntWorker(workerT list[], int siz) {
int i = 0;
for (i = 0; i < siz; ++i) {
printf("%s ", list[i].name);
printf("%s ", list[i].title);
printf("%d ", list[i].empID);
printf("%d ", list[i].empStatus);
printf("%d ", list[i].year100_salary);
printf("%d ", list[i].year100_401k);
printf("%lf ", list[i].taxRate);
printf("%d ", list[i].month100_paycheck);
printf("\n"); // put a newline at the end for nicer formatting
}
return;
}
After changing this function, also change the call in main:
prntWorker(roster, MAX_ROSTER);
After making these changes, you should get the following output:
Buggy, Orson Director/President 1 1 12015000 950000 0.450000 0
Czechs, Imelda Chief Financial Officer 2 1 8020000 960000 0.390000 0
Hold, Levon Customer Service 6 -1 8575000 1133000 0.390000 0
Andropov, Picov Shipping Coordinator 7 1 4450000 375000 0.310000 0
none none -1 -1 0 0 0.000000 0
none none -1 -1 0 0 0.000000 0
none none -1 -1 0 0 0.000000 0
none none -1 -1 0 0 0.000000 0
none none -1 -1 0 0 0.000000 0
none none -1 -1 0 0 0.000000 0

Here is your tweaked code. Primarily I called initWorkerArray() from main(), but removed its loop that initialises the struct 4 times over. I also changed the loop control variable and added a newline in prntWorker() after printing each record. However the last field month100_paycheck is printing absurd values, because it has not been calculated.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_ROSTER 10 //roster of employees
typedef struct workerT_struct {
char name[81]; //employee name
char title[81]; //employee title
int empID; //unique ID for employee
int empStatus;
int year100_salary; //before-tax salary, in cents
int year100_401k; //annual contribution to retirement, in cents
double taxRate; //fraction used to determine payroll taxes
int month100_paycheck; //monthly paycheck, in cents
} workerT;
void initWorkerArray(workerT list[], int siz);
void prntWorker(workerT list[], int siz, int indx);
int main()
{
workerT roster[MAX_ROSTER];
initWorkerArray(roster, MAX_ROSTER);
prntWorker(roster, MAX_ROSTER, 0); //FIXME
return 0;
}
void initWorkerArray(workerT list[], int siz) {
int i = 0;
strcpy(list[0].name, "Buggy, Orson");
strcpy(list[0].title, "Director/President");
list[0].empID = 1;
list[0].empStatus = 1;
list[0].year100_salary = 12015000;
list[0].year100_401k = 950000;
list[0].taxRate = 0.45;
strcpy(list[1].name, "Czechs, Imelda");
strcpy(list[1].title, "Chief Financial Officer");
list[1].empID = 2;
list[1].empStatus = 1;
list[1].year100_salary = 8020000;
list[1].year100_401k = 960000;
list[1].taxRate = 0.39;
strcpy(list[2].name, "Hold, Levon");
strcpy(list[2].title, "Customer Service");
list[2].empID = 6;
list[2].empStatus = -1;
list[2].year100_salary = 8575000;
list[2].year100_401k = 1133000;
list[2].taxRate = 0.39;
strcpy(list[3].name, "Andropov, Picov");
strcpy(list[3].title, "Shipping Coordinator");
list[3].empID = 7;
list[3].empStatus = 1;
list[3].year100_salary = 4450000;
list[3].year100_401k = 375000;
list[3].taxRate = 0.31;
for (i = 4; i < siz; ++i) {
strcpy(list[i].name, "none");
strcpy(list[i].title, "none");
list[i].empID = -1;
list[i].empStatus = -1;
list[i].year100_salary = 0;
list[i].year100_401k = 0;
list[i].taxRate = 0.0;
}
return;
}
void prntWorker(workerT list[], int siz, int indx) {
int i = 0;
for (i = 0; i < siz; ++i) {
printf("%s ", list[i].name);
printf("%s ", list[i].title);
printf("%d ", list[i].empID);
printf("%d ", list[i].empStatus);
printf("%d ", list[i].year100_salary);
printf("%d ", list[i].year100_401k);
printf("%lf ", list[i].taxRate);
printf("%d ", list[i].month100_paycheck);
printf("\n");
}
return;
}
Program output:
Buggy, Orson Director/President 1 1 12015000 950000 0.450000 0
Czechs, Imelda Chief Financial Officer 2 1 8020000 960000 0.390000 1636580
Hold, Levon Customer Service 6 -1 8575000 1133000 0.390000 40370720
Andropov, Picov Shipping Coordinator 7 1 4450000 375000 0.310000 -2
none none -1 -1 0 0 0.000000 50397953
none none -1 -1 0 0 0.000000 2047
none none -1 -1 0 0 0.000000 -1
none none -1 -1 0 0 0.000000 5505360
none none -1 -1 0 0 0.000000 43441
none none -1 -1 0 0 0.000000 4222855

Related

How is my ring buffer adding an additional element?

I have a ring buffer example code that I'm practicing and for some odd reason, it adds an extra element with no apparent reason.
The behavior I am coding is that it drops incoming data if buffer is full.
Here is the code:
#include <stdio.h>
#include <stdint.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdbool.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
typedef struct {
void *buf;
ssize_t ri; //read index
ssize_t wi; //write index
ssize_t capacity; // total size of buffer in bytes
size_t max_count;
size_t count;
ssize_t sz; // size of individual elements in bytes
bool full;
} r_buffer_t;
r_buffer_t* ring_buffer_init(unsigned int count, ssize_t dsize) {
r_buffer_t *buffer = malloc(sizeof(r_buffer_t));
if(buffer != NULL){
buffer->buf = malloc(count * sizeof(dsize));
if(buffer->buf != NULL) {
buffer->max_count = count;
buffer->sz = dsize;
buffer->count = 0;
buffer->ri = 0;
buffer->wi = 0;
buffer->capacity = count * dsize;
buffer->full = false;
return buffer;
}
free(buffer);
}
return NULL;
}
int put_item(r_buffer_t *buffer, void *data) {
assert(buffer && data); // exception catch on stderr;
if(!buffer->full) {
printf("\nw-memcpy");
memcpy((buffer->buf + (buffer->wi * buffer->sz)), data, sizeof(buffer->sz));
printf("\n\t\tret\tdata\tcount\tfull\twi");
//printf("\n-------------------------------------------------\n");
printf("\nAdding data :\t%d\t%d\t%ld\t%d\t%ld", 0, *((int*)data), buffer->count, buffer->full, buffer->wi);
buffer->count++;
buffer->wi++;
buffer->wi %= buffer->max_count;
//if((buffer->wi == buffer->ri) && (buffer->count >= (buffer->max_count))) {
if(buffer->count >= buffer->max_count) {
printf("\n>>>Full for count = %ld, buffer-full = %d, index ri = %ld, wi=%ld",
buffer->count, buffer->full, buffer->ri, buffer->wi);
buffer->full = true;
}
return 0;
}
printf("\n>>>Dropping data. Buffer Full for count = %ld, buffer-full = %d, index ri = %ld, wi=%ld",
buffer->count, buffer->full, buffer->ri, buffer->wi);
//printf("\n%d\t%d\t%ld\t%d", -1, *((int *)data), buffer->count, buffer->full);
return -1;
}
int get_item(r_buffer_t *buffer, void *data) {
assert(buffer && data);
if(buffer->count > 0) {
printf("r-memcpy");
memcpy(data, (buffer->buf + (buffer->ri * buffer->sz)), buffer->sz);
memset((buffer->buf + (buffer->ri * buffer->sz)), 0, buffer->sz);
//printf("\n%d\t%d\t%ld\t%d\t%ld", 0, *((int*)data), buffer->count, buffer->full, buffer->ri);
buffer->count--;
buffer->ri++;
buffer->ri %= buffer->max_count;
buffer->full = (buffer->count >= buffer->max_count);
return 0;
}
//printf("\n%d\t%d\t%ld\t%d\t%ld", -1, *((int*)data), buffer->count, buffer->full, buffer->ri);
return -1;
}
void print_buffer(r_buffer_t *buffer) {
int i = 0;
printf("\n*************Buffer***********\n");
printf("\ncount = %ld, full = %d, ri = %ld, wi = %ld",
buffer->count, buffer->full, buffer->ri, buffer->wi);
printf("\n\t");
for(i =0; i < buffer->max_count; i++){
if(buffer->ri == i)
printf("R ");
else
printf(" ");
}
printf("\n\t");
for(i =0; i < buffer->max_count; i++)
printf("%d |", *(int *)(buffer->buf + i * buffer->sz));
printf("\n\t");
for(i =0; i < buffer->max_count; i++){
if(buffer->wi == i)
printf("W ");
else
printf(" ");
}
printf("\n*********************************\n");
}
int main() {
int i = 0;
int d1[] = {1,2,3,4,5,6,7,8,9,10};
int rd = 0;
int ret = 0;
r_buffer_t *buf = ring_buffer_init(5, sizeof(unsigned int));
print_buffer(buf);
printf("\nAdding 4 items to buffer");
for(i = 0; i < 4; i++) {
printf("\nCalling put for %d", d1[i]);
ret = put_item(buf, (void *)&d1[i]);
}
print_buffer(buf);
printf("\nRemoving and printing 2");
for(i = 0; i < 2; i++){
get_item(buf, &rd);
}
print_buffer(buf);
printf("\nAdding 4 more items to buffer");
for(i = 4; i < 9; i++) {
ret = put_item(buf, &d1[i]);
}
print_buffer(buf);
return 0;
}
The output makes no sense:
*************Buffer***********
count = 0, full = 0, ri = 0, wi = 0
R
0 |0 |0 |0 |0 |
W
*********************************
Adding 4 items to buffer
Calling put for 1
w-memcpy
ret data count full wi
Adding data : 0 1 0 0 0
Calling put for 2
w-memcpy
ret data count full wi
Adding data : 0 2 1 0 1
Calling put for 3
w-memcpy
ret data count full wi
Adding data : 0 3 2 0 2
Calling put for 4
w-memcpy
ret data count full wi
Adding data : 0 4 3 0 3
*************Buffer***********
count = 4, full = 0, ri = 0, wi = 4
R
1 |2 |3 |4 |5 |
W
*********************************
How is there an extra '5' in the buffer ?
memcpy((buffer->buf + (buffer->wi * buffer->sz)), data, sizeof(buffer->sz));
The above line in put_item() would copy a number of sizeof(buffer->sz) bytes from data to (buffer->buf + (buffer->wi * buffer->sz)).
The sizeof(buffer->sz) equals to sizeof(ssize_t) for the type of buffer->sz is ssize_t in type r_buffer_t.
In many system, ssize_t would be signed long while size_t would be unsigned long, and they would be double the sizeof(int) bytes in general. It is possible that the above code line actually copy double the sizeof(int) bytes from the source to destination, then at the fourth call to put_item() the fifth element in array d1[] would always be copied into the ring buffer.
You might want to change it as the following line.
memcpy((buffer->buf + (buffer->wi * buffer->sz)), data, buffer->sz);

write a c function, check if an int array only contains 1 and 2

Given an array of ints, return 1 if every element is a 1 or a 2, otherwise return 0;
only12([1,2,2]) -> 1
only12([1,4,2,4]) -> 0
only12([2,1]) -> 1
only12([1,2,12]) -> 0
only12([]) -> 1
only12(NULL) -> 0
prototype:
int only12(const int nums[]);
Any advice?
Thanks!
updated answer from HiEd :
The result is 1 even the array includes 3.
// answered by HiEd
#include <stdio.h>
int only12(const int nums[])
{
int size = sizeof(nums)/sizeof(nums[0]);
int i;
int result = 1;
for(i = 0; i < size; i++)
{
if(nums[i] != 1 && nums[i]!=2 )
{
result = 0;
}
}
//printf("%d",result);
return result;
}
int main()
{
const int nums[5]= {1,2,3,1,1};
int r = only12(nums);
printf("%d",r);
}
After reading Gerhardh's comment, I decided to give value for size in the function, then the program runs. but still did not get this part:
only12([]) -> 1
this is the code updated:
#include <stdio.h>
#include <stdlib.h>
int only12(const int nums[]);
int only12(const int nums[])
{
size_t i, size = 5;
int result = 1;
for(i = 0; i < size; i++)
{
if(nums[i] != 1 && nums[i] != 2 )
{
result = 0;
}
}
return result;
}
int main()
{
const int nums[5]= {1,2,2,1,3};
printf("%d", only12(nums));
return 0;
}
#include <stdio.h>
int only12(const int nums[], int size){
int i;
int result = 1;
for(i = 0; i < size; i++){
if(nums[i] != 1 && nums[i]!=2 ){
result = 0;
}
}
//printf("%d",result);
return result;
}
int main()
{
const int nums[5]= {1,2,3,1,1};
int size = 5;
int r = only12(nums, size);
printf("%d",r);
}
In the code above, we find the size of the array and iterate over it using a for loop. In the for loop, we see if nums[i] is something other than 1 or 2 and we set result to 0 if that's the case. At the end of the function, we return the result.
As pointed out in the comments, using sizeof(nums)/sizeof(nums[0]); won't work, so I have passed size as a parameter.

Return multiple values from function prototype in C. Results are multiple products

So I have a function prototype find all products from two numbers whether it has 2 or 3 digits. I believe that function can only return one value. So how do I print out all possible values in main using printf statement?
int find_largest_products(int ndigits){
int min = 1;
int max;
int smallest_num;
int largest_num = 0;
int product = 0;
int max_min_product = 0;
//Finding the minima. 1 digit = 1; 2 digits = 10; 3 digits = 100
smallest_num = min * pow(10, ndigits-1);
//Finding the maxima. 1 digits = 9; 2 digits = 99; 3 digits = 999
for (int i = 0; i < ndigits; i++){
max = 9 * pow(10, i);
largest_num += max;
}
for (int x = largest_num; x >= smallest_num; x--){
for (int y = smallest_num; y <= largest_num; y++){
product = x * y;
max_min_product = product;
}
}
return max_min_product;
}
int main() {
int num = find_largest_palindrome(2);
printf("Results: %d\n", num);
return 0;
}
Callback function:
int find_largest_products(int ndigits, int (*callback)(int, void *), void *baton){
//...
//max_min_product = product;
int r= callback(product, baton);
if (r) return r;
//...
return 0;
}
int print_product(int product, void *ignored) {
printf(" %d", product);
return 0;
}
int main()
{
//...
printf("Results:");
find_largest_products(2, print_product, NULL); // Invocation is here
printf("\n");
//...
}
What about commas? What about newline every so many? We can adapt the callback.
int print_product(int product, void *baton) {
int *counter = baton;
if (counter % 8 == 7) {
printf(", %d\n", product);
else if (counter % 8 == 0)
printf("%d\n", product);
else
printf(", %d\n", product);
++*counter;
return 0;
}
But now the invocation should look like:
int counter = 0;
find_largest_products(2, print_product, &counter); // Invocation is here
Notice how this keeps state between invocations. Here it's an int, but it could easily be a struct or a pointer thereof to enable keeping arbitrary amounts of state.
So this is the pattern of a callback function that can do whatever it wants. The callback function takes the accumulating argument found by find_largest_products and the state argument baton from find_largest_products, and returns 0 to continue or nonzero to bail. Here the callback function only prints the value out and never fails. I also consider this lower-skill-level than dynamic memory. We only need to learn the somewhat annoying syntax for function pointers and the rest easy concepts. Note that we don't take the address of a function pointer with &; it's like an array in that regard.
To make the point this is the general form; here's the callback that could be passed to retrieve the list.
struct product_info {
int *products;
int nproducts;
int aproducts;
};
int gather_products(int product, void *baton)
{
struct product_info *info = baton;
// normal dynamic stretchy array zzzzz
if (info->nproducts == info->aproducts) {
if (info->aproducts == 0) {
info->products = malloc(sizeof(int)*4);
if (!info->products) return 1;
info->aproducts = 0;
} else {
void *more = realloc(sizeof(int) * (info->aproducts << 1));
if (!more) return 1;
info->aproducts <<= 1;
info->products = more;
}
}
// end stretchy array
info->products[info->nproducts++] = product;
return 0;
}
int main()
{
//...
printf("Results: ");
struct product_info info = { NULL, 0, 0 };
if (find_largest_products(2, gather_products, &info)) { // Invocation is here
fprintf(stderr, "Out of memory\n");
free(info->products);
}
for (int i = 0; i < info->nproducts; i++)
printf("%s%d", (i == 0) ? "" : ", ", info->products[i]);
free(info->products);
printf("\n");
//...
}
Returning the list requires dynamic memory. It's interesting to note that function pointers provides a separation of concerns that I've come to appreciate in these late days; we can separate the generating algorithm from the storing of the results.
Another sample: find biggest!
int biggest_product(int product, void *baton) {
int *biggest = baton;
if (*biggest < product) *biggest = product;
return 0;
}
int main()
{
int biggest = 0;
find_largest_products(2, biggest_product, &biggest); // Invocation is here
printf("Biggest product is: %d\n", biggest);
}
Notice how easy it is to swap what you do with the products as you generate them.

3n+1 wrong answer according to uva onlinejudge [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
I am trying to solve the "3n+1" question and submit it on uva onlinejudge but every time it says that my code gives the wrong answer and unfortunately i can't find it's problem
here is the question: Problem 100
My Code:
#include <stdio.h>
int main()
{
unsigned long int n, m;
int max = 0;
scanf("%d %d", &n, &m);
int i;
for (i = n; i <m + 1; i++)
{
int ter = i;
int counter = 1;
while (ter != 1)
{
counter++;
if (ter % 2 == 1) { ter = 3 * ter + 1; }
else
ter = ter / 2;
if (ter == 1)
if (counter>max) { max = counter; }
}
}
printf("%d %d %d\n", n, m, max);
return 0;
}
The problem is clear. You are not following the instructions from the problem statement
For any two numbers i and j you are to determine the maximum cycle
length over all numbers between i and j.
The input will consist of a series of pairs of integers i and j, one
pair of integers per line. All integers will be less than 1,000,000
and greater than 0.
You only read one line of input and print that answer
You assume that i is less than j
Correct Solution:
#include <stdio.h>
int cycleSize(int x) {
int cycle = 1;
while (x != 1) {
if (x % 2 == 0) { //if even
x = x / 2;
} else { //if odd
x = x * 3 + 1;
}
++cycle;
}
return cycle;
}
int maxCycleSizeBetween(int a, int b) {
if (a > b) { //if b > a, swap them
int temp = a;
a = b;
b = temp;
}
int maxCycle = 0;
for (; a <= b; a++) {
int thisCycleSize = cycleSize(a);
if (thisCycleSize > maxCycle) {
maxCycle = thisCycleSize;
}
}
return maxCycle;
}
int main() {
int a, b; //input vars
while (scanf("%d %d", &a, &b) != EOF) {
printf("%d %d %d\n", a, b, maxCycleSizeBetween(a, b));
}
return 0;
}
The following function performs the requested calculation:
void n3plus1(int min, int max)
{
int i, n, len, lenmax=0;
for (i=min; i<=max; i++)
{
n= i; len= 1;
while (n!=1) {
if (n&1)
n= 3*n + 1;
else n= n/2;
len++;
}
if (len>lenmax) lenmax= len;
}
printf("Answer: %d %d %d\n", min,max,lenmax);
}
With the following tests:
void test(void)
{
n3plus1(22, 22);
n3plus1(1, 10);
n3plus1(100, 200);
n3plus1(201, 210);
n3plus1(900, 1000);
}
the output is:
Answer: 22 22 16
Answer: 1 10 20
Answer: 100 200 125
Answer: 201 210 89
Answer: 900 1000 174
Note: the "the maximum cycle length over all numbers between i and j" in the problem statement must be interpreted as including i and j.
The code assumes i<=j on input. The code excludes reading the input.
the following code implements the requirements
However, some online code contests expect a final blank line. You will need to determine those kinds of details.
#include <stdio.h>
int main( void )
{
size_t n1;
size_t m1;
char buffer[1024];
while( fgets( buffer, sizeof(buffer), stdin ) )
{
if( 2 != sscanf(buffer, "%lu %lu", &n1, &m1) )
{
break;
}
size_t n = n1;
size_t m = m1;
if( n1 > m1 )
{ // then first number greater than second so reverse for calculations
size_t temp = n;
n = m;
m = temp;
}
size_t maxCount = 0;
for (size_t i = n; i <= m; i++)
{
size_t ter = i;
size_t counter = 1;
while (ter != 1)
{
counter++;
if ( (ter & 0x01) == 1)
{ // then odd
ter = 3 * ter + 1;
}
else
{ // else even
ter = ter / 2;
}
// for testing only
// printf( "%lu: %lu, %lu\n", counter, i, ter );
}
if( maxCount < counter )
{
maxCount = counter;
}
}
printf("%lu %lu %lu\n", n1, m1, maxCount);
}
}
Note:
this code will exit if non numeric value entered
this code will exit if a EOF encountered -- this is expected
this code will fail if a negative number entered, however; the contest stipulation says that the numbers will be in the range 1...1000000 so no need to check for negative numbers
this code will exit if only one number on input line
this code will exit if only a <cr> is entered

C function returns wrong value

float a, b;
float sa() { return a;};
int main() {
a = 10;
b = sa();
printf("%f", b);
return 0;
}
This is a simplified version of my code.
I believe the program should print 10 but it gives me really small numbers like -65550, not always the same but very alike.
I have used the debugger to check the value of variabe a right before it is returned and it is 10, so the function returns 10, but b is set to something like -65550. I don't understand why this happens.
I'd appreciate some intell.
Thanks in advance.
Here is the full code:
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <time.h>
int dimensiuni, nrBitiSolutie, bitiPeDimensiune, gasitInbunatatire, nrRulari;
float limInf, limSup, precizie, valoareFunctie, minim, minimNou, T;
char solutie[100000];
float solutieReala[100];
void generateRandomSolution();
void bitesToFloat();
void rastrigin();
void rosenbrock();
float nextFirstFit();
float nextBestFit();
void main() {
int k;
T = 10;
gasitInbunatatire = 1;
srand ( time(NULL) );
printf("Introduceti numarul de dimensiuni: ");
scanf("%d", &dimensiuni);
printf("Introduceti limita inferioara si cea superioara: ");
scanf("%f%f", &limInf, &limSup);
printf("Introduceti precizia: ");
scanf("%f", &precizie);
//calculam numarul de biti necesari ca sa reprezentam solutia
nrBitiSolutie = dimensiuni * ceil(log(limSup-limInf * pow(10, precizie)))/log(2.0);
bitiPeDimensiune = nrBitiSolutie/dimensiuni;
//generam o solutie random
generateRandomSolution();
bitesToFloat();
rastrigin();
minim = valoareFunctie;
printf("Pornim de la %f\n", minim);
while( (nrRulari < 10000) && (T > 0.001)) {
minimNou = sa(); //error occurs here. sa() returns about 200 but minimNou is set to -65550
if (minimNou < minim) {
printf("Minim nou: %f\n", minimNou);
minim = minimNou;
T *= 0.995;
}
nrRulari++;
}
printf("Minimul aproximat: %f\n", minim);
system("pause");
}
void generateRandomSolution() {
int l;
for (l = 0; l < nrBitiSolutie; l++) solutie[l] = rand()%2;
}
void bitesToFloat() {
int i, parcurse = 1, gasite = 0;
int variabila = 0;
float nr;
for (i = 0; i < nrBitiSolutie; i++) {
variabila = variabila<<1 | (int)solutie[i];
if(parcurse == bitiPeDimensiune) {
nr = (float)variabila / (float)pow(2, bitiPeDimensiune);
nr *= limSup-limInf;
nr += limInf;
nr *= pow(10, precizie);
nr = (int)nr;
nr /= pow(10, precizie);
parcurse = 0;
solutieReala[gasite++] = nr;
variabila = 0;
}
parcurse++;
}
}
void rastrigin() {
int i;
valoareFunctie = 10 * dimensiuni;
for (i = 0; i < dimensiuni; i++) {
valoareFunctie += pow((float)solutieReala[i], 2) - 10 * (float)cos(2 * 3.14 * (float)solutieReala[i]);
}
}
void rosenbrock() {
int i;
valoareFunctie = 0;
for (i = 0; i < dimensiuni - 1; i++) {
valoareFunctie += 100 * pow((solutieReala[i+1] - pow(solutieReala[i], 2)), 2) + pow((1-solutieReala[i]), 2);
}
}
float sa() {
int j;
for (j = 0; j < nrBitiSolutie; j++) {
solutie[j] = solutie[j] == 0 ? 1 : 0;
bitesToFloat();
rastrigin();
if (valoareFunctie < minim) return valoareFunctie;
else if ( (rand()/INT_MAX) < exp((minim - valoareFunctie)/T) )
return valoareFunctie;
else solutie[j] = solutie[j] == 0 ? 1 : 0;
}
return minim;
}
I have marked where the error occurs with error occurs here comment
You simplified the code incorrectly. In your simplification, you defined sa() before calling it. But in your full program, you call sa() before defining it. In the absence of a declaration, functions are assumed to return int. Since your function actually returns a float, the result is undefined. (In this case, you will read a garbage value from the top of the floating point stack and then the floating point stack will underflow, and things go downhill from there.)

Resources