I'm facing some problems regarding the Floating point exception error because previously when i printed the variables individually so i wasn't sure what went wrong. Down below is the code i have written so far. I'm not sure what cause the error as i am pretty sure i'm not dividing by zero.
#include <stdio.h>
#include <cs50.h>
#include <ctype.h>
#include <string.h>
#include <math.h>
int main(void)
{
//promt user for text
string n = get_string("Text: ");
int sumletters = 0;
int sumdots = 0;
int sumspaces = 1;
for (int i = 0; i < strlen (n); i++ )
{
if (n[i] >= 'A' && n[i] <= 'z')
{
sumletters = sumletters + 1;
}
if (n[i] == ' ')
{
sumspaces = sumspaces + 1;
}
if (n[i] == '.' || n[i] == '?' || n[i] == '!' )
{
sumdots = sumdots + 1;
}
float L = sumletters / (sumspaces / 100);
float S = sumdots / (sumspaces / 100);
int index = round ((0.0588 * L) - (0.296 * S) - 15.8);
if (index < 1)
{
printf ("Before grade 1\n");
}
{
printf ("Grade 16+\n");
}
else
{
printf ("Grade %i", index);
}
}
printf ("\n");
}
This is the part at fault:
sumletters / (sumspaces / 100)
sumspaces / 100 uses integer division so it will almost always be 0. You can refactor your code to use floating point division by simply distributing the division:
sumletters / sumspaces * 100
The below is integer division and the quotient is often zero as int math discards the fraction.
int sumspaces;
...
sumspaces / 100
The below can result in int division of 0.
int sumletters;
...
// v---------------v might be 0
sumletters / (sumspaces / 100);
Floating point exception error ... i am pretty sure i'm not dividing by zero.
For various reason of a common error handler, int division by zero may be reported as a floating point exception.
As with many operations were the result type is not in the operation, but only the assignment, such problems are common.
Instead, insure the math uses the destination type.
// v---------------v int division
// float L = sumletters / (sumspaces / 100);
float L = sumletters / (sumspaces / 100.0f);
// ^------------------^ At least float division
Aside: No good reason to use float types here, just use double.
Notice that code uses double math, and not float math in:
// v----v v---v v--v double constants
round ((0.0588 * L) - (0.296 * S) - 15.8)
// ^---^ double function
Related
I'm a beginner in C doing the harvard cs50x course and this code was written a lot of help but I still can't seem to figure out why it compiles on vscode but does not ask for text from the user.
The prompt is on writing a code that can estimate the difficulty of a text according to grade level based on a given equation that I have included below. Some of the comments include my previous mistakes so they are not descriptions that I purposely added.
#include <cs50.h>
#include <ctype.h>
#include <math.h>
#include <stdio.h>
#include <string.h>
int main(void)
{
// Declare variables to count letters, words, and sentences
// Check if character is an alphabet
// letter++
// If character is not an alphabet or punctuation
// word++
// If character is punctuation
// sentence++
int count_letter = 0;
int count_word = 1;
int count_sentence = 0;
string text = get_string("What is your chosen text?\n");
int text_length = strlen(text);
for(int i = 0; i < text_length; i++) // Run through the length of the text?
{
if(isalpha(text[i])) // check if alphabet
{
count_letter++; // count the number of letters in the text
}
}
for(int i = 0; i < text_length; i++)
{
if(isspace(text[i])) {
count_word++;
}
}
for(int i = 0; i < text_length; i++)
{
// if(text[i]=="." || text[i]=="?" || text[i]=="!")
if(text[i] == '.' || text[i] == '?' || text[i] == '!') {
count_sentence++;
}
}
// L = letters/word*100, S = sentence/word*100
int L = count_letter / count_word * 100;
int S = count_sentence / count_word * 100;
// index = 0.0588 * L - 0.296 * S - 15.8
int index = round(0.0588 * L - 0.296 * S - 15.8);
printf("%d\n", index);
}
In
// L = letters/word*100, S = sentence/word*100
int L = count_letter / count_word * 100;
int S = count_sentence / count_word * 100;
you are doing integer arithmetic, so you are dividing the number of letters by the number of words (the numer of letters is supposed to be larger) but the division is done as integers, so once multiplying it by 100 you will get no decimals (you will get a number ended in two final 00 digits)
you have a chance here, is to multiply first by 100, and then you will get the closest result as an integer and you will get decimals.
Another chance is to convert the numbers to floating point as soon as possible, as in:
// L = letters/word*100, S = sentence/word*100
/* using a floating point literal forces the calculation to be done as real numbers */
int L = 100.0 * count_letter / count_word;
int S = 100.0 * count_sentence / count_word;
or even better (get and use double floating point numbers all the time) after calculations:
// L = letters/word*100, S = sentence/word*100
/* using a floating point number forces the calculation to be done as real numbers */
double L = 100.0 * count_letter / count_word;
double S = 100.0 * count_sentence / count_word;
The data numbers continue to be integers, but as the first operation consists of multiplying a real number (the 100.0 floating point literal) the first product is calculating as floating point (the second argument, the first variable in the expression, is converted to double before doing the calculation, and the third, are both converted to double before doing the calculations) resulting in double precision values.
So finally you can show the result as a floating point number with:
// index = 0.0588 * L - 0.296 * S - 15.8
/* everything is calculated as floating point numbers (L and S have been defined as double above */
double index = round(0.0588 * L - 0.296 * S - 15.8);
/* the formatting specifier must be g below, once index is floating point */
printf("%g\n", index);
I need to redo printf for a projet, so I actually have a problem with the conversion of float.
I managed to convert almost everything but for the number 1254451555.6
I got an issue: I got 1254451555.59999.
I think it's the calculation to keep the part after the . that doesnt work.
nbr = ((n - nbr) * 100000000);
I tried different things but I haven't managed to fix it yet.
Do you have any idea?
int getlenghtitoa(long long n, int nbase)
{
int i;
i = 0;
while (n >= 0)
{
n /= nbase;
i++;
if (n == 0)
break ;
}
return (i);
}
float ft_nbconv(float n, int i)
{
while (i-- > 0)
n = n *10;
return (n);
}
int ft_power(long long nbr)
{
int i;
i = 1;
while(nbr > 10)
{
i *= 10;
nbr = nbr / 10;
}
return (i);
}
char *ft_conver_f(long double n)
{
char *dest;
int i;
int a;
long long int nbr;
int power;
nbr = (long long) n;
i = getlenghtitoa((long long )n, 10);
if (!(dest = malloc(sizeof(char) * (i + 8))))
return (0);
a = i;
i = 0;
power = ft_power(nbr);
while (a--)
{
dest[i++] = ((nbr / power) % 10) + '0';
if (power != 1)
power /= 10;
}
dest[i++] = '.';
nbr = ((n - nbr) * 100000000);
power = 10000000;
while (a++ < 5)
{
if (a == 5)
if ((((nbr / power)) % 10) >= 5)
{
dest[i++] = ((nbr / power) % 10 + 1) + '0';
break;
}
dest[i++] = ((nbr / power) % 10) + '0';
power /= 10;
}
dest[i] = '\0';
return (dest);
}
Most decimal fractions cannot be represented exactly as binary fractions. A consequence is that, in general, the decimal floating-point numbers you enter are only approximated by the binary floating-point numbers actually stored in the machine.
That's why when implementing a printf, the only way to really be able to convert a floating number to a 2-seperated-by-point integers, is by using the precision factor and rounding manually.
If you are not required to implement the precision, the default is 6.
(Precision is the number of places to print after the dot (and it's rounded)).
And that's what's missing in your implementation.
Let's call the digits before the dot the ipart and the digits after the fpart .
nbr = ((n - nbr) * 100000000);
This should be
nbr = ((n - nbr) * 10000000); // 7 zeros
// nbr is now equal to 5999999
if (nbr % 10 >= 5)
{
nbr = nbr / 10 + 1;
}
else
nbr = nbr / 10;
This way, you get 7 digits after the dot, see if the last one is higher than 5, if it is, you add +1 to nbr (after dividing by 10 to make sure nbr has 6 digits), if it's not, you just divide by 10.
One more note about this rounding method, It will not be able to carry the rounding from the fpart to the ipart .
what if you want to print 3.9999999 ? It should print 4.000000. That means that can't just convert the ipart to a string from the beginning, because sometimes rounding the fpart will add +1 to your ipart
So think about creating a function ltoa for example that takes a long long int and converts it to a string, complete the piece of code about rounding i just gave you to make sure rounding can be carried to the ipart , then convert the whole thing to string using something like
dest = join(ltoa(ipart), ".", ltoa(fpart)).
A couple more notes, your function does not handle negative numbers.
And your int ft_pow can be easily flooded, so consider changing to long long ft_pow
This question already has answers here:
Exchange 1000s digit with 10s digit (C)
(3 answers)
Closed 5 years ago.
What I want to do in C is swap two digits in a double.
For example, if the input is 54321.987 and I want to swap the 2nd with the 4th digit, the output should be 52341.987.
Example when too small: 12.34 would output 1002.34.
Using stringification approach:
There are more elegant ways, but you can see the steps (and improve on) this pseudo code to stringify, move values, and convert back to number.
char buf1[20];
char buf2[20];
char *dummy;
double val = 54321.987;
sprintf(buf1, "%9.3f", val );
//Now the number is in string form: "54321.987". Just move the two elements
buf2[0]=buf1[0];
buf2[1]=buf1[3];
buf2[2]=buf1[2];
buf2[3]=buf1[1]; //and so on
//now convert back:
val = strtod(buf2, &dummy);
printf("%9.3f\n", val);
Or, a function could be used to do essentially the same thing: (still stringification)
double swap_num_char(double num, int precision, int c1, int c2); //zero index for c1 and c2
int main(void)
{
double val = 54321.987;
printf("%9.3f\n", swap_num_char(val, 3, 1, 3));
return 0;
}
double swap_num_char(double num, int precision, int c1, int c2)
{
char buf[25];
char format[10];
char *dummy;
char c;
sprintf(format, "%s0.%df", "%", precision);
sprintf(buf, format, num);
c = buf[c1];
buf[c1] = buf[c2];
buf[c2] = c;
num = strtod(buf, &dummy);
return num;
}
You can get the two digits you're interested in with simple operations:
You can do so with
double x = 54321.987;
double tens = ((int)(x / 10)) % 10; // Result is 2
double thousands = ((int)(x / 1000)) % 10; // Result is 4
Then you can subtract out the digits from their original place,
and add them back in a new place:
x = x - (tens * 10.0) - (thousands * 1000.0); // result is 50301.987
x = x + (tens * 1000.0) + (thousands * 10.0); // result is 52341.987
Now just reduce the expression:
x = x + tens * (1000.0 - 10.0) - thousands * (1000.0 - 10.0);
This leaves you with a final expression:
x += (tens - thousands) * 990.0;
Or, if you don't want the intermediate variables:
x += (((int)(x/10))%10 - ((int)(x/1000))%10) * 990;
One solution would be to extract the digits, then swap them.
You extract the digits (from positive numbers, at least) by using floor():
int place1 = 1; /* 0-based*/
double desiredPowerOf10 = powersOf10[place1];
double nextPowerOf10 = powersOf10[place1 + 1];
double digit1 = floor(number / desiredPowerOf10) - floor(number/nextPowerOf10) * 10;
You can then subtract the digits and add them back with the different powers:
double digitsRemoved = number - (digit1 * power1 + digit2 * power2);
double digitsSwapped = digitsRemoved + digit1 * power2 + digit2 * power1;
This may be susceptible to loss of precision with very large numbers, though.
1 - Use modf() to break the number into whole and fractional parts.
double modf(double value, double *iptr);
The modf functions break the argument value into integral and fractional parts, C11 ยง7.12.6.12
2 - Print the whole number part as a string and do the swap.
3 - Reconstruct
#include <float.h>
#include <math.h>
#include <stdio.h>
double swap2_4digit(double x) {
if (signbit(x)) {
return -swap2_4digit(-x);
}
printf("Before %f\n", x);
double ipart;
double fpart = modf(x, &ipart);
// ms_digit digits '.' '\0' min_size
char buf[1 + DBL_MAX_10_EXP + 1 + 1 + 4]; // Insure buffer is big enough
strcpy(buf, "0000"); // Handle small numbers
sprintf(buf + strlen(buf), "%.0f", ipart);
size_t len = strlen(buf);
char ch = buf[len - 2];
buf[len - 2] = buf[len - 4];
buf[len - 4] = ch;
x = atof(buf) + fpart;
printf("After %f\n", x);
return x;
}
int main(void) {
swap2_4digit(54321.987);
swap2_4digit(12.34);
}
Output
Before 54321.987000
After 52341.987000
Before 12.340000
After 1002.340000
Something left for OP. Make general for other digit positions.
If you want input number to be double then you can do something like this:
#include <stdio.h>
#include <stdlib.h>
int main()
{
double numbergiven = 56789.1234;
double dummy;
double _4th_digit = (10*modf(numbergiven/10000, &dummy)) - modf(numbergiven/1000, &dummy);
double _2th_digit = (10*modf(numbergiven/100, &dummy)) - modf(numbergiven/10, &dummy);
numbergiven = numbergiven - (_4th_digit * 1000) + (_2th_digit * 1000);
numbergiven = numbergiven + (_4th_digit * 10) - (_2th_digit * 10);
printf("%lf",numbergiven);
return 0;
}
If you are not familiar with modf then you can simply do it this way:
#include <stdio.h>
#include <stdlib.h>
int main()
{
double numbergiven = 56789.1234;
int number = numbergiven;
int _4th_digit = (number/1000) - (10*(number/10000));
int _2th_digit = (number/10) - (10*(number/100));
numbergiven = numbergiven - (_4th_digit * 1000) + (_2th_digit * 1000);
numbergiven = numbergiven + (_4th_digit * 10) - (_2th_digit * 10);
printf("%lf",numbergiven);
return 0;
}
or use fmod() #John Bollinger.
The fmod functions compute the floating-point remainder of x/y.
Extract the 2 digits each with the difference of modding with 10place and modding with 10place-1.
Subtract the 2 digits and then add them back swapped.
double swap_digit(double x, unsigned a, unsigned b) {
printf("Before %f\n", x);
double a_place = pow(10.0, a);
double b_place = pow(10.0, b);
double scaled_digit_a = fmod(x, a_place) - fmod(x, a_place/10);
double scaled_digit_b = fmod(x, b_place) - fmod(x, b_place/10);
x -= scaled_digit_a + scaled_digit_b;
x += scaled_digit_a/a_place*b_place + scaled_digit_b/b_place*a_place;
printf("After %f\n", x);
return x;
}
int main(void) {
swap_digit(54321.987,2,4);
swap_digit(12.34,2,4);
}
Output
Before 54321.987000
After 52341.987000
Before 12.340000
After 1002.340000
Double is stored in a memory as a sequence of bits, but you want to operate with decimal digits. Doing this with double variable you may not receive the original digits because of floating-point arithmetic.
Therefore, you should manipulate with string representation of double. The main aspect is how many digits string will contain. But it's obvious that you get number from input. Scan it as string, not as double.
There is a working code:
#include <stdio.h>
#include <stddef.h>
#define BUFSIZE 255
void swap_digits(char *str, int n, int m) {
char *digit1 = NULL;
char *digit2 = NULL;
int count = 0;
while (*str && (!digit1 || !digit2)) {
if (*str != '.') {
count++;
if (count == n) {
digit1 = str;
}
if (count == m) {
digit2 = str;
}
}
str++;
}
if (digit1 && digit2) {
char tmp = *digit1;
*digit1 = *digit2;
*digit2 = tmp;
}
}
int main(void) {
char buffer[BUFSIZE];
scanf("%s", buffer);
// it is preferably to validate input
swap_digits(buffer, 2, 4);
printf(buffer);
return 0;
}
Is there any way to round systemGuess up. In this case the outcome of systemGuess is 5.5 I want it to be 6 how do I do this?
See code below:
int main(void){
int systemGuess = 0;
stystemGuess = (10 - 1)/2 + 1;
printf(" %d ", stystemmGuess);
}
Use floating point division and ceil:
stystemGuess = ceil((10 - 1)/2.0) + 1;
If you want to round 0.4 down, use round instead.
OP wants to perform an integer division with the result rounded-up.
// If the quotient fraction > 0, return next larger number.
unsigned udiv_ceiling(unsigned n, unsigned d) {
return (n + d - 1)/d;
}
// If the quotient fraction >= 0.5, return next larger number.
unsigned udiv_nearest_ties_up(unsigned n, unsigned d) {
return (n + d/2)/d;
}
stystemGuess = udiv_ceiling(10 - 1, 2) + 1;
// or
stystemGuess = udiv_nearest_ties_up(10 - 1, 2) + 1;
Additional code needed to handle negative numbers and in corner cases, protect against n + d - 1 overflow.
You can use
systemGuess = (10 - 1)/2.0 + 1 + 0.5;
The problem is that you do integer calculation.
So e.g. 9/2 is 4. If you use 9/2.0 you have floating point division, which gives you 4.5. Adding 0.5 in the end gives you 6.0 instead of 5.5, so when storing it in systemGuess, you get 6 instead of 5.
Integer division in C truncates toward 0, so if you do the math on the other side of 0 (i.e., on negative numbers), it will "round up". You might do this by subtracting an amount from the dividend and adding half that amount back to the result:
int main(void)
{
int systemGuess = 0;
//systemGuess = (10 - 1)/2 + 1;
systemGuess = (10 - 1 - 20)/2 + 1 + 10;
printf(" %d ", systemGuess);
}
Probably in your real program there is a more elegant way to make this happen.
Here you go:
#include <stdio.h>
#include <stdlib.h>
int divide(int x, int y);
int main(void){
int systemGuess = 0;
int x = 10-1;
int y = 2;
systemGuess = divide(x,y) + 1;
printf(" %d ", systemGuess);
}
int divide(int x, int y) {
int a = (x -1)/y +1;
return a;
}
I am new to recursion so I am trying to write a simple program that adds to the nth number of the series 1/n. So if the user enters n = 4, the program will add 1 + 1/2 + 1/3 + 1/4. My program keeps outputting that the sum of the series is 0. Can someone please explain what I am doing wrong? I'd appreciate the help. Here is my code:
#include <stdio.h>
double sum(double n);
int main() {
double n;
double total;
printf("Enter a positive integer greater than 0: ");
scanf("%lf", &n);
total = sum(n);
printf("Sum: %lf", total);
return 0;
}
double sum(double n) {
if (n == 1)
return 1;
else
return ((1 / n) + sum(n - 1));
}
The problem is in the definition of this function:
double sum(int n) {
if (n == 1)
return 1;
else
return ((1 / n) + sum(n - 1));
}
n is int so 1/n will be always evaluated as int since both 1 and n are integers. Thus 1/n is always 0 for each n>1.
The solution would be to define n as double :
double sum(double n) {
if (n <= 1.0)
return 1.0;
else
return ((1.0 / n) + sum(n - 1.0));
}
Check your base case. sum(1) should return 1.
Also, an int divided by an int returns an int. Use a floating point number in your division.
It should be
double sum(double n) {
if (n == 1)
return 1.0;
else
return ((1.0 / n) + sum(n - 1));
}
1/n will always return 0 since 'n' acts as an integer value and not a float value even though the datatype is double as the value assigned to it is of type integer.