Giter Club home page Giter Club logo

Comments (6)

Pharap avatar Pharap commented on June 14, 2024

Unfortunately this is a limitation that I currently don't have a work around for.

Fixed point multiplication results in a type twice as large as the source type, which is then scaled back down to the appropriate type.
For example, in the case of UQ8x8 it results in a UQ16x16, which is then scaled back down to a UQ8x8 to give the final result.
(There's also a multiply function that doesn't scale back down, in case the larger precision is wanted for some reason.)

In the case of UQ32x32, which is backed by a uint64_t and similarly SQ31x32, which is backed by an int64_t, i.e. both require 64 bits to be stored.
When multiplying either of these, the resulting type would require 128 bits to be stored.
But there is no 128 bit type by default (i.e. no uint128_t or int128_t), so to fix the issue I'd have to either introduce one or introduce a workaround that can reliably achieve 128 bit multiplication.
That would mean implementing a multiplication algorithm instead of being able to rely on the compiler to generate the appropriate multiplication code, which would take a fair bit of research beforehand.


Truth be told, when I originally wrote this I wasn't anticipating people wanting to use the 64 bit-backed types because I wasn't aware of the ARM-based Arduino MCUs, I was only aware of the AVR-based ones which can only realistically achieve 32-bit backed, 16-bit backed ant 8-bit backed variations.

from fixedpointsarduino.

nunovilhena avatar nunovilhena commented on June 14, 2024

Hi,
Thanks for your reply!
That was what I was expecting about the multiplication issue!!!
However, I'd like to ask you about another issue!
If I do the multiplication:

SQ15x16 x = 320.153;
SQ15x16 y = 0.000200;
SQ15x16 z = 0.0;

z = x*y;

The result is z = 0.06349182 however the real value is 0.06403060, that means the error is 0.008. If you are using 16 bits for the decimal part, the resolution should be 2^-16 = 0.00001525878. Thus, why the error started in the thousandth part?
Best regards.
Nuno Vilhena

from fixedpointsarduino.

Pharap avatar Pharap commented on June 14, 2024

The error happens when the floats are first converted as well, not just during the multiplication.

320.153 gets stored as 320.1530151367187500 (320 + 10028/65536)
0.0002 gets stored as 0.0001983642578125 (0 + 13/65536)

320.1530151367187500 * 0.0001983642578125 = 0.063506915234029293060302734375
((320 + 10028/65536) * (0 + 13/65536) = (0 + 4161/65536))

So actually 0.0634918212890625 isn't too far off.

Unfortunately you'll always have some amount of error because of the difficulty of expressing decimal fractions in binary.

For example, you can't exactly store 0.153.
Using SQ15x16 the closest you can get is either:
10028 / 65536 = 0.15301513671875
10027 / 65536 = 0.1529998779296875


If you know that the integer part will have a limited range then you can improve the precision of the fractional part.
For example, if you know the integer part isn't going to exceed 2000 then you could make your own type alias using SQ11x20 = SFixed<11, 20>;, which would give you greater precision.

Using SFixed<11, 20> gets a final result of 0.0638113021850585.
Using SFixed<10, 21> gets a final result of 0.0639648437500000.
Using SFixed<9, 22> gets a final result of 0.0639648437500000.
(And so on.)

Even a full 32 bits of fraction would only be able to represent 0.153 as 0.1529999971389770.
In fact I'm not sure how many bits you'd need to actually manage to represent it properly using a fraction-over-power-of-two approach, it might not be possible.


Ultimately depending on what you're calculating, fixed points might not actually be the best solution.
Fixed points are better for dealing with smaller ranges of values.
If you need to cover a large range of values that have both a large integer part and a large fractional part then floating points probably are more suitable.

from fixedpointsarduino.

Pharap avatar Pharap commented on June 14, 2024

As it has been 5 days since the last post,
I'm considering closing this issue.

@nunovilhena,
Have I successfully answered your questions?
Is there something you think I should do to make this problem more obvious in the library documentation or the library source (e.g. give a clearer error message)?

from fixedpointsarduino.

nunovilhena avatar nunovilhena commented on June 14, 2024

Hello Pharap,
Sorry my late reply but this week is being very stressful for me!
About my question, yes, you have.
If you could include something to advise about those limitations, should be better yes. About the multiplication/ division limitations and how the conversions between float to fixed_point is done (to show why there are a error in the calculations with your library!
So, you can close this issue, many thanks!

Nuno Vilhena

from fixedpointsarduino.

Pharap avatar Pharap commented on June 14, 2024

It's ok, I wasn't trying to rush you.
I just thought you might have intended to reply and then forgotten because you had other things to do.
(I have sometimes forgotten to press 'send'/'comment' on messages before and only realised the next day.)

I have opened a second issue (#23) to remind myself to add a proper explanation.

As I have answered all your questions, I will close this issue.

from fixedpointsarduino.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.