Why does C give me a different answer than my calculator? - c

I've run into an odd problem with this code:
legibIndex = 206.385 - 84.6 * (countSylb / countWord) - 1.015 * (countWord / countSent);
This is the calculation for the legibility index of a given text file.
Since this is a homework assignment, we were told what the Index should be (80, or exactly 80.3)
My syllable count, word count, and sentence count are all correct (they match up with the given numbers for the sample textfiles.
Even if I hardcode the numbers in, I do not get 80, even though I do when i put it into my caclulator exactly as seen. I can't imagine what is wrong.
Here is the equation we were given:
Index = 206.835 - 84.6 * (# syllables/# words) - 1.015 * (# words/# sentences)
As you can see, I just plugged in my variables (which are holding the correct values.
For reference, the values are : 55 Syllables, 40 Words, 4 Sentences, as given by the instructor. The values my program produces when ran is a Legibility Index of 112.
Am I missing some brackets, or what?
I'm stumped!

Right off the bat, from the names (which include the word count) I'd guess that countSylb, countSent and countWord are declared as integers, and therefore your divisions are doing integer arithmetic, truncating the decimal portions. Cast them to floats and that should fix it.
legibIndex = 206.385 - 84.6 * ((float)countSylb / ((float)countWord) -
1.015 * (((float)countWord / ((float)countSent);

You probably have a data type issue where you're rounding because int/int = int instead of float.
If you cast to float or declare as float it should help you.

Works here. Perhaps you're doing integer division instead of float division:
>>> def leg(syl, wor, sen):
... return 206.835 - 84.6 * (float(syl) / wor) - 1.015 * (float(wor) / sen)
...
>>> print leg(55, 40, 4)
80.36

If your calculations inside the brackets are pure integer the calculation will drop the decimal parts and be rounded down ( same as using floor() ) which obviously will alter the result.

When I run this in Haskell, I get the right answer (80.36000000000001).

I think the problem is that (# syllables/# words) comes to 1 if you're using integer arithmetic. If you make sure that you perform the calculation using floating point arithmetic (so # syllables/# words = 1.375), you should get the right answer out.

As pointed out above, your count variables are likely whole number integers, but your expression contains literal floating point numbers. Casting those ints into floats will give the correct value. You must also make sure that what you are storing the expression's result in (legibIndex) is also of type float.

It's probably an operator precedence issue. To be sure, group the things you think should happen first more than you already have.
Edit No, it isn't; using C's operator precedence I get 80.36. I expect sparks was right (and the first off the mark) that it's a data type problem and you're running into premature rounding.

Related

Does data types change the output of an operation in C [duplicate]

This question already has answers here:
What is the behavior of integer division?
(6 answers)
Closed last year.
Iam new to C programming and i guess this question might look foolish but I have searched and i didn't get a satisfactory answer:
My question is does hierachy of execution of operators depend on whether the declared variables are integer or float, here is a scenario which I don't understand;
this is the first case:
main()
{
int i=2,j=3,k;
k=i/j*j;
printf("%d",k);
and the output to that is 0 which i don't agree with;
But when I change the variables to float as in below;
main()
{
float i=2,j=3,k;
k=i/j*j;
printf("%f",k);
The output to becomes 2.00000
why is this?
In the first code snippet, the subexpression i/j has integer operands so integer division is performed. This means that the result is also an integer and any fractional part is truncated.
In the second snippet, both operands have floating point type so floating point division is performed.
and the output to that is 0 which i don't agree with;
The program is always right, people (programmers) do mistakes.
The operation below is an integer division and 2 divided by 3 is 0. Integer division does not round to the closest integer value which causes your confusuin.
i/j == 2/3 == 0
does hierachy of execution of operators depend on whether the declared variables are integer or float?
Hierarchy of execution as in order, no.
However, results very much depend on the types. Division involving two integers results in a truncated integer, so 2 / 3 is zero, not two thirds as you may expect.
Then, when you multiply that by two, you still have zero.
An example can be seen when calculating percentage of a ratio. Let's say 40 of the 60 students in a class are male. If you wanted to know the percentage of males, there's a vast difference between the two formulae below:
int males = 40;
int total = 60;
bad_pct = males / total * 100; // 40/60=0, 0*100=0.
good_pct = males * 100 / total; // 40*100=4000, 4000/60=66.
The issue of integer math vs. floating point math has been dealt with well already, but when you use the term "hierarchy of operators," I think you're referring to operator precedence.
No, it does not change this. Operator precedence is the same for floating point and integer math operations.

Simple floating point multiplication not giving expected result [duplicate]

This question already has answers here:
Is floating point math broken?
(31 answers)
Closed 3 years ago.
When given the input 150, I expect the output to be the mathematically correct answer 70685.7750, but I am getting the wrong output 70685.7812.
#include<stdio.h>
int main()
{
float A,n,R;
n=3.14159;
scanf("%f",&R);
A=n*(R*R);
printf("A=%.4f\n",A);
}
float and double numbers are not represented very accurately in the memory. The main reason is that the memory is limited, and most non-integers are not.
The best example is PI. You can specify as many digits as you want, but it will still be an approximation.
The limited precision of representing the numbers is the reason of the following rule:
when working with floats and double numbers, not not check for equality (m == n), but check that the difference between them is smaller than a certain error ((m-n) < e)
Please note, as mentioned in the comments too, that the above rule is not "the mother rule of all rules". There are other rules also.
Careful analysis must be done for each particular situation, in order to have a properly working application.
(Thanks #EricPostpischil for the reminder)
It is common for a variable of type float to be an IEEE-754 32-bit floating point number.
The number 3.14159 cannot be stored exactly in an IEEE-754 32-bit float - the closest value is approximately 3.14159012. 150 * 150 * 3.14159012 is 70685.7777, and the closest value to this that can be represented in a 32-bit float is 70685.78125, which you are then printing with %.4f so you see 70685.7812.
Another way of thinking about this is that your n value only ends up being accurate to the sixth significant figure, so - as you are just calculating a series of multiplications - your result is also only acccurate to the sixth significant figure (ie 70685.8). (In the general case this can be worse - for example subtraction of two close values can lead to a large increase in the relative error).
If you switch to using variables of type double (and change the scanf() to use %lf), then you will likely get the answer you are after. double is typically a 64-bit float, which means that the error in the representation of your n values and the result is small enough not to affect the fourth decimal place.
Have you heard that float and double values aren't always perfectly accurate, have limited precision? Have you heard that type float gives you the equivalent of only about 7 decimal digits' worth of precision? This is what that means. Your expected and actual answers, 70685.7750 and 70685.7812, differ in the seventh digit, just about as expected.
I expect the output to be the mathematically correct answer
I am sorry to disappoint you, but that's your mistake. As a general rule, when you're doing floating-point arithmetic, you will never get the mathematically correct answer, you will always get a limited-precision approximation of the mathematically correct answer.
The canonical SO answers to this sort of question are collected at Is floating point math broken?. You might want to read some of those answers for more enlightenment.

Do the rules of arithmetic hold for addition in C?

I'm new to C, and I'm having such a hard time understanding this material. I really need help! Please someone help.
In arithmetic, the sum of any two positive integers is great than either:
(n+m) > n for n, m > 0
(n+m) > m for n, m > 0
C has an addition operator +. Does this arithmetic rule hold in C?
I know this is False. But can please someone explain to me why so, I can understand it? Please provide counter-example?
Thank you in advance.
(I won't solve this for you, but will provide some pointers.)
It is false for both integer and floating-point arithmetic, for different reasons.
Integers are susceptible to overflow.
Adding a very small floating-point number m to a very large number n returns n. Have a read of What Every Computer Scientist Should Know About Floating-Point Arithmetic.
It doesn't hold, since C's integers are not "abstract" infinititely-sized integers that the real integers (in mathematics) are.
In C, integers are discrete and digital, and implemented using a fixed number of bits. This leads to limited range, and problems when you go (try to) out of range. Typically integers will wrap, which is very "un-natural".
I brief search did not show up nice answers describing these, so I rather attempt to answer this nicely here, for beginners.
The answer is false, of course, but why so?
Integers
In C, or any programming language providing some kind of integer type, this type does not mean it in the mathematical sense. In mathematical sense non-negative integers range from 0 to infinity. A computer, however has only limited storage, so integers necessarily are constrained to something less than infinity.
This alone proves that a + b > a and a + b > b can not be true all the time, since it can be set up so both a and b is less than the largest number the computer can represent in it's storage, but a + b is larger than that.
What exactly happens here, depends. Some mentioned wraparound, but that's not necessarily the case. The C language the first place defines integer overflow to be an undefined behaviour, that whatever, including fire and smoke, may happen if the code happens to step on it (of course in the reality that won't happen, but interpreting the standard strictly it could, as well as the breach of the space-time continuum).
I won't describe how wraparound works here since it is beyond the scope of the problem itself.
Floating point
The case here is again just the same like for integers: the key to understand why mathematics don't fully apply here is that the computer has a limited storage.
Floating numbers in the computers memory are represented much like scientific notation: a mantissa, and an exponent. Both of these have a fixed limited range depending on the type of the floating point variable.
In base 10, you may conceive this like you have the exponent ranging from 10 ^ -10 to 10 ^ 10, and the mantissa having like 4 fraction digits after the decimal point, always normalized.
With this in mind, check these example additions:
1.2345 * (10 ^ 0) + 1.0237 * (10 ^ 5)
5.2345 * (10 ^ 10) + 6.7891 * (10 ^ 10)
The first is an example where the result will equal one of the input numbers while both were larger than zero. The second is an example where the result is out of range.
The floating point representation computers use however is capable to represent infinity, and two at that: positive infinity and negative infinity. So while the first example passes as a proof, the second does not, since that addition's result is positive infinity.
However with this in mind, you could produce an another proofing example:
3.1416 * (10 ^ 0) + (+ infinity)
Of course the result is positive infinity, no matter what you add it to. And of course positive infinity is not larger than positive infinity, so proved again.

Why doesn't my code work when replacing 622.08E6 with 622080000?

I recently came across a C code (working by the way) where I found
freq_xtal = ((622.08E6 * vcxo_reg_val->hiv * vcxo_reg_val->n1)/(temp_rfreq));
From my intuition it seems that 622.08E6 should mean 622.08 x 106. From this question this assumption is correct.
So I tried replacing 622.08e6 with
uint32_t default_freq = 622080000;
For some reason this doesn't seem to work
Any thoughts or suggestions appreciated
The problem you are having (and I'm speculating here because I don't have the rest of your code) appears to be that replacing the floating point with an integer caused the multiplication and division to be integer based, and not decimal based. As a result, you now compute the wrong value.
Try type casting your uint32_t to a double and see if that clears it up.
The problem is due to overflow!
The original expression (622.08E6 * vcxo_reg_val->hiv * vcxo_reg_val->n1)/temp_rfreq (you have too many unnecessary parentheses though) is done in double precision because 622.08E6 is a double literal. That'll result in a floating-point value
However if you replace the literal with 622080000 then the whole expression will be done in integer math if all the variables are integer. But more importantly, integer math will overflow (at least much sooner than floating-point one)
Notice that UINT32_MAX / 622080000.0 ≈ 6.9. That means just multiply the constant by 7 and it'll overflow. However in the code you multiply 622080000 with 2 other values whose product may well be above 6. You should add the ULL suffix to do the math in unsigned long long
freq_xtal = (622080000ULL * vcxo_reg_val->hiv * vcxo_reg_val->n1)/temp_rfreq;
or change the variable to uint64_t default_freq = 622080000ULL;

Find the percentage that is one integer to another

I have two integers (amount of bytes of two files). One is always smaller if not the same than the other. I want to calculate the percentage that the smaller is of the bigger.
I'm using plain C. I've applied the math formula, but am getting always 0:
printf("%d\r", (current/total)*100);
Any ideas?
Try
printf("%g\r", (((double)current)/total)*100);
instead. Integer division always rounds towards zero. By converting one of the numbers to double first, you will trigger floating point division. If you would like to use integer arithmetic, you could also use
printf("%d\r", (100*current)/total);
which will print the percentage rounded down to the next integer.
Sven give you good advice.
If you want to keep your integers, do the multiplication before the division :
printf("%d\r", (current * 100) / total);
You will get a rounded result.
The integral division done with numerator < denominator always give 0. That's the explanation for your "always 0" problem. Multiplying by 100 before dividing get the integral part of your division (percentage)
my2c
I recommend scaling up the nominator before doing the division:
const float ratio = (100.f * current) / total;
Here, making the 100 a floating point literal will promote the calculation, so no explicit casts are necessary which is also a benefit.
Better to try:
printf("%lf\r", (((double)current)/total)*100);
Since answer will be in floating point.
Integer division rounds down, so if your answer is less than 1 you will get 0.
You could try something like this:
printf("%d\r", ((current*100)/total));
However you will always get an integer.
If you cast numerator to a float you will get float division and the right answer.
printf("%f\r", ((float)current/total * 100));
However you may want to truncate zeros after, for example, for 3 digits before the decimal and 2 after you can use:
printf("%3.2f\r", ((float)current/total * 100));
Check out:
http://www.cplusplus.com/reference/clibrary/cstdio/printf/

Resources