I tried to convert a number n-based to decimal with C. I have this code :
scanf("%d", &n);
scanf("%d %d %d %d", &n1, &n2, &n3, &n4);
dec = ( n1*pow(n,3) + n2*pow(n,2) + n3*pow(n,1) + n4*pow(n,0) );
It works fine until I enter n=10 & n1 n2 n3 n4=0 2 5 4.
The result should be 254, but the terminal showed 253. It turns out that starting from 200-999, the dec decreased by 1. However when I input 1000, the dec=1000. How can I fix this?
Most likely you have declared dec as an int while the function pow returns a double value. Here double is converted to an int an is rounded.
change to
double dec = ( n1*pow(n,3) + n2*pow(n,2) + n3*pow(n,1) + n4*pow(n,0) );
printf("%f",dec);
and the output will be
254.000000
While the code you have provided works fine on some implementations, example here, you could preferably not use the pow function since you are working with integers and non-negatives as power, and define your own intpow function. A naive implementation of that would be:
int intpow(int n, unsigned int power)
{
int result = 1;
while (power)
{
result *= n;
power--;
}
return result;
}
It just might be that that whole sum, which is a sum of doubles, turns out to be less than the number you expect to see by, say, 0.000013, of which the digits after the decimal point are discarded when being converted to get assigned to that int dec.
You could check the double result by changing the type of dec to double and printing it with the format specifier "%f". If that's the case, my recommendation would be a proper solution.
You may also try and think of better ways of base conversion, because there is one which doesn't require a (int)pow at all.
Related
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');
}
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).
I was trying to extract the exact fractional part from a floating point number. I tried with this:
float f=254.73;
int integer = (int)f;
float fractional = f-integer;
printf ("The fractional part is: %f", fractional);
But the output is: 0.729996. For this reason when I was doing this:
float f=254.73;
int integer = (int)f;
float fractional = f-integer;
int fractional_part_in_integer = ((int)(f*100)%100);
printf ("The value is: %d", fractional_part_in_integer);
It gives me 72 as output. But, I want to extract exactly 73 from the given number 254.73. I already know how to use %.2f during printf() function to print upto two decimal numbers. But in my code I don't want to print the number right now. I have some calculations with that fractional part as integer form i.e. 73.
So, my problem is how could I extract the fractional part from 254.73 so that I can get exact 73 as integer to do more calculations?
How to get the exact fractional part from a floating point number as an integer?
trying to extract the exact fractional part from a floating point number.
Use modf() or modff()
double modf(double value, double *iptr);
float modff(float value, float *iptr);
The modf functions break the argument value into integral and fractional parts, ...
C11 ยง7.12.6.12 2
#include <math.h>
double value = 1.234;
double ipart;
double frac = modf(value, &ipart);
A better approach for OP's need may be to first round a scaled value and then back into whole and fractional parts.
double value = 254.73;
value = round(value*100.0);
double frac = fmod(value, 100); // fmod computes the floating-point remainder of x/y.
double ipart = (value - frac)/100.0;
printf("%f %f\n", ipart, frac);
254.000000 73.000000
Ref detail: When OP uses 254.73, this is converted to the nearest float value which may be 254.729995727539....
float f = 254.73;
printf("%.30f\n", f);
// 254.729995727539062500000000000000
You can use sprintf and sscanf to print the value to a string and then extract the fraction. The %*d scans and discards the first integer of the formatted string. A dot is scanned and then the fraction.
#include <stdio.h>
int main( void)
{
char fp[30];
int fraction;
float f = 254.73f;
sprintf ( fp, "%.2f", f);
sscanf ( fp, "%*d.%d", &fraction);
printf ( "%d\n", fraction);
return 0;
}
The easiest way is to use standard library function ceil from <math.h>.
The float number 254.73 may be converted to 254.7299957275390625000000.
f-integer will give 0.7299957275390625000000.
Now multiply it by 100 and use ceil function to get the smallest integer value not less than 72.99957275390625000000.
int fractional_part_in_integer = ((int)ceil(fractional*100)) % 100;
UPDATE: As pointed in a comment by #Sneftel, the above suggested method in this answer will not work consistently.
A simple hack is to use round function from math.h to round the f and then extract the fractional part
float f=254.73;
int int_part = (int)f;
float fractional = round(f*100)/100 - int_part;
int fractional_part_in_integer = (int)(fractional*100);
printf("%d, %d\n ", int_part, fractional_part_in_integer);
Output:
254, 73
Take the number in string use the built-in function find() to find the position of ".".
#include <iostream>
using namespace std;
int main()
{
string f = "254.7356656";
int position = f.find(".");
cout << f.substr(position + 1);
return 0;
}
Output: 7356656
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;
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