Giter VIP home page Giter VIP logo

Comments (7)

RobTillaart avatar RobTillaart commented on June 9, 2024 1

should been int32_t my mistake

long is 32 bit on Leonardo and I expect too on ESP.

These 'intermediate overflows' happen sometimes when porting code or when mixing unsigned and signed math.
Typical solution is to make intermediate values "big" enough.
If that is not possible one needs to rewrite the algorithm so all (intermediate) variables stay within a defined range.

from multimap.

RobTillaart avatar RobTillaart commented on June 9, 2024 1

Similar things can happen when e.g. a time variable overflows, most famous is millis() after some 49.7 days. or micros() after ~70 minutes. If you math is not prepared to handle the overflows correctly strange values may pop up.

Recently I read about a bug that occurred every ~25 days, which was almost in sync with the moon cycle so people were quite amazed. In the end it was a mix of millis() overflow combined with signed/unsigned math mixture.

from multimap.

satoer avatar satoer commented on June 9, 2024

Just tried the same code on a ESP32. This resulted in the expected outcome:

0: 0
1: 0
2: 0
3: 1
4: 1
5: 2
6: 2
7: 3
8: 3
9: 4
10: 4

...

500: 249
501: 249
502: 250
503: 250
504: 251
505: 251
506: 252
507: 252
508: 253
509: 253
510: 254
511: 254
512: 255

truncated for readability

from multimap.

RobTillaart avatar RobTillaart commented on June 9, 2024

Hi Satoer,

The explanation is probably quite simple, the size of an int is 16 bit on a Leonardo and 32 bit on an ESP32
What you see is that an intermediate result in the math became larger than 32767 and caused overflow and sign flipping.

you can verify my hypothesis with the sketch below.

void setup()
{
  Serial.begin(115200);
  Serial.println(sizeof(int));
}

void loop()
{}

Solution for your sketch

#include "MultiMap.h"
int32 In[]   = { 0  ,   512};
int32 Out[]  = { 0  ,   255};

void setup() {
  Serial.begin(9600);
}

void loop() {
  for (int i = 0; i <= 512; i++) {
    int mapValue = multiMap<int32>(i, In, Out, 2);  // <<<<<<<<<<< make it explicit 32 bits integers.
    Serial.println(String(i) + ": " + String (mapValue));
  }
  delay(10000);
}

from multimap.

RobTillaart avatar RobTillaart commented on June 9, 2024

We can try to check the input value of 129 (which was the first to fail

int In[] = { 0 , 512};
int Out[] = { 0 , 255};

As there is only one segment, the output = outmin + (input * (outmax - outmin)) / (inmax - in min)

output = 0 + (129 * ( 255 - 0)) / (512- 0)
output = (129 * 255) / 512
output = 32895 / 512 <<<<< here it happens 32895 > 32767 so overflow.

32895 flips to - (65535 - 32685) = -32640

output = -32640 /512
output = - 63 exactly what you got.

So always check intermediate math results if unexpected values pop up (even when most look OK).

from multimap.

satoer avatar satoer commented on June 9, 2024

First code had output: 2

Second code received an error:
'int32' does not name a type

Changed every 'int32' to 'long' and it fixed the problem! The outcome is as suspected. Thank you, this was driving me crazy.

from multimap.

satoer avatar satoer commented on June 9, 2024

Thanks Rob, You've been really helpful, and got my program working. Didn't suspected a overflow because the values are well below a 16 bit integer. I didn't took intermediate results in consideration though.

from multimap.

Related Issues (3)

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.