3

I am working on a problem that requires me to input a float with exactly 2 digits of precision.

I know how to print a float with two digits of precision but how can I input a float under this condition? I think this is the problem with my program because there is no compilation error as such but it just says wrong answer. I am working with C language.

I tried to read an int and a float with two digits of precision as required the following way:

int x;
float balance,y;
scanf("%d %.2f",&x,&y);

For complete references, here are the question and my solution

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
HawkEyez
  • 43
  • 1
  • 5
  • `scanf("%.2f",var_name)` – Ankur Jan 14 '15 at 15:15
  • possible duplicate of [Floating point inaccuracy examples](http://stackoverflow.com/questions/2100490/floating-point-inaccuracy-examples) – dandan78 Jan 14 '15 at 15:16
  • 1
    `scanf("%.2f",&var_name)` – Quentin Jan 14 '15 at 15:16
  • @dandan78 not at all...? – Quentin Jan 14 '15 at 15:17
  • 6
    @Shan, @Quentin: Nope. There is only a field-width for `scanf` formats, not a precision. – mafso Jan 14 '15 at 15:17
  • The point is, even if you input just 2 digits the resulting float could easily have many more. – dandan78 Jan 14 '15 at 15:17
  • i tried this solution... my output matches the example outputs given but still the online compiler shows an error. – HawkEyez Jan 14 '15 at 15:18
  • i don't think there will be compiler error. – Ankur Jan 14 '15 at 15:18
  • this is the question i have been working on. http://www.codechef.com/problems/HS08TEST/ and here is the solution int x; float balance,y; scanf("%d %.2f",&x,&y); if(x>0 && x<=2000 && y>=0 && y<=2000 && x0 && x<=2000 && y>=0 && y<=2000 && x>y) { printf("%.2f \n",y); } else { printf(" %.2f \n",y); } } – HawkEyez Jan 14 '15 at 15:19
  • question http://www.codechef.com/problems/HS08TEST/ solution http://www.codechef.com/viewsolution/5899676 what might have gone wrong then ?? – HawkEyez Jan 14 '15 at 15:26
  • 1
    You really don't need any precision for this question.just understand logic and try to solve.This is very simple. – Ankur Jan 14 '15 at 15:27
  • I don't think you can do it with scanf or any other standard input. So, write your own code for that! – Sucho Jan 14 '15 at 15:29
  • i was able to match all the example outputs given in the question statement but it doesnt accept the solution... i can understand where i went wrong @sucho what do u mean by i cant do it by scanf, are you suggesting creating a new function ?? – HawkEyez Jan 14 '15 at 15:55
  • If you have a compiler error, say what error, with full error message, and on what expression. As such we could only guess. This question is in risk to be closed as unclear or off topic because not enough detail on the error. – Serge Ballesta Jan 14 '15 at 16:02
  • there is no compilation error... it just says wrong answer – HawkEyez Jan 14 '15 at 16:06
  • @SergeBallesta i added few details to the question description.. hope it helps... m new to this so please excuse my mistakes for a while :) – HawkEyez Jan 14 '15 at 16:09
  • 1
    You are welcome, I'm not that old here anyway :-). But questions are required to show relevant part of source and eventual error messages *directly in question and not in links*. – Serge Ballesta Jan 14 '15 at 16:30
  • i have found the answer to this question, i just wrote it differently... this one before http://www.codechef.com/viewsolution/5899676 and this one workedhttp://www.codechef.com/viewsolution/5899676 but i just cant tell why the previuos one didnt work.. – HawkEyez Jan 14 '15 at 16:40
  • Post examples of invalid input and of valid input. – chux - Reinstate Monica Jan 14 '15 at 16:42
  • @chux http://www.codechef.com/problems/HS08TEST/ this is the question – HawkEyez Jan 14 '15 at 16:47
  • Post the examples here. – chux - Reinstate Monica Jan 14 '15 at 17:26

2 Answers2

5

There is a problem in proposed solution. According to cplusplus.com, the format f only accepts a width and no precision.

If you had controlled the return from the scanf (what you should definitively always do - and now you know why !) you would have seen immediately the problem :

int x, cr;
float balance,y;
cr = scanf("%d %.2f",&x,&y);
if (cr != 2) {
    fprintf(stderr, "Read error : cr = %d\n", cr);
}

Given any input, you will get :

Read error : cr = 1

Possible implementation with very little change :

cr = scanf("%d %f",&x,&y);
if (cr != 2) {
    fprintf(stderr, "Read error : cr = %d\n", cr);
}
// should round to only two digits - within floating point accuracy 
y = (((double)((int)(y * 100 + 0.5))) / 100.);

If you have a system where math.h contains round (not MSVC :-( ), last line is better written as (thanks to chux for proposing it) :

y = round(y * 100)/100

because above formula will fail for negative y and for y > INT_MAX / 100

If you really needed exact precision with two decimal digit, the correct way would be to do all computation as integer on long, taking the numbers multiplied by 100. I leave that as an exercise for the reader :-)

Serge Ballesta
  • 143,923
  • 11
  • 122
  • 252
  • i am new to programming with beginner level skills ... therefore i did not get you completely but i hope its correct. – HawkEyez Jan 14 '15 at 17:07
  • @HawkEyez : as your are a beginner it is normal you make mistakes :-). Learn from them : take time to understand what was wrong and why, so you no longer make same again. Good luck ... PS : for the floating point accuracy problem do read [Floating point inaccuracy examples](http://stackoverflow.com/questions/2100490/floating-point-inaccuracy-examples) suggested by dandan78. – Serge Ballesta Jan 14 '15 at 17:23
  • Using `(((double)((int)(y * 100 + 0.5))) / 100.)` to round to nearest 0.01 is incorrect for negative numbers and fails for values larger than `INT_MAX`. Better to use `round(y * 100)/100` – chux - Reinstate Monica Jan 14 '15 at 17:30
  • I now see the 0-2000 requirement buried in the comments. T'would been better had those requirements been posted by OP in the post. BTW: I should have said "fails for `y` values larger than `INT_MAX/100`". Likely OP's `INT_MAX` is not the minimal 32767. – chux - Reinstate Monica Jan 14 '15 at 17:40
  • @chux : requirement was for numbers between 0 and 2000 (seen in OP code) and `round` is not available below C++11 nor under MSVC ... even if is definitively cleaner than my awkward line ! – Serge Ballesta Jan 14 '15 at 17:42
  • Hmmm: `round()` is in the 16 year-old C99 spec and is in [VS 2013](http://msdn.microsoft.com/en-us/library/dn353646.aspx) – chux - Reinstate Monica Jan 14 '15 at 18:05
0

This answer inputs a float then checks it was in the correct format. But If you are working with money you should be using int cents; unless you have megabucks and don't care about cents, or are working to fractions of a penny (in which case you could work in 10th of a penny).

#include <stdio.h>
#include <string.h>

#define BUFLEN  20

int main()
{
    float money;
    char buff[BUFLEN+1], bank[BUFLEN+1], *eptr;
    printf ("Input the money: ");
    if (fgets(buff, BUFLEN, stdin) == NULL) {
        printf("Failed input\n");
        return 1;
    }
    if ((eptr = strchr (buff, '\n')) != NULL)   // newline?
        *eptr = 0;                              // terminate
    if (sscanf(buff, "%f", &money) != 1) {      // get the money
        printf("Failed input\n");
        return 1;
    }
    sprintf(bank, "%0.2f", money);              // check format of entry
    if (strcmp(bank, buff)) {
        printf("2 digit precision please: Euros.cents\n");
        return 1;
    }
    printf("You paid %s\n", bank);
    return 0;
}
Weather Vane
  • 33,872
  • 7
  • 36
  • 56