obtain root square in p24FJ64GA702 using C languagehttps://www.microchip.com/forums/(c) Microchip30Re: obtain root square in p24FJ64GA702 using C language (1and0)XC16 also uses arithmetic shifts on signed integers.<br/> <br/>Comparing the disassembly listings of using uint32_t vs. int32_t variables, both unsigned and signed versions use the same number of instructions and cycles. The differences are unsigned uses logical shifts LSR and comparison conditions GTU and NC, while signed uses arithmetic shifts ASR and comparison conditions GT and LT.<br/> <br/>So, the conclusion is it's better to use unsigned, because it not only handles twice the input range but also avoids the infinite loop resulted from negative input. Also, use uint16_t, instead of int32_t, for the return type reduces two instructions and cycles.<br/>https://www.microchip.com/forums/FindPost/1148423Wed, 22 Jul 2020 14:39:22 GMTRe: obtain root square in p24FJ64GA702 using C language (1and0)<blockquote class="quote"><span class="original">NorthGuy</span><br/>On 8-bit PICs arithmetic shift would probably produce slightly longer code, but I don't think XC8 uses arithmetic shifts.<br/></blockquote><br/>XC8 does perform arithmetic shifts.<br/> <br/>That said, OP uses a PIC24. ;)<br/> <br/>https://www.microchip.com/forums/FindPost/1148394Wed, 22 Jul 2020 10:44:51 GMTRe: obtain root square in p24FJ64GA702 using C language (NorthGuy)For this particular program, if you declare the variables as signed, it will work for the range from 0 to 2147483647. If you declare them as unsigned, it'll work for the range from 0 to 4294967295.<br/> <br/>The only difference is in the comparison operator. It makes the difference in results. All other operators are the same either for signed or unsigned. Signed comparison is slightly longer on 8-bit PICs, but doesn't matter on most other CPUs.<br/> <br/>The right shift may be arithmetic in signed version, which doesn't affect the result in this particular program, but may produce different code. On 8-bit PICs arithmetic shift would probably produce slightly longer code, but I don't think XC8 uses arithmetic shifts.<br/> <br/>https://www.microchip.com/forums/FindPost/1148392Wed, 22 Jul 2020 10:22:50 GMTRe: obtain root square in p24FJ64GA702 using C language (1and0)<blockquote class="quote"><span class="original">LdB_ECM</span><br/>The return is linked to the temps .. change them back and forward between unsigned and signed. Look where the adds I mentioned are. What it isn't connected to is the type of the input variable which just determines if you end up with a signed/signed compare or an unsigned/signed compare and ultimately the range.<br/> <br/>Anyhow this has gone stupid I am out .. leave you to it .. really don't care that much.<br/></blockquote><br/>What's stupid is using signed values for a square root function. The input, temps, and output variables in that function should be unsigned. I'm not surprised at the timing, as I'd expect unsigned to be more efficient than signed.<br/> <br/>Edit: ... not to mention right shift of signed numbers has implementation-defined behavior. ;)<br/>https://www.microchip.com/forums/FindPost/1148373Wed, 22 Jul 2020 06:06:27 GMTRe: obtain root square in p24FJ64GA702 using C language (LdB_ECM)The return is linked to the temps .. change them back and forward between unsigned and signed. Look where the adds I mentioned are. What it isn't connected to is the type of the input variable which just determines if you end up with a signed/signed compare or an unsigned/signed compare and ultimately the range.<br/> <br/>Anyhow this has gone stupid I am out .. leave you to it .. really don't care that much.<br/>https://www.microchip.com/forums/FindPost/1148372Wed, 22 Jul 2020 05:44:07 GMTRe: obtain root square in p24FJ64GA702 using C language (1and0)<blockquote class="quote"><span class="original">LdB_ECM</span><br/>You have gone off on a tangent (you are talking about num being uint32_t) .... read again what he said and I commented which is the "return value".<br/></blockquote><br/>If it is just the "return value", then why did you write these:<br/><blockquote class="quote"><span class="original"></span><br>... the optimizer can do more with ints vs unsigned int where it has to be careful with overflows as they are defined.<br></blockquote><br>How can returning an unsigned value causes overflow?<br/> <br/>... and this<br><blockquote class="quote"><span class="original"></span><br>If you doubt it measure the speed of any of the C code above and then change the types to unsigned and ruin it again. On most CPU and C compilers it's 20-50% slower with unsigned.<br></blockquote><br>How can returning unsigned slower than returning a signed?<br/> <br/> <br/><blockquote class="quote"><span class="original"></span> <br/>So leave the return int signed and change the num interface to uint32_t and it will give you exactly the same range. The range is limited simply by the input type not the return type. You already noted above correctly the largest possible.<br/></blockquote><br/>The range of the return value is uint16_t, and it should be faster than returning an int32_t. ;)<br/> <br/>https://www.microchip.com/forums/FindPost/1148365Wed, 22 Jul 2020 04:12:10 GMTRe: obtain root square in p24FJ64GA702 using C language (LdB_ECM)You have gone off on a tangent (you are talking about num being uint32_t) .... read again what he said and I commented which is the "return value".<br/> <br/>So leave the return int signed and change the num interface to uint32_t and it will give you exactly the same range. The range is limited simply by the input type not the return type. You already noted above correctly the largest possible.<br/> <br/>I will take your word for the timing it isn't worth the effort even though I am a bit surprised because of the adds.<br/>https://www.microchip.com/forums/FindPost/1148363Wed, 22 Jul 2020 03:56:01 GMTRe: obtain root square in p24FJ64GA702 using C language (1and0)<blockquote class="quote"><span class="original">LdB_ECM</span><br/>The use of signed int on isqrt is because the MSB bit can't ever be set and the optimizer can do more with ints vs unsigned int where it has to be careful with overflows as they are defined. If you write it in assembler taking care of that yourself there is probably nothing in it.<br/></blockquote><br/>Why can't you take a square root on an integer value >= 2^31 (0x80000000uL)? I don't see any overflow in that function.<br/> <br/><blockquote class="quote"><span class="original"></span><br/>If you doubt it measure the speed of any of the C code above and then change the types to unsigned and ruin it again. On most CPU and C compilers it's 20-50% slower with unsigned. There may be rare compiler and CPU's that isn't the case but given the MSB bit can never be set so you generally just write it that way for portability.<br/></blockquote><br/>I just did a brief measure with the latest XC16 Compiler v1.50 and the speed is the SAME for both signed and unsigned ints. In fact, the function with unsigned ints works for all 2^32 integers, while the function with signed ints works for only the 2^31 non-negative integers and of course fails for the 2^31 negative integers.<br/> <br/> <blockquote class="quote"><span class="original"></span><br/>So short answer is you gain nothing by using unsigned but in many situations you may lose speed.<br/></blockquote><br>No, using unsigned int it is possible to take the square roots of ALL 32-bit integers and without loss of speed.<br/> <br/>Edit: If signed ints are used for this isqrt() and a negative value is passed in, the code will stick in an infinite loop inside the function. ;)<br/> <br/>https://www.microchip.com/forums/FindPost/1148357Wed, 22 Jul 2020 02:34:07 GMTRe: obtain root square in p24FJ64GA702 using C language (LdB_ECM)No such thing as any type of unsigned float type ... so irrelevant.<br/>The use of signed int on isqrt is because the MSB bit can't ever be set and the optimizer can do more with ints vs unsigned int where it has to be careful with overflows as they are defined. If you write it in assembler taking care of that yourself there is probably nothing in it.<br/> <br/>If you doubt it measure the speed of any of the C code above and then change the types to unsigned and ruin it again. On most CPU and C compilers it's 20-50% slower with unsigned. There may be rare compiler and CPU's that isn't the case but given the MSB bit can never be set so you generally just write it that way for portability.<br/> <br/>So short answer is you gain nothing by using unsigned but in many situations you may lose speed.<br/>https://www.microchip.com/forums/FindPost/1148326Tue, 21 Jul 2020 21:35:07 GMTRe: obtain root square in p24FJ64GA702 using C language (jtemples)I hadn't noticed they were returning a signed value from a square root function, which doesn't make much sense. But then, sqrt() also returns a signed value...<br/>https://www.microchip.com/forums/FindPost/1148325Tue, 21 Jul 2020 21:01:51 GMTRe: obtain root square in p24FJ64GA702 using C language (soleil_sword)thank you guys so much !!!<br/>I will try this code tomorrow ! <br/>https://www.microchip.com/forums/FindPost/1148316Tue, 21 Jul 2020 17:58:06 GMTRe: obtain root square in p24FJ64GA702 using C language (dan1138)Don't you guys know how to quibble. :)https://www.microchip.com/forums/FindPost/1148314Tue, 21 Jul 2020 17:19:34 GMTRe: obtain root square in p24FJ64GA702 using C language (1and0)<blockquote class="quote"><span class="original">jtemples</span><br/> <br/>1L << 30 since the target is signed. But yes, the Wikipedia article assumes a 32-bit platform.<br/></blockquote><br/>Smile: <img src="https://www.microchip.com/forums/upfiles/smiley/209.gif" alt="Smile" data-smiley="<img src="https://www.microchip.com/forums/upfiles/smiley/209.gif" alt="Smile" data-smiley="[:)]" />" /> So it should really be this:<br><pre class="prettyprint">uint16_t isqrt(uint32_t num) {<br> <br> uint32_t res = 0;<br /> uint32_t bit = 1UL << 30;<br /></pre><br/>https://www.microchip.com/forums/FindPost/1148313Tue, 21 Jul 2020 16:40:49 GMTRe: obtain root square in p24FJ64GA702 using C language (jtemples)<blockquote class="quote"><span class="original">1and0</span><br/></blockquote><br/>Have not tested that function, but shouldn't that be:<br/><br><pre class="prettyprint">uint16_t isqrt(uint32_t num) {<br> int32_t bit = 1UL << 30;</pre><br/></blockquote><br>1L << 30 since the target is signed. But yes, the Wikipedia article assumes a 32-bit platform.<br/>https://www.microchip.com/forums/FindPost/1148311Tue, 21 Jul 2020 16:30:57 GMTRe: obtain root square in p24FJ64GA702 using C language (1and0)<blockquote class="quote"><span class="original">dan1138</span><br/>An integer square root can be computed almost as quickly as a 32-bit divide.<br><br>This Wikipedia <a href="https://en.wikipedia.org/wiki/Methods_of_computing_square_roots" target="_blank" rel="nofollow" title="https://en.wikipedia.org/wiki/Methods_of_computing_square_roots">Methods of computing square roots</a> article you will find this code to compute an integer square root:<pre class="prettyprint">int32_t isqrt(int32_t num) {<br /> assert(("sqrt input should be non-negative", num > 0));<br /> int32_t res = 0;<br /> int32_t bit = 1 << 30; // The second-to-top bit is set.<br /> // Same as ((unsigned) INT32_MAX + 1) / 2.<br /></pre><br/></blockquote><br/>Have not tested that function, but shouldn't that be:<br><pre class="prettyprint">uint16_t isqrt(uint32_t num) {<br> <br> int32_t bit = 1UL << 30;<br /></pre><br/>https://www.microchip.com/forums/FindPost/1148309Tue, 21 Jul 2020 16:16:54 GMTRe: obtain root square in p24FJ64GA702 using C language (dan1138)An integer square root can be computed almost as quickly as a 32-bit divide.<br><br>This Wikipedia <a href="https://en.wikipedia.org/wiki/Methods_of_computing_square_roots" target="_blank" rel="nofollow" title="https://en.wikipedia.org/wiki/Methods_of_computing_square_roots">Methods of computing square roots</a> article you will find this code to compute an integer square root:<pre class="prettyprint">int32_t isqrt(int32_t num) {<br /> assert(("sqrt input should be non-negative", num > 0));<br /> int32_t res = 0;<br /> int32_t bit = 1 << 30; // The second-to-top bit is set.<br /> // Same as ((unsigned) INT32_MAX + 1) / 2.<br /><br /> // "bit" starts at the highest power of four <= the argument.<br /> while (bit > num)<br /> bit >>= 2;<br /><br /> while (bit != 0) {<br /> if (num >= res + bit) {<br /> num -= res + bit;<br /> res = (res >> 1) + bit;<br /> } else<br /> res >>= 1;<br /> bit >>= 2;<br /> }<br /> return res;<br />}</pre>This method tends to be fairly quick on controllers that use integer math libraries as it uses shifts not divides.<br/>https://www.microchip.com/forums/FindPost/1148301Tue, 21 Jul 2020 14:58:31 GMTRe: obtain root square in p24FJ64GA702 using C language (jtemples)Does the C sqrt() function not work for you?<br/>https://www.microchip.com/forums/FindPost/1148285Tue, 21 Jul 2020 11:40:16 GMTRe: obtain root square in p24FJ64GA702 using C language (crosland)See <a href="https://bfy.tw/OYoA" target="_blank" rel="nofollow">https://bfy.tw/OYoA</a><br/>https://www.microchip.com/forums/FindPost/1148284Tue, 21 Jul 2020 11:23:12 GMTobtain root square in p24FJ64GA702 using C language (soleil_sword)Hi,<br/>I'm trying to get the root square in p24FJ64GA702 using C language.<br/>The purpose is to process the readings from triaxial accelerometer/gyroscope/magnetometer.<br/>The sensor has x, y, z axis readings for each measurements. A common method is to calculate the root square using the following fomulae:<br/>Output = (x^2+y^2+z^2)^0.5;<br/>Here, x, y, z are all 16-bit integer. Output can be a 32-bit integer.<br/>I don't need a super high precision, anything that is simple to implement would be the best. (if the speed is faster, that would be even better, but that is not a hard requirement)<br/>thank you very much!<br/> https://www.microchip.com/forums/FindPost/1148281Tue, 21 Jul 2020 11:04:34 GMT