Some new "ideas for" core functions

Hello, as the title says, I have some new core functions I would like to add to future IDE updates.

  1. avg( ) "Average", this function will average the contents of a numeric array and return the value.
template<class T, size_t size> T avg(T(&x)[size])
{
  T tmp; 
  for(int i = 0, j = size; i < j; i++) 
  {
    tmp += x[i];
  } return (tmp/size);
}

Example sketch:

int myIntArray[5] = {25,324,420,1000,10};
float myFloatArray[5]={25,324,420,1000,10};

void setup()
{
  Serial.begin(115200);
  Serial.println(avg(myIntArray));
  Serial.println(avg(myFloatArray));
}

void loop() {}

Output:

355
355.80


  1. shed(), Nothing fancy, just a simple little function to get the values after the decimal point, of a float or double
float shed(float val)
{
   return val - long(val); // stupidly simple function
}

Example Sketch:

float val = 123.4567;

void setup(){
  Serial.begin(115200);
  Serial.println(shed(val),4);
}

void loop() {}

Output:

0.4567


  1. _map "templated map" this allows the map function to do ints, longs and floats with their expected outputs
template<class T> 
T _map(T x, T in_min, T in_max, T out_min, T out_max)
{
  return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}

Example Sketch:

void setup()
{ 
  Serial.begin(115200);
  for(byte i = 0; i < 101; i++)
  {
    Serial.print(map(i, 0, 100, 0, 10));
    Serial.print("\t");
    Serial.println(_map<float>(i, 0, 100, 0, 10));
    delay(10);
  }
}

void loop() {}

Output: See attachment

I'm still thinking of more I can make, but for now this is all I got.

results.txt (810 Bytes)

I would prefer to see this sort of thing in a tutorial so that readers can add to their knowledge rather than have the learning experience abstracted away from them.

...R

3 more, mirrorByte, mirrorInt and mirrorLong.

(I am at work and I don't have my Nano with me, so I cant give any real outputs)

mirrorByte:

unsigned char mirrorByte(unsigned char B)
{
  unsigned char h, l;
  static const unsigned char table[16] = {
    0x0, 0x8, 0x4, 0xC,
    0x2, 0xA, 0x6, 0xE,
    0x1, 0x9, 0x5, 0xD,
    0x3, 0xB, 0x7, 0xF
  };
  h = table[ (B >> 4) ]; 
  l = table[ B & 0x0f ] << 4;

  return (l | h ); 
}

mirrorByte(0x67) should return 0xE6

mirrorInt:

unsigned short mirrorInt(short B)
{  
  unsigned char h = mirrorByte(B >> 8 );
  unsigned short l = mirrorByte(B);
  
  return ((l << 8 ) | h);
}

mirrorInt(0x675D) -> 0xBAE6

mirrorLong:

unsigned long mirrorLong(long B)
{
  unsigned long h = mirrorInt(B >> 16);
  unsigned long l = mirrorInt(B);
  return ((l << 16) | h);
}

mirrorLong(0x675DAF39) -> 0x9CF5BAE6

I can't keep track of all the stuff that already exists - I find it easier to just add this kind of stuff right in the code when needed, figuring out how to do it as needed.

RE: shed
Any particular reason you not using...
http://www.cplusplus.com/reference/cmath/modf/

RE: _map
In the not too distant past, that would never have made it into the core. I suspect now it will be met with significant resistance.

Remember, the Arduino core is intended for people who have never programmed. More syntax to learn (the ) is a bad thing.

RE: shed
The typical name for such functions is frac or fract. fraction is probably the best choice for the intended audience.

RE: mirrorInt
Is that going to work on a 32 bit processor?

That issue did come to mind but thinking just for the arduino it should be fine. Maybe I can use sizeof as a multiplier instead of just having 8 as a shifting value.

I don't go through each and every function of the C library, but from what I see, mine is easier to understand. Plus the user doesn't need to know referencing to use it.

Update:

mirrorInt and mirrorLong functions fixed. (should be able to support 32 bit systems)

HazardsMind:

[quote author=Coding Badly link=topic=265085.msg1870557#msg1870557 date=1409954558]RE: mirrorInt
Is that going to work on a 32 bit processor?

That issue did come to mind but thinking just for the arduino it should be fine. Maybe I can use sizeof as a multiplier instead of just having 8 as a shifting value.[/quote]

Or you could use unsigned short.

Ok, I change it to unsigned short.

HazardsMind:

[quote author=Coding Badly link=topic=265085.msg1870547#msg1870547 date=1409954226]RE: shed
Any particular reason you not using...
http://www.cplusplus.com/reference/cmath/modf/

I don't go through each and every function of the C library, but from what I see, mine is easier to understand.[/quote]

And fails when the whole number exceeds the maximum value of a long.

Plus the user doesn't need to know referencing to use it.

You could modify your version to use modf and get the best of both.

I tried the modf function and compared it to a modified version of mine.

double intpart;
double param = 12.123456789;
double fractpart = modf(param , &intpart);
#define fract(x) float(x) - (unsigned long)x

void setup(){
  Serial.begin(115200);
  Serial.println(fractpart,6); // 4190 bytes
  Serial.println(fract(param),6); // 4092 bytes
}

void loop() {

}

Results:

0.123457
0.123457

No difference in results. You can try it yourself if you want to.

I was playing around with my templated map function and I found out that you can have both work even with the same name.

This is valid and the results are the same as the results I attached before.

template<class type> type map(type x, type in_min, type in_max, type out_min, type out_max);

void setup()
{ 
  Serial.begin(115200);
  for(byte i = 0; i < 101; i++)
  {
    Serial.print(map(i, 0, 100, 0, 10));
    Serial.print("\t");
    Serial.println(map<float>(i, 0, 100, 0, 10));
    delay(10);
  }
}

template<class type> type map(type x, type in_min, type in_max, type out_min, type out_max)
{
  return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
}

void loop() {}

@CB
Could you explain to me why the normal map function in the following sketch uses more memory then my templated map function as type long?

void setup()
{ 
  Serial.begin(115200);
  for(byte i = 0; i < 101; i++)
  {
     Serial.println(map(i, 0, 100, 0, 10)); // 2,794 bytes
      //Serial.println(map<long>(i, 0, 100, 0, 10)); // 2,562 bytes
  }
}

void loop() {}

Library!

Added these files to your normal libraries folder under the sketch folder, and add #include <Core_Ext.h> like so.

#ifndef Arduino_h
#define Arduino_h

#include <stdlib.h>
#include <string.h>
#include <math.h>

#include <avr/pgmspace.h>
#include <avr/io.h>
#include <avr/interrupt.h>

#include "binary.h"
#include <Core_Ext.h>

Save the file, and there you go.

Core_Ext.cpp (703 Bytes)

Core_Ext.h (950 Bytes)

So how exactly do you justify wanting "mirrorbyte" to be a core function, instead of sticking it in some obscure bit-twiddling library? (or FFT library?)

I put it in some obscure bit-twiddling library, just for now.

Besides, there is a one in a million chance they will ever see these functions, and a one in a billion chance these functions will be added.

We have been asking to have things added for years, and exactly how many of them were ever implemented?

If these functions help anyone, even just one person, I will be happy.

HazardsMind:
Could you explain to me why the normal map function in the following sketch uses more memory then my templated map function as type long?

Your template is compiled inline.