0

I want to split the float number to two separate part as real and non real part. For example: if x = 45.678, then my function have to give real= 45 and non_real=678. I have tried the following logic.

split ( float x, unsigned int *real, unsigned int *non_real)
{
   *real = x;
   *non_real = ((int)(x*N_DECIMAL_POINTS_PRECISION)%N_DECIMAL_POINTS_PRECISION);
    printf ("Real = %d , Non_Real = %d\n", *real, *non_real);
}

where N_DECIMAL_POINTS_PRECISION = 10000. It would give decimal part till 4 digits, not after.

It works only for specific set of decimal point precision. The code is not generic, it has to work for all floating numbers also like 9.565784 and 45.6875322 and so on. So if anyone could help me on this, it would be really helpful.

Thanks in advance.

1 Answers1

0

Use floor() to find the integer part, and then subtract the integer part from the original value to find the fractional part.

Note: The problem you're most likely having is that some numbers are too large for the integer part to fit in the range of an int.

--Added--

If and only if you are able to assume that an unsigned int is larger than the floating point representation's significand (e.g. 32-bit unsigned int and IEEE standard single-precision floating point with only 23 fractional bits, where "32 < 23" is true); then a number that is too large for an unsigned int can't have any fractional bits. This leads to a solution like:

if(x > UINT_MAX) {
    integer_part = x;
    fractional_part = 0;
} else {
    integer_part = (int)x;
    fractional_part = x - integer_part;
}
Brendan
  • 35,656
  • 2
  • 39
  • 66
  • Brendan I cannot use any libraries. – Nitin Nagaraj Mar 04 '17 at 09:01
  • @NitinNagaraj: Then I'd recommend asking a new question titled "How to implement `floor()` (using inline assembly or something)". ;-) – Brendan Mar 04 '17 at 09:03
  • Is there any other way to implement this? without floor(). – Nitin Nagaraj Mar 04 '17 at 09:06
  • Why cannot use a library? – Ed Heal Mar 04 '17 at 09:11
  • @NitinNagaraj: Yes; using other library functions (e.g. `ceil()`), or writing non-portable code (inline assembly and/or code that relies on the exact formats of integer and floating point types), or being excessively complex and slow and still losing accuracy. – Brendan Mar 04 '17 at 09:12
  • Can you please help me in writing that code? – Nitin Nagaraj Mar 04 '17 at 09:17
  • @NitinNagaraj: Added a "potentially least worst" alternative (that isn't portable and will break if `unsigned int` happens to be a perfectly legal 16-bit type). – Brendan Mar 04 '17 at 09:22
  • @NitinNagaraj: Note that you could use a different integer type (`unsigned long long`); and that I've assumed `x` is not negative, and that `integer_part` has to be `float` or `double` because of the "too large to fit in an integer type" problem. – Brendan Mar 04 '17 at 09:26
  • @Brendan: Got it! But one more thing how do you access that fraction part as an integer? The output should be _italic_ **bold** `code`fraction part = 94567 not 0.94567. I think th output from above code would be 0.94567 – Nitin Nagaraj Mar 04 '17 at 09:27
  • @NitinNagaraj: That part is easy - just multiply by a power of ten and convert (cast) to integer. As long as your power of 10 fits in an integer, the result will fit – Brendan Mar 04 '17 at 09:29
  • @Brendan: Is it possible without pow() function??i know its irritating, but i cannot use any libraries. – Nitin Nagaraj Mar 04 '17 at 10:15
  • @Brendan: I have solved it, first count number of decimal parts and take power of ten. Now API is working perfectly fine. Thanks – Nitin Nagaraj Mar 04 '17 at 11:14