Post Go back to editing

Is there a optimized Q1_23 to float function thats faster than the conv_RtoF() builtin function for SHARC+

Thread Summary

The user inquires about a faster method to convert Q1.23 integers to float compared to the built-in conv_RtoF function. The provided solution suggests directly scaling the value in C by dividing the integer by (1 << 24). The user notes a typo in the original question and asks for assembly code for a Conv_Q1.23ToFloat function, which is not found in the database.
AI Generated Content
Category: Software
Product Number: ADSP-21593

I am wondering if there is a faster way to convert integer to float if it is known to be Q1.24 format numbers, as compared to the builtin_conv_RtoF  which handles 32 bits input ? 

Thread Notes

Parents
  • Hi,

    Thank you for your inquiry.

    As you are aware "conv_RtoF" is hardwired for Q1.31 input, so Q1.23 values must be shifted or scaled to match its expected fractional bit alignment.

    Instead of shifting and calling conv_RtoF, you can directly scale in C:

    Below is sample code to cast the fract-typed argument to float type without using the built-in conversion.

    #include <stdint.h>
    #include <stdio.h>

    float q1_23_to_float(int32_t qval) {
    return (float)qval / (1 << 24); // direct scaling
    }

    int main() {
    int32_t qval = 0x00800000; // 0.5 in Q1.23
    float f = q1_23_to_float(qval);

    printf("Q1.23: 0x%08X -> float: %f\n", qval, f);
    return 0;
    }

    Hope this helps.

    Best Regards,
    Santhakumari.V

  • Thanks for the response. My understanding is that the cast to a float will invoke the built-in function and then a divide so not be more efficient than f=(float)(qval<<8). Also in the question I made a typo that should have said Q1.23 for the 24 bit inputs. In the long ago past  I think adi did provide a Conv_Q1.23ToFloat() function. If there is assembly code for that anywhere would be appreciated.

  • Hi,

    Unfortunately, we are unable to locate any information in our database regarding the function “Conv_Q1.23ToFloat()”. Could you please share how you obtained this reference, whether from Ezone or private support?

    If available, please provide the Ezone link or the support ticket ID.

    Waiting for your reply.

    Best Regards,
    Santhakumari.V

  • Sorry I don't have any more information, which is why I posted here. I am using the built-in function which works correctly. Was just looking at optimizing for mips by using a function that knows it only will operate on 24 bit data.

Reply Children
  • Hi JohnG,

    We're unable to find the assembly function you refer to. Nonetheless, the solution suggested by Santhakumari is good. The divide by 1<<23 will be executed as a single "scalb" instruction that modifies the float exponent, so does not incur the usual high cost of a divide operation. The only improvement would be to declare that function as inline so that you don't pay the cost of the call, and also correct the 23 vs. 24 shift as you noted:

    #include <stdint.h>
    #include <stdio.h>

    inline float q1_23_to_float(int32_t qval) {
      return (float)qval / (1 << 23); // direct scaling
    }

    int main() {
      int32_t qval = 0x00400000; // 0.5 in Q1.23
      float f = q1_23_to_float(qval);

      printf("Q1.23: 0x%08X -> float: %f\n", qval, f);
      return 0;
    }

    Michael.

  • Thanks for trying - your answer is good. Just not what I was interested in which was the assembly code that converts an int to a float.