I want to find the sum of all the digits entered by a user after the decimal point in c.
Eg. 12.36 must return 9
15.06 must return 6
9.0 must return 0
My approach
#include <stdio.h>
int main()
{
double num,numfloat;
int digitf,numint,sumf=0;
scanf("%lf",&num);
numint=num;
numfloat=num-numint;
while(numfloat!=0)
{
digitf=(numfloat*10);
numfloat=numfloat*10-digitf;
sumf=sumf digitf;
}
printf("Sum float %d",sumf);
return 0;
}
The sum comes out a lot more than the expected.
CodePudding user response:
Try, (The reason why in this example, I haven't joined the loops is that: I want this to be usable on other situations where they use an alternate method of validating input, see the SECOND EXAMPLE for both loops joined):
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int main() {
// read from stdin
char num[512] = { };
fgets(num, sizeof(num), stdin);
num[strcspn(num, "\n")] = '\0';
// verify if number is valid
int decimal_point_found = 0;
for (int i = 0; i < strlen(num); i ) {
// check if digit
if (!isdigit(num[i])) {
// be safe from multiple decimal points
if (num[i] == '.' && decimal_point_found == 0) {
decimal_point_found = 1;
continue;
}
printf("ERROR: enter a valid number\n");
return 1;
}
}
int total = 0;
// add all the decimal points
for (int i = 0, decimal_point_found = 0; i < strlen(num); i ) {
if (decimal_point_found == 1) {
total = num[i] - '0'; // - '0' converts char to int
}
if (num[i] == '.') {
decimal_point_found = 1;
}
}
// show total
printf("%d\n", total);
}
In the above, I have read char instead of reading float. I have read using fgets() which is safer than scanf().
Handling char makes it so much easier to calculate such things. As we know the number of digits, etc.
With both loops joined:
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int main() {
char num[512] = { };
fgets(num, 512, stdin);
num[strcspn(num, "\n")] = '\0';
// verify if number is valid
int decimal_point_found = 0;
int total = 0;
for (int i = 0; i < strlen(num); i ) {
if (!isdigit(num[i])) {
if (num[i] == '.' && decimal_point_found == 0) {
decimal_point_found = 1;
continue;
}
printf("ERROR: enter a valid number\n");
break;
}
if (decimal_point_found == 1) {
total = num[i] - '0';
}
}
printf("%d\n", total);
}
CodePudding user response:
You mentioned in a comment that the input has to be a number.
This first point to mention is that when coding, we are not manipulating such abstract things as numbers, but imperfection representations of numbers. Think to the famous painting "This is not a pipe". Same here, "This is not a number".
float, double and char* are all or can be all representations of numbers.
Depending on the context, one representation can be more suitable than others. Here, using a char*
would be quite possible.
Now, let us assume that the input format double is imposed by a sadistic professor (they are paid for that).
Why is your code not working? Mainly because internally, the representation of the numbers is generally imperfect.
A small error can lead to a large error when converting a float to an integer.
For example, int i = 0.999999 will give i = 0.
The solution is to account for the internal error representation, by introducing a margin, e.g. eps = 1.0e-8,
when performing the float-to-integer conversion, or when testing if a number is equal to 0.
#include <stdio.h>
int main() {
double num, numfloat;
int digitf, numint, sumf = 0;
double eps = 1.0e-8; // to deal with representation inaccuracy of numbers
if (scanf("%lf", &num) != 1) return 1;
if (num < 0.0) num = -num;
numint = (int) (num eps);
numfloat = num - numint;
while (numfloat > eps) {
numfloat *= 10;
digitf = (int) (numfloat eps);
numfloat -= digitf;
sumf = sumf digitf;
}
printf("Sum float %d\n", sumf);
return 0;
}
