C giving wrong answer to calculation - c

I am coding a very simple program in C but I keep getting wrong answers to calculations that I am doing. The final output that I want needs to have no decimal places so I am using int as the data type even though the answer will not be an integer. Here is the code:
int numberOfInches = (100/254)*101;
I either get the answer 0 if I use int as the data type or crazy long numbers if I try using float or double. Any ideas on what I am doing wrong?

100 / 254
This is integer division, which will get 0. You then multiply by 101.
To do floating point division, at least one of the operands of / must be floating point:
int n = (int)((100. / 254.) * 101.);

When both operands of the / operator are integer, it performs integer division, i.e. the result is the quotient with the fraction part trucated. The result of 100/254 is less that 1, so it rounds down to 0.
You can either make one of the constants floating point:
(100.0/254)*101
Or you can do the division last:
(100*101)/254

You use an int. The results are rounded to the nearest int value:
100/254 = 0 THEN 0 * 101 = 0 SO, final result is 0.
I think you can do something like :
int numberOfInches = 100 * 101 / 254;
result: 100 * 101 = 10100 THEN 10100 / 254 = 39.7xxxxxx SO, final result is 40.

Obviously it will give 0.
int numberOfInches = (100/254)*101;
When it will calculated first it will evaluate inner bracket.
so (100/254) will be 0 And when you multiply 0 to 101, i.e 0*101 = 0.
It will be 0.
To get the correct output, use the following.
int numberOfInches =(int)((100.0/254)*101);

Division in parentheses is integer-type, so 100/254=0. If you want to calculate value with a fractional part try:
int numberOfInches = (100.0 / 254.0) * 101.0;

Why not using float ? try 100.0f/254.0f

Related

Save float result number to third digit, no rounding in C

How to round result to third digit after the third digit.
float result = cos(number);
Note that I want to save the result up to the third digit, no rounding. And no, I don't want to print it with .3f, I need to save it as new value;
Example:
0.00367 -> 0.003
N.B. No extra zeroes after 3 are wanted.
Also, I need to be able to get the 3rd digit. For example if it is 0.0037212, I want to get the 3 and use it as an int in some calculation.
0.00367 -> 0.003
A float can typically represent about 232 different values exactly. 0.00367 and 0.003 are not in that set.
The closest float to 0.00367 is 0.0036700000055134296417236328125
The closest float to 0.003__ is 0.0030000000260770320892333984375
I want to save the result up to the third digit
This goal needs a compromise. Save the result to a float near a multiple of 0.001.
Scaling by 1000.0, truncating and dividing by 1000.0 will work for most values.
float y1 = truncf(x * 1000.0f) / 1000.0f;
The above gives a slightly wrong answer with some values near x.xxx000... and x.xxx999.... Using higher precision can solve that.
float y2 = (float) (trunc(x * 1000.0) / 1000.0);
I want to get the 3 and use it as an int in some calculation.
Skip the un-scaling part and only keep 1 digit with fmod().
int digit = (int) fmod((trunc(x * 1000.0), 10);
digit = abs(digit);
In the end, I suspect this approach will not completely satisfy OP's unstated "use it as an int in some calculation.". There are many subtitles to FP math, especially when trying to use a binary FP, as are most double, in some sort of decimal way.
Perhaps the following will meet OP's goal, even though it does some rounding.:
int third_digit = (int) lround(cos(number)*1000.0) % 10;
third_digit = abs(third_digit);
You can scale the value up, use trunc to truncate toward zero, then scale down:
float result = trunc(cos(number) * 1000) / 1000;
Note that due to the inexact nature of floating point numbers, the result won't be the exact value.
If you're looking to specifically extract the third decimal digit, you can do that as follows:
int digit = (int)(result * 1000) % 10;
This will scale the number up so that the digit in question is to the left of the decimal point, then extract that digit.
You can subtract from the number it's remainder from division by 0.001:
result -= fmod(result, 0.001);
Demo
Update:
The question is updated with very conflicting requirements. If you have an exact 0.003 number, there will be infinite numbers of zeroes after it, and it is a mathematical property of numbers. OTOH, float representation cannot guarantee that every exact number of 3 decimal digits will be represented exactly. To solve this problem you will need to give up on using the float type and switch to a some sort of fixed point representation.
Overkill, using sprintf()
double /* or float */ val = 0.00385475337;
if (val < 0) exit(EXIT_FAILURE);
if (val >= 1) exit(EXIT_FAILURE);
char tmp[55];
sprintf(tmp, "%.50f", val);
int third_digit = tmp[4] - '0';

Moving decimal place to right in c

I'm new to C and when I run the code below, the value that is put out is 12098 instead of 12099.
I'm aware that working with decimals always involves a degree of inaccuracy, but is there a way to accurately move the decimal point to the right two places every time?
#include <stdio.h>
int main(void)
{
int i;
float f = 120.99;
i = f * 100;
printf("%d", i);
}
Use the round function
float f = 120.99;
int i = round( f * 100.0 );
Be aware however, that a float typically only has 6 or 7 digits of precision, so there's a maximum value where this will work. The smallest float value that won't convert properly is the number 131072.01. If you multiply by 100 and round, the result will be 13107202.
You can extend the range of your numbers by using double values, but even a double has limited range. (A double has 16 or 17 digits of precision.) For example, the following code will print 10000000000000098
double d = 100000000000000.99;
uint64_t j = round( d * 100.0 );
printf( "%llu\n", j );
That's just an example, finding the smallest number is that exceeds the precision of a double is left as an exercise for the reader.
Use fixed-point arithmetic on integers:
#include <stdio.h>
#define abs(x) ((x)<0 ? -(x) : (x))
int main(void)
{
int d = 12099;
int i = d * 100;
printf("%d.%02d\n", d/100, abs(d)%100);
printf("%d.%02d\n", i/100, abs(i)%100);
}
Your problem is that float are represented internaly using IEEE-754. That is in base 2 and not in base 10. 0.25 will have an exact representation, but 0.1 has not, nor has 120.99.
What really happens is that due to floating point inacuracy, the ieee-754 float closest to the decimal value 120.99 multiplied by 100 is slightly below 12099, so it is truncated to 12098. You compiler should have warned you that you had a truncation from float to in (mine did).
The only foolproof way to get what you expect is to add 0.5 to the float before the truncation to int :
i = (f * 100) + 0.5
But beware floating point are inherently inaccurate when processing decimal values.
Edit :
Of course for negative numbers, it should be i = (f * 100) - 0.5 ...
If you'd like to continue operating on the number as a floating point number, then the answer is more or less no. There's various things you can do for small numbers, but as your numbers get larger, you'll have issues.
If you'd like to only print the number, then my recommendation would be to convert the number to a string, and then move the decimal point there. This can be slightly complicated depending on how you represent the number in the string (exponential and what not).
If you'd like this to work and you don't mind not using floating point, then I'd recommend researching any number of fixed decimal libraries.
You can use
float f = 120.99f
or
double f = 120.99
by default c store floating-point values as double so if you store them in float variable implicit casting is happened and it is bad ...
i think this works.

Doing operations between an int and double

I have a homework assignment in basic C that is asking me to calculate certain expressions and then check my answers in a program. I can't seem to get any of these answers correct by my own calculations...
They want me to solve math problems using these variables:
int a = 2;
double b = 4.7;
int c = 3;
double d = 4.2;
Here's an example question:
int answer1 = b+a/c-d;
I understand that since it has an int operand then all the variables convert to an integer, so it should look something like this I think:
(4+2)/(3-4)
I got -6 as my answer when doing it by hand, but when I input it as code it gives me an answer of 0. Can anyone explain this? Am I doing the order of operations wrong? I simply don't understand how the computer gets 0 out of that. This is the easiest question in my homework and I don't have a clue. Please help!
Your expression
b+a/c-d
is the same as
b + (a/c) - d
Since both a and c are integers, then the quotient a/c is computed using integer division. That gives 2/3 = 0. So then you have:
b - d
This is calculated using floating point since b and d are double. The result is 0.5, which when assigned to the result int, is truncated to 0.
Your orders of operations is a bit off:
int answer1 = b+(a/c)-d;
int tmp1 = a/c; ---> 2/3 --> 0
int answer1 = 4.7 + 0 - 4.2 ----> 0.5 --> 0
http://www.cplusplus.com/doc/tutorial/typecasting/

Is Multiplying a decimal number where all results are full integers, considered Floating Point Math?

Sorry for the wordy title. My code is targeting a microcontroller (msp430) with no floating point unit, but this should apply to any similar MCU.
If I am multiplying a large runtime variable with what would normally be considered a floating point decimal number (1.8), is this still treated like floating point math by the MCU or compiler?
My simplified code is:
int multip = 0xf; // Can be from 0-15, not available at compile time
int holder = multip * 625; // 0 - 9375
holder = holder * 1.8; // 0 - 16875`
Since the result will always be a positive full, real integer number, is it still floating point math as far as the MCU or compiler are concerned, or is it fixed point?
(I realize I could just multiply by 18, but that would require declaring a 32bit long instead of a 16 bit int then dividing and downcasting for the array it will be put in, trying to skimp on memory here)
The result is not an integer; it rounds to an integer.
9375 * 1.8000000000000000444089209850062616169452667236328125
yields
16875.0000000000004163336342344337026588618755340576171875
which rounds (in double precision floating point) to 16875.
If you write a floating-point multiply, I know of no compiler that will determine that there's a way to do that in fixed-point instead. (That does not mean they do not exist, but it ... seems unlikely.)
I assume you simplified away something important, because it seems like you could just do:
result = multip * 1125;
and get the final result directly.
I'd go for chux's formula if there's some reason you can't just multiply by 1125.
Confident FP code will be created for
holder = holder * 1.8
To avoid FP and 32-bit math, given the OP values of
int multip = 0xf; // Max 15
unsigned holder = multip * 625; // Max 9375
// holder = holder * 1.8;
// alpha depends on rounding desired, e.g. 2 for round to nearest.
holder += (holder*4u + alpha)/5;
If int x is non-negative, you can compute x *= 1.8 rounded to nearest using only int arithmetic, without overflow unless the final result overflows, with:
x - (x+2)/5 + x
For truncation instead of round-to-nearest, use:
x - (x+4)/5 + x
If x may be negative, some additional work is needed.

Endless loop in C

Beginner here.
Why is this an endless loop ?
for (p = 0; p < 5; p += 0.5)
{
printf("p=%2.2f\n",p);
}
You see an endless loop because your p is of an integral type (e.g. an int). No matter how many times you add 0.5 to an int, it would remain 0, because int truncates double/fp values assigned to it. In other words, it is equivalent to a loop where you add zero on each step.
If you make p a float or a double, your problem would go away.
EDIT (Suggested by Oli Charlesworth's comment)
It is worth noting that using floats and doubles to control loops is discouraged, because the results are not always as clean as in your example. Changing the step from 0.5 (which is 2 to the negative power of 1) to 0.1 (which is not an integral negative power of 2) would change the results that you see in a rather unexpected way.
If you need to iterate by a non-integer step, you should consider using this simple pattern:
// Loop is controlled by an integer counter
for (int i = 0 ; i != 10 ; i++) {
// FP value is calculated by multiplying the counter by the intended step:
double p = i * 0.5;
// p is between 0 and 4.5, inclusive
}
I think it depends on how p is declared. If it's an integer type, p will always be 0 (because the result of 0 + 0.5 will be truncated to 0 every time) so the for will never stop.
a type conversion problem, float/double lost precision when assigned to an integer type.
P.S. It is really a very bad idea to use float/double in condition test. Not all floating point numbers in computers are accurate.
If p is a float or a double, there's nothing wrong with the code, and the loop will terminate.
If p is integer, the behaviour of the code is undefined since the format specifier in printf() is wrong.
when you add a double constant to integer variable, the double constant "becomes" integer. 0.5 becomes just 0. So you add 0 to p.

Resources