0

Input:

6

-4 3 -9 0 4 1

Expected output:

0.500000

0.333333

0.166667

My output:

0.000000

0.000000

0.000000


Code explanation:

1)User enters the number of inputs

2)User enters numbers

3)Code displays percentage of positive / negative / zero numbers


What am I doing wrong?

#include<stdio.h>
int main()
{
    int counter=0;
    int howmany;
    scanf("%d",&howmany);
    int clone=howmany;
    int numbers[howmany];
    int zero=0, positive=0, negative=0;

    while(howmany>0)
    {    
        scanf("%d",&numbers[counter]);
        if(numbers[counter]>0)
        {

            positive++;
        }
        else if(numbers[counter]<0)
        {
            negative++;
        }
        else if(numbers[counter]==0)
        {
            zero++;
        }
        counter++;
        howmany--;
    }

    double a=positive/clone;
    double b=negative/clone;
    double c=zero/clone;
    printf("%lf\n%lf\n%lf",a, b, c);  

    return 0;
}
jhelphenstine
  • 435
  • 2
  • 10
Atilla Gun
  • 15
  • 4
  • 7
    You are performing an *integer* division. Try something like `a=(double)positive/clone;` – Eugene Sh. Oct 28 '19 at 17:42
  • Welcome to SO! This title is a bit vague. Can you edit the question to choose a more descriptive title? Thank you. – ggorlen Oct 28 '19 at 17:44
  • unrelated, I see no need whatsoever for the `numbers` array in this code. Once you determine if a number is positive, negative, or zero, and update counters accordingly, the number is no longer needed. A single value read per pass in the loop without retention is completely viable. – WhozCraig Oct 28 '19 at 17:45
  • If you want to declare an array and allocate specific value with an user input, you shouldn't do it this way. You're using static memory allocation to allocate an array with dynamic size. It's not an error for gcc but not a good practice for a beginner. – patoglu Oct 28 '19 at 18:04
  • @sushibossftw Can you explain what do you mean? Why It's not good practice for beginners? – Atilla Gun Oct 28 '19 at 20:42
  • By preference, do **not** use `*scanf()` on potentially malformed (user) input. **If** you do, make sure you check the return value. Because if the user entered non-matching input, your variables are not initialized and you are running into undefined behavior. By preference, read whole lines of user input with `fgets()` and then parse them in-memory with e.g. `strtol()`, `strtof()`, `strtok()` or whatever is appropriate -- this allows you to backtrack, identify exactly the point where the input failed to meet your expectations, and print meaningful error messages including the full input. – DevSolar Oct 28 '19 at 22:30
  • @sushibossftw that's not static allocation, `numbers` is a local variable with automatic storage duration (IOW it will be in stack, not with static data). Also, for use like this it is perfectly fine... – hyde Oct 28 '19 at 22:33
  • @AtillaGun Using Variable Length Array (VLA) has the problem, that stack is quite small (pnly a few megabytes typically), and there is no way to check if there is enough space in stack. It's nice if you know or can set max size, but then you could just allocate array with that max size instead of VLA. – hyde Oct 28 '19 at 22:37
  • @AtillaGun https://stackoverflow.com/questions/43463690/user-input-array-size-c – patoglu Oct 29 '19 at 07:43
  • @hyde Sure, it's not static allocation, it's automatic allocation. Still I would not recommend "beginner" to use variable length arrays anyway. You explained the reason actually, here we may be working with small data but I think we should avoid using VLA as much as we can, especially a beginner. – patoglu Oct 29 '19 at 07:57
  • @sushibossftw I'd almost argue the opposite: VLA are nice and convenient for learning exercises and other "toy" programs, but using them in anything which is going to be released to external users requires careful analysis :-D – hyde Oct 29 '19 at 12:19

1 Answers1

1

The problem is how C handles your integer division:

    double a=positive/clone;
    double b=negative/clone;
    double c=zero/clone;
    printf("%lf\n%lf\n%lf",a, b, c);  

    return 0;

positive and clone are integers; dividing them discards any remainder - the answer must be an integer. You're defining a double, a, to receive positive/clone, for example, but the evaluation is first performed on two integers (positive and clone), resulting in an integer answer, which is then assigned to a - regardless of it being a double.

Instead, you'll want to cast one of the integers as though it were a double, for purposes of this evaluation. Then, a double form of positive is divided, and the result is able to hold the remainder, as it's a double. That double is then assigned to a, and you'll get the output you're looking for.

    double a=(double)positive/clone;
    double b=(double)negative/clone;
    double c=(double)zero/clone;
    printf("%lf\n%lf\n%lf",a, b, c);  

    return 0;
jhelphenstine
  • 435
  • 2
  • 10