Skip to content

Request: unsafe addition #22

@spcutler

Description

@spcutler

Thanks for the very useful library. I like the use of range tracking to ensure there is no overflow.

However, as a purely pragmatic matter this is not always what I want. Generally I expect multiples to act like 16x16=>32 and additions to work like 16+16=>16 (or 32+32=>32). For instance, say I'm performing a dot product on some S4x12 values: a.x*b.x + a.y*b.y + a.z*b.z. This produces an S10x24 value, which is definitely not what I want since my ESP32 only does 32-bit integer math!

I could add some extra casts and such, but that gets inconvenient, and in practice I already have to ensure my values don't overflow. And I am better able to keep track of this than the range tracker. Again with the dot product example, I know that the dot product between two normalized vectors is between -1 and 1, but the range tracker cannot know this.

I've put in a simple local fix, which is just this:

// returns the RANGE following an addition
// if FIXMATH_UNSAFE_ADDITION is set, the range is just the max of the inputs, so as not to require a larger output datatype
#ifdef FIXMATH_UNSAFE_ADDITION
  constexpr uint64_t rangeAdd(byte NF, byte _NF, uint64_t RANGE, uint64_t _RANGE) { return ((NF > _NF) ? FM_max(RANGE, (_RANGE<<(NF-_NF))) : FM_max(_RANGE, (RANGE<<(_NF-NF))));}
#else
  constexpr uint64_t rangeAdd(byte NF, byte _NF, uint64_t RANGE, uint64_t _RANGE) { return ((NF > _NF) ? (RANGE + (_RANGE<<(NF-_NF))) : (_RANGE + (RANGE<<(_NF-NF))));}
#endif

I'm not sure whether this fix fits in with your "philosophy" of the library (or even whether it's totally correct, though it works for me). Probably you'd have something else in mind. Regardless, thanks again!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions