0

Made a code that calculated the amount of negative numbers in an array and shows those numbers. The problem is when the program prints out the number, it changes the number a slight bit, adding or subtracting something like 0.003.

I have absolutely no clue as to what's wrong with it, tried asking my professor; she said she didn't know, so I am here.

float col[10];
...
for (int i = 0; i < 10; ++i)
        {
            scanf_s("%f", &col[i]);
        }
...
printf("\n");
        printf("There are %d negative numbers\n", ct);
        for (int i = 0; i < 10; ++i)
        {
            if (col[i] < 0)
            {
                printf("[%d]=%f ", i, col[i]);
            }

        }
...

Put in -7786.88, command line printed out -7786.888184. It's fine on integers, just prints out a bunch of zeroes after the dot.

Sander De Dycker
  • 16,053
  • 1
  • 35
  • 40
  • 4
    There is an infinite number of values in the `float` range, but only about 2^32 of them can be exactly represented. – Weather Vane Oct 03 '19 at 12:33
  • Also see [What Every Computer Scientist Should Know About Floating-Point Arithmetic](https://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html) – haldo Oct 03 '19 at 12:33
  • It's not "randomly subtracting or adding". It's rounding to the nearest value representable in the floating point type. – R.. GitHub STOP HELPING ICE Oct 03 '19 at 12:36
  • @WeatherVane how do I avoid this problem. I have seen a lot of explanation regarding why floating point acts a certain way, but I haven't really noticed a solution to it? – Chinguun Erdenebadrakh Oct 03 '19 at 12:43
  • 1
    @ChinguunErdenebadrakh: You need to specify the problem you're trying to solve. If you frame a question that way it probably won't get closed as duplicate. For example, if your problem is storing amounts of currency, don't use floating point at all. Store integer values in cents (or whatever the currency's smallest fractional denomination is). – R.. GitHub STOP HELPING ICE Oct 03 '19 at 12:46
  • If you entered values with 2 decimal places you can print them with `%.2f` but you can only get 6 or 7 significant decimal digits from `float`. – Weather Vane Oct 03 '19 at 12:49
  • @R.. It's a problem in my programming class. The example is just inputting random numbers from positives to negatives, fractals to integers and spitting the negative ones out in the original amount with the position on the array printed with it. – Chinguun Erdenebadrakh Oct 03 '19 at 12:50
  • If you only want to see two digits to the right of the radix you must specify that in your printf format string. The general form of the float specifier in printf formatting strings is "%w.pf" where w is the width of the entire number and p is the precision, or number of digits to the right of the radix. https://www.dummies.com/programming/c/how-to-format-with-printf-in-c-programming/ – Jim Rogers Oct 03 '19 at 12:51
  • It's not a complete solution, but using `double` instead of `float` let you store the values more precisely. If you do change `float col[10];` to `double col[10];`, you will need to change `scanf_s("%f", &col[i]);` to `scanf_s("%lf", &col[i]);` (i.e. change `%f` to `%lf`). – Ian Abbott Oct 03 '19 at 13:10
  • @WeatherVane I would think that there's a very large finite number of values that can be expressed in a `float`, and that some of them may have duplicate representations. Also take note that a decent portion of those are NaNs. – S.S. Anne Oct 03 '19 at 13:47
  • @ChinguunErdenebadrakh: Let’s understand the problem. You say the problem involves “inputting random numbers.” It is impossible to input numbers—numbers are abstract mathematical entities with no physical existence. Input can contain numerals, which are strings of digits (or other characters) that represent numbers, such as the digits “3” and “4” for 34 or “3e4” for scientific notation for 3•10\*\*4 = 30,000. Since `float` can only represent certain numbers, it is not capable of holding all numbers that might be represented by numerals in the input… – Eric Postpischil Oct 03 '19 at 14:09
  • … As you have seen, it cannot represent −7786.88. One solution to this is narrowing the problem so that you do not need to accept any numbers represented by the input but only certain numbers, such as numbers with no more than six significant decimal digits. Another solution is not to represent the numbers internally at all but only to process the numerals—process the characters without converting them to numbers. For the simple problem you state, showing the negative numbers, this is simple: Read the input. For any numerals in the input without a `-`, ignore them… – Eric Postpischil Oct 03 '19 at 14:11
  • … For any numeral in the input starting with `-`, copy it character by character to the output. Then you will hae a very simple program that reads an array of numerals and shows only those numerals in the array that represent negative numbers. (Except that if a numeral might be a “negative zero”, such as “-000.000”, and you do not want to output this numeral, you will have to add some processing for that. Unfortunately, this will require being prepared to handle an arbitrary number of leading zeros.) – Eric Postpischil Oct 03 '19 at 14:12
  • I think the underlying problem here is that the instructor who made the assignment has no idea what they're doing. Subtleties of what floating point types can represent, what constitutes a number, how to write code that can handle an arbitrary number of leading zeros in a string without running out of memory to store them in, etc. were almost surely not intended to be part of the assigned problem. – R.. GitHub STOP HELPING ICE Oct 03 '19 at 15:16

0 Answers0