Fixed point , how to extract fractional part ?

Go To Last Post
14 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello guys , Today i decided to study the Fixed point math , so here is a code i am working on ... i am assuming that i have 2 variables x =1.2 and z =3.2 but they are scaled by 16 so X=19 and Z=51 , 

I want to Add X+Z and store the result in Result variable which is going to be equal to 70 which is in the form of UQ4_4(UQ4.4) iam working on unsigned Q ...

70 is represented in binary as 0100.0110 ,,, the decimal point is just virtual my problem is how can i get the fractional part? 
i did ANDing the 70 with 0x0F to extract the 4 fractional bits which is equal to 6 in decimal but the value should be 0.375 ... so when i divide 6 / 16 I get 0.375 .. the problem is how can i get 0.375 on AVR to display 4.375 which is an approximated result of adding 1.2 +3.2 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Moderator,

 

Please lock this Thread.

The OP has the same question running in the Mega sub-forum.

 

JC

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

can you give me a link to that forum that has the same question as mine?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

https://www.avrfreaks.net/forum/fixed-point-math-help-please

The Freaks, Compilers sub-forum!

 

https://www.avrfreaks.net/forum/fixed-point-math-help-please

The Freaks Mega & Tiny sub-forum!

 

You posted it, you should certainly know where and how many times you did so.

 

JC

 

Last Edited: Mon. Mar 23, 2020 - 07:30 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

when i posted it there , they told me this topic has nothing to do with AVR and post it in general programming forum ... so i posted it here , but i do not know how to delete it from AVR Forum 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I locked the other thread.

 

Muhammed,

You have been here long enough.  Don't play the noob card.  I moved the topic and locked the other thread.

 

Let's move on.

 

Jim

I would rather attempt something great and fail, than attempt nothing and succeed - Fortune Cookie

 

"The critical shortage here is not stuff, but time." - Johan Ekdahl

 

"Step N is required before you can do step N+1!" - ka7ehk

 

"If you want a career with a known path - become an undertaker. Dead people don't sue!" - Kartman

"Why is there a "Highway to Hell" and only a "Stairway to Heaven"? A prediction of the expected traffic load?"  - Lee "theusch"

 

Speak sweetly. It makes your words easier to digest when at a later date you have to eat them ;-)  - Source Unknown

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB, RSLogix user

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Do it on pencil and paper first, figure out what you need to do.

You can:

add/subtract integers

multiply integers 

perform left/right shifts

 

Using these items what are your steps?

 

Mult by16 is often rather poor (unless an exact match, then any mult is equally wonderful), use at least mult by 256 (1 part in 256).

 

However, her it is even simpler:

add 12 & 32 (decimal position assumed) , now you have 44  (really it represents 4.4)

simply convert this to ascii digits (binary to ascii routine) and insert a decimal point "4"  "." "4"  sent to lcd...NO math was used & you get the exact answer....why?  no number conversion was needed, only binary to ascii

 

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

Last Edited: Tue. Mar 24, 2020 - 04:26 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

doing some googling, I came across this: https://spin.atomicobject.com/20...

It seems to simplify the concepts, but an AVR may have problems with the 64 bit math needed in his examples.

I may be better to use a floating point lib.....

Hope it helps the OP.

Jim

 

 

(Possum Lodge oath) Quando omni flunkus, moritati.

"I thought growing old would take longer"

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

 

For only simple 4-bit fractional part you might choose a lookup table:

 

Coded as:

const __flash char * const frac_decimal[16] = {
    ".0",
    ".0625",
    ".125",
     etc,
     etc,
};

 

 

 

Last Edited: Mon. Mar 23, 2020 - 09:04 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I think the problem needs restated with more clarity...seems like he wants to add "1.2"  & "3.2"  so he can show "4.4" & is jumping through unneeded hoops  (like multiplying by 16) to get there.

The concept of an assumed decimal point should be mentioned & highlighted, since then no conversion calculations of any sort are needed.

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

Last Edited: Tue. Mar 24, 2020 - 12:48 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I think the main point is, you don't have to use a scaling factor that is a power of 2.

In the general case, it makes sense to use a scaling factor that is a power of 2, since all of the scaling/de-scaling operations then become multiplies or divides by power of 2.

 

In the OPs simple case, however, where all you are doing is adding a few values together and then display the complete result, it would make more sense to use a scaling factor that is a power of 10 eg. 10

It all depends on what you are trying to do.

 

MuhammedElmaghraby wrote:
70 is represented in binary as 0100.0110 ,,, the decimal point is just virtual my problem is how can i get the fractional part? 
i did ANDing the 70 with 0x0F to extract the 4 fractional bits which is equal to 6 in decimal but the value should be 0.375 ... so when i divide 6 / 16 I get 0.375

You understand correctly, the fractional part is 6 in units of 1/16, or looking at it another way it is 1/4 + 1/8 = 3/8 = 6/16.

Some suggestions have already been given as to how you could display this. I would question if you really need to display it to 3 or 4 places after the decimal point given that it is an approximation anyway.

 

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

MrKendo wrote:
where all you are doing is adding a few values together and then display the complete result, it would make more sense to use a scaling factor that is a power of 10

Indeed.

 

Example:

 

Instead of trying to mess about with 1.23 Volts, just treat it as 1230 milli Volts.

 

The decimal point can easily be re-positioned in the output routine.

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I would question if you really need to display it to 3 or 4 places after the decimal point given that it is an approximation anyway.

It seems you have the situation reversed...the OP mistakenly believes he needs to do some approximation calculations using a limited precision result, when in fact he can get an exact answer, using no approximation at all. 

When in the dark remember-the future looks brighter than ever.   I look forward to being able to predict the future!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

avrcandies wrote:

I would question if you really need to display it to 3 or 4 places after the decimal point given that it is an approximation anyway.

It seems you have the situation reversed...the OP mistakenly believes he needs to do some approximation calculations using a limited precision result, when in fact he can get an exact answer, using no approximation at all. 

I don't know what the OP believes :)

I'm just making it clear that you can choose whatever scaling factor you like, in case the OP believed that you had to use a power of 2.

Your 'assumed decimal point' is simply choosing a scaling factor that is a power of 10, which I agree makes much more sense than using 16 in this simple example.