CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 4 of 4
  1. #1
    Join Date
    Feb 2002
    Posts
    24

    Question Fixed point decimals

    I've decided not to use standard float variables in my program but instead I'm using fixed point decimals (16.16)

    The problem I've got is that I'm can't seem to find out how to multiply and divided to fixed point numbers.

    Does anyone have any example code that does this? All the code that I have found doesn't seem to give the correct result

    Many Thanks

  2. #2
    Join Date
    Feb 2003
    Location
    Brazil
    Posts
    335

    Whay did you decide that?

    I think you made not a good decision. float point decimals is, as I see, the best way to use the computer for calculating, just curious, whay did you decide that?

  3. #3
    Join Date
    Nov 2003
    Location
    Belgium
    Posts
    8,150
    I'm curious to as to why you want to use fixed point instead of floating points?

    Often people try to use fixed points to improve performance, but if fixed points are not implemented correctly, it could be the case that just using plain floating points are even beter. Also, keep in mind that floating point is getting beter and beter so in the long run it often isn't worth it to use fixed point calculations.
    If you really have a performance issue, the first I would do and the first everyone should do is try to optimize the algorithm your using and NOT the implementation of your algorihtm!
    Marc Gregoire - NuonSoft (http://www.nuonsoft.com)
    My Blog
    Wallpaper Cycler 3.5.0.97

    Author of Professional C++, 4th Edition by Wiley/Wrox (includes C++17 features)
    ISBN: 978-1-119-42130-6
    [ http://www.facebook.com/professionalcpp ]

  4. #4
    Join Date
    Sep 2002
    Posts
    1,747
    Is this something you need to code or just want to use. Many libraries out there have fixed-point classes for use (the gnu FixN classes, for example, are free in libg++) and you could search around and see which one suits your needs best. But if you must code it yourself, understand that normally some tricks are used to speed things up. That said, the method to use depends on your internal representation, but if you are using actual decimal representation (ie. base 10 strings with one "point" location), then the calculation starts fairly simple. Look at this

    ABC.DE
    w.xy
    ------------
    1234.5678

    In general, a multiplication of an m digit (bit / sized / etc.) number multiplied by an n digit number gives you m+n digits (the leading digit may be 0, though, for effective m + n - 1 at times). The decimal position follows the same rule. If number1 has decimal point at position d1 and number2 has its point at d2 (these are #s of digits to the right of the points), there will be d1 + d2 digits on the right of the multiplied.

    So the most simple step to maintain a fixed decimal is to truncate. You could cut short your entire calculation and assume no carries into those positions (since each position in result is a convolution sum plus a carry split mod base with a new carry calculated for next position -- in fact, you should work this out so you are familiar with the general form; it is a set of two, coupled iterative equations), which would save calculation time but introduce a lot of error. Or you could calculate the carry but only store the results at the fixed digit accuracy you desire. This latter option improves your error of the result to within one of the last position.

    Then you might consider rounding, which centers the error so that results of more complex expressions don't suffer the exponential bias of the truncated version. This also dampens the error terms as the square root of operands.

    Beyond that, you may need to look into storing error terms in your class during expression evaluation or other ways to reduce or express error if that is your goal. You can fft transform the convolutions as well, to speed up the calculation with the fast symmetries.

    Division is very similar. Here, you can start out using long division as taught in elementary school or you can implement a reciprocal multiply technique or something similar to piggyback some of your code from the multiplication. Long division is the method where you start with the digits of the divisor and enough digits of the dividend to be greater than the divisor (ignoring the decimal points and adding trailing zeros to the dividend as needed). You represent these as integral values and integral divide, giving a digit of the result placed over the unit location of the dividend's digit group used (thus fixing the location of the decimal point). You then multiply the divisor by this digit and subtract from the dividend digit group. Then you pull more digits from the dividend and repeat until you reach zero remainder from subtract and only zeroes remain in the dividend (again, this should be worked out so it is clear). Often, of course, there is no termination step, and so you again have the options as with multiplication (ie. you can truncate your result at the appropriate end of the fixed point calculation, or you calculate an extra digit and round).

    I hope that gives the basics...
    */*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/*/

    "It's hard to believe in something you don't understand." -- the sidhi X-files episode

    galathaea: prankster, fablist, magician, liar

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured