Cleaving a decimal value into its integer and fractional portions is a neat trick, one that relies upon C natural capability to thwack off the decimal portion of a float when it’s recast as an integer. Knowing about this conversion makes solving this month’s Exercise a whole lot easier.
Only two statements are added for my solution, shown below:
2022_05-Exercise.c
#include <stdio.h> int main() { float input,fractional; int integer; printf("Enter a decimal value: "); scanf("%f",&input); integer = (int)input; fractional = input - integer; printf("Value %f can be split in to %d and %f\n", input,integer,fractional ); return(0); }
The first statement provides the conversion:
integer = (int)input;
The int typecast converts float value input
into an integer, effectively lopping off the decimal portion. The second statement performs the math:
fractional = input - integer;
Variable fractional
is equal to the original value, input
, minus its decimal portion stored in integer
. The result is only the fractional value.
Here’s a sample run:
Enter a decimal value: 123.456
Value 123.456001 can be split in to 123 and 0.456001
As feared, you see the 001
hanging off the fractional portion of the value, a remnant of the float data type’s precision. Ugh.
I hope your solution met with success, and that you used the simple trick I did to achieve the result.
If you’ve been hanging around this blog a while, I wrote a similar Exercise back in February 2015. It dealt more with rounding functions, though one way to round down is to use the simple typecast shown in this exercise solution.
Alas, I don’t know of a standard library function that deals with removing the digital detritus like the 001 in 0.456001. It would be keen to have a function that limited precision to a certain range or would be smart enough to recognize a series of zeros at the end of a value and surgically tighten them up. Such a task I leave for you to explore on your own.
I thought casting to int rounded to the nearest integer, which is why I asked about floor. Bottom of the class again 🙁
Some languages and frameworks have binary coded decimal types but they’re slow. I think it’s best to just to use %.2f or whatever number of dp you want. Can you use a variable here instead of a hard-coded number?
I believe the int cast just extracts the integer portion from the BCD format. I tried to run some experiments to confirm that this is the case, but was unsuccessful.
>Can you use a variable here instead of a hard-coded number?
Yes, the format string argument in the printf() family of statements can be a string variable, allowing you to format the string kinda on-the-fly. I’ve done so a few times. I think, however, limiting the output (as you suggest) is a better option. For example, using
%.2f
in an snprintf() statement would suffice for most calculations.