Why does this integer division yield 0? - c

Could someone tell me why the following code is outputting 0 at the marked line?
It seems as if everything is correct but then when I try to get the result near the end it's giving me 0 each time.
#include <stdio.h>
int main() {
// Gather time-lapse variables
int frameRate, totalLengthSecs;
printf("How many frames per second: ");
scanf("%i", &frameRate);
printf("--> %i frames confirmed.", frameRate);
printf("\nDesired length of time-lapse [secs]: ");
scanf("%i", &totalLengthSecs);
printf("--> %i seconds confirmed.", totalLengthSecs);
int totalFrames = frameRate * totalLengthSecs;
printf("\nYou need %i frames.", totalFrames);
// Time-lapse interval calculation
int timeLapseInterval = totalLengthSecs / totalFrames;
printf("\n\n%i", timeLapseInterval); // <-- this prints 0
return 0;
}

In short: Integer division truncates
You need the following:
double timeLapseInterval = (double) totalLengthSecs / (double)totalFrames;
printf("\ntimeLapseInterval : %f \n", timeLapseInterval);

You are performing integer math.
Math between two integers will produce an integer. And the result will be rounded towards zero.
This line:
totalLengthSecs / totalFrames;
Is likely producing a result that's between 0 and 1. And getting rounded to 0

You are printing integers and therefore it will round down the value.
timeLapseInterval / totalFrames will be (1 / frameRate) which will be < 1 unless frameRate is 1 (or 0 in which case you have an error dividing by 0)

When you divide 2 numbers in C and the denominator is integer, the compiler intends it as an integer division. Therefore, if you divide 1 divided 2, it returns zero and not 0.5
Moreover, your output variable is an integer too, hence, if you expect decimal outputs, you won't get it.
You can fix it by doing:
float timeLapseInterval = totalLengthSecs / (float)totalFrames;
printf("\n\n%f", timeLapseInterval);
I hope this helps

Related

How to set the level of precision for the decimal expansion of a rational number

I'm trying to print out the decimal expansion of a rational number in C. The problem I have is that when I divide the numerator by the denominator I lose precision. C rounds up the repeating part when I don't want it to.
For example, 1562/4995 = 0.3127127127... but in my program I get 1562/4995 = 0.312713. As you can see a part of the number that I need has been lost.
Is there a way to specify C to preserve a higher level of decimal precision?
I have tried to declare the result as a double, long double and float. I also tried to split the expansion into 2 integers seperated by a '.'
However both methods haven't been successful.
int main() {
int numerator, denominator;
numerator = 1562;
denominator = 4995;
double result;
result = (double) numerator / (double) denominator;
printf("%f\n", result);
return 0;
}
I expected the output to be 1562/4995 = 0.3127127127... but the actual output is 1562/4995 = 0.312713
The %f format specifier to printf shows 6 digits after the decimal point by default. If you want to show more digits, use a precision specifier:
printf("%.10f\n", result);
Also, the double type can only accurately store roughly 16 decimal digits of precision.
You need to change your output format, like this:
printf("%.10lf\n", result);
Note two things:
The value after the . specifies the decimal precision required (10 decimal places, here).
Note that I have added an l before the f to explicitly state that the argument is a double rather than a (single-precision) float.
EDIT: Note that, for the printf function, it is not strictly necessary to include the l modifier. However, when you come to use the 'corresponding' scanf function for input, it's absence will generate a warning and (probably) undefined behaviour:
scanf("%f", &result); // Not correct
scanf("%lf", &result); // Correct
If printing is all you want to do, you can do this with the same long division you were taught in elementary school:
#include <stdio.h>
/* Print the decimal representation of N/D with up to
P digits after the decimal point.
*/
#define P 60
static void PrintDecimal(unsigned N, unsigned D)
{
// Print the integer portion.
printf("%u.", N/D);
// Take the remainder.
N %= D;
for (int i = 0; i < P && N; ++i)
{
// Move to next digit position and print next digit.
N *= 10;
printf("%u", N/D);
// Take the remainder.
N %= D;
}
}
int main(void)
{
PrintDecimal(1562, 4995);
putchar('\n');
}

how to divide the float number into 2 or 3 pieces

So I just received my paper. its said if the input number is 0.001001001 (repeated) it's gonna print 0.001..., if it's 0.015015015, then 0.015... as a print, if the number is 998 its should be 0.998... my idea is to divide it into something like 2 pieces but im still cant figure its out. thanks
scanf("%f",&num1);
scanf("%f",&num2);
scanf("%f",&num3);
num1 = floor(1000*(num1/999))/1000;
num2 = floor(1000*(num2/999))/1000;
num3 = floor(1000*(num3/999))/1000;
printf("%.3f...\n",num1);
printf("%.3f...\n",num2);
printf("%.3f...\n",num3);
input = 3 integers that divide to 999, the value is below 999
output = the result, if the result repeated (0.001001001) then its going to print out 0.001...
sample :
input = output
3 = 0.003...
10 = 0.010...
998 = 0.998...
Note: I tried it with the floor so i guess there's something error about my logic
Since the value is below 999, 999 not included, just read the integer, and print it with 0.%03d...:
int num;
scanf("%d", &num);
printf("0.%03d...\n", num);
The conversion specification %03d will print the given integer in base-10, with leading zeroes prepended so that it is at least 3 characters wide. For 3, it will print 003, for 10 it will print 010 and for 976 it will print 976.
What you specifically cannot do this with are floats. Floats in your computer are binary numbers and they cannot precisely produce decimal fractions... nor can they do infinite precision.
Ifx is near some 0.abcabcabc... pattern, scale is by *999 and then /1000.
abc.abcabc... 1000x
- 0.abcabcabc... 1x
-------------------
abc. 999 x
/ 1000
-------------------
0.abc
Mathematically this works to exact 3 digits. Yet we are working with double.
double is usual encoded as binary64 and can not exactly represent, 0.001..., 0.015..., 0.998... and so the above idea will result in values very near the intended. The * 999 and / 1000 steps may impart a small departure from the mathematical result too.
int cajunb_print(double x) {
printf("(before %.*e) ", DBL_DECIMAL_DIG, x);
x = x * (1000 - 1) / 1000;
printf("(after %.*e) ", DBL_DECIMAL_DIG, x);
return printf("%.3f...\n", x);
}
int main(void) {
cajunb_print(0.001001001001001001);
cajunb_print(0.015015015015015015);
cajunb_print(0.998998998998998998);
return 0;
}
Output
(before 1.00100100100100099e-03) (after 1.00000000000000002e-03) 0.001...
(before 1.50150150150150149e-02) (after 1.49999999999999994e-02) 0.015...
(before 9.98998998998999022e-01) (after 9.97999999999999998e-01) 0.998...

C - pow function unexpected behavior

This is a program to find number of digits.
Here is my code:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main() {
int i = 0, n;
printf("Enter number: ");
scanf("%d", &n);
while ((n / pow(10, i)) != 0) {
i++;
}
printf("%d", i);
}
This program gives 309 as the output (value of i) on any input. However, if I store the value of pow(10, i) in another variable and put it in while loop, I get the correct output. Please help!
C++ uses the most precise type (when types are mixed) when doing a calculation or evaluation, and here you are effectively mixing a double with an int. You are dividing a user input number by a very large exponential number.
This in theory will never be zero, no matter how big the divisor gets. So, the theoretical result should be infinite. However, due to the limits of a double (which is returned by pow), it will still eventually approximate zero.
If you store the return of pow in an integer, you will no longer be mixing types and will effectively be working out the number of digits or what the approximate log base 10 is (any integer divide by a larger integer will equal zero).
Change:
while( ( n / pow(10,i) )!=0 ){
To:
while( ( n / pow(10,i) ) >= 1 ){
pow returns double and therefore the full result is double and the fractional part will be always non-zero until running out of exponent possible values which is 309 (translated to decimal, binary is 1024).

Simple division of odd numbers not working in C programming

I'm sure I'm missing something extremely simply since I'm very new to this, but for some reason when I divide an odd number by 2 and then multiply the result, the program will only multiply by the number rounded down, for example when I divide 5 by 2 and then multiply that, it only multiplies it by 2, not even 2.5. What I am eventually trying to do is have it so it rounds up so that dividing 5 by 2 would become 3, but for whatever reason it rounds down now automatically. Here's my code:
#include <stdio.h>
#include <math.h>
int main() {
int num_containers;
float price, total, num_half;
printf("What is the cost of one container?\n");
scanf("%f", &price);
printf("How many containers are you buying?\n");
scanf("%d", &num_containers);
num_half = num_containers / 2;
total = num_half * price;
if(num_containers % 2 == 0)
printf("The total cost is $%.2f.\n", num_containers / 2 * price);
else
printf("The total cost is $%f.\n", num_containers / 2 * price);
return 0;
}
num_containers is defined as int, when you divide it by 2 it is rounded down.
The expression
num_containers / 2;
is evaluated as integer division since both operands are integers, resulting in an integer. There's no way to represent the remaining 0.5 in an integer, so it is lost.
For comparison, the expression
0.5 * num_containers;
includes a floating-point literal, so num_containers is promoted to a double first, and the result is a double (num_containers / 2.0 does the same).
Since everything apart from num_containers is a float, skipping the intermediate value would have worked:
total = num_containers * price / 2;
Note, in order to force rounding up, you can either do it explicitly with ceil
total = ceil(num_containers / 2.0) * price;
or stay in integer land and simply add one:
int more_than_half = (num_containers + 1) / 2;
The variable num_containers is an integer, and so the expression num_containers / 2 will resolve to a rounded integer value. If you declare it as float num_containers, you should get the desired result, or you can cast it as a floating point value whenever you use it in an expression. For example:
num_half = (float) num_containers / 2;
If you want a rounded division in integer arithmetic, add an adjustment before doing the divide. For example to divide by 10 and round, add 5 first. In your case of dividing by 2
num_half = (num_containers + 1) / 2;
Which will round 5 / 2 up to 3.
It's because num_containers is defined as an int. If you do operations including an int and a float, the result will become a float. You're dividing an int by an int, so the result is an int.
If you want a float result, first cast num_containers to a float, or, if you're always dividing by the literal '2', change it to 2.0f.

How to get the integer and fractional part of a decimal number as two integers in Arduino or C?

How do I convert 30.8365146 into two integers, 30 and 8365146, for example, in Arduino or C?
This problem faces me when I try to send GPS data via XBee series 1 which don't allow to transmit fraction numbers, so I decided to split the data into two parts. How can I do this?
I have tried something like this:
double num=30.233;
int a,b;
a = floor(num);
b = (num-a) * pow(10,3);
The output is 30 and 232! The output is not 30 and 233. Why and how can I fix it?
double value = 30.8365146;
int left_part, right_part;
char buffer[50];
sprintf(buffer, "%lf", value);
sscanf(buffer, "%d.%d", &left_part, &right_part);
and you will get left/right parts separately stored in integers.
P.S. the other solution is to just multiply your number by some power of 10 and send as an integer.
You can output the integer to a char array using sprintf, then replace the '.' with a space and read back two integers using sscanf.
I did it for float, using double as temporary:
int fract(float raw) {
static int digits = std::numeric_limits<double>::digits10 - std::numeric_limits<float>::digits10 - 1;
float intpart;
double fract = static_cast<double>(modf(raw, &intpart));
fract = fract*pow(10, digits - 1);
return floor(fract);
}
I imagine that you could use quadruple-precision floating-point format to achieve the same for double: libquadmath.
The 30 can just be extracted by rounding down (floor(x) in math.h).
The numbers behind the decimal point are a bit more tricky, since the number is most likely stored as a binary number internally, this might not translate nicely into the number you're looking for, especially if floating point-math is involved. You're best bet would probably be to convert the number to a string, and then extract the data from that string.
As in the comments, you need to keep track of the decimal places. You can't do a direct conversion to integer. A bit of code that would do something like this:
#include <stdio.h>
#include <math.h>
#define PLACES 3
void extract(double x)
{
char buf[PLACES+10];
int a, b;
sprintf(buf, "%.*f", PLACES, x);
sscanf(buf, "%d.%d", &a, &b);
int n = (int) pow(10, PLACES);
printf("Number : %.*f\n", PLACES, x);
printf(" Integer : %d\n", a);
printf(" Fractional part: %d over %d\n", b, n);
}
int main()
{
extract(1.1128);
extract(20.0);
extract(300.000512);
}
Produces:
Number : 1.113
Integer : 1
Fractional part: 113 over 1000
Number : 20.000
Integer : 20
Fractional part: 0 over 1000
Number : 300.001
Integer : 300
Fractional part: 1 over 1000
What about using floor() to get the integer value and
num % 1 (modulo arithmetic) to get the decimal component?
Then you could multiply the decimal component by a multiple of 10 and round.
This would also give you control over how many decimal places you send, if that is limited in your comm. standard.
Would that work?
#include <math.h>
integer_part = floor(num);
decimal_part = fmod(num,1)*10^whatever;

Resources