The most efficient way to divide a number into integer and decimal parts

I try to break the double into all its parts and lobes. My code works, but it is too slow, given that the microcontroller that I use does not have a special multiplication command in the assembly. For instance,

temp = ((int)(tacc - temp); // This line takes about 500us 

However, if I do,

 temp = (int)(100*(tacc-temp)); // This takes about 4ms 

I could speed up the microcontroller, but since I try to stay low, I am curious if this can be done faster. This is a small piece that I'm really interested in optimizing:

  txBuffer[5] = ((int)tacc_y); // Whole part txBuffer[6] = (int)(100*(tacc_y-txBuffer[5])); // 2 digits of fraction 

I remember that there is a quick way to multiply by 10 using shifts, so that:

 a * 10 = (a << 2 + a) << 1 

Perhaps I could nest this and get multiplication by 100. Is there any other way?

+4
source share
2 answers

I believe that the correct answer, which may not be the fastest, is this:

 double whole = trunc(tacc_y); double fract = tacc_y - whole; // first, extract (some of) the data into an int fract = fract * (1<<11); // should be just an exponent change int ifract = (int)trunc(fract); // next, decimalize it (I think) ifract = ifract * 1000; // Assuming integer multiply available ifract = ifract >> 11; txBuffer[5] = (int)whole; txBuffer[6] = ifract 

If integer multiplication is out of order, then your switching trick should now work.

If floating point multiplication is too stupid to just quickly edit the exponent, you can do it manually using bit twisting, but I would not recommend it as the first option. In any case, once you get the satisfied FP numbers, you can simply remove the mantissa or even complete the entire operation manually.

+2
source

I assume that you are working with paired. You can try to execute the double bit bitwise:

 double input = 10.64; int sign = *(int64_t *)&input >> 63; int exponent = (*(int64_t *)&input >> 52) & 0x7FF; int64_t fraction = (*(int64_t *)&input) & 0xFFFFFFFFFFFFF; fraction |= 0x10000000000000; int64_t whole = fraction >> (52 + 1023 - exponent); int64_t digits = ((fraction - (whole << (52 + 1023 - exponent))) * 100) >> (52 + 1023 - exponent); printf("%lf, %ld.%ld\n", input, whole, digits); 
+1
source

Source: https://habr.com/ru/post/1489931/


All Articles