Math with very large numbers.

I am working on a RC Transmitter project and trying to add an Expo function.

I found a formula that with a little bit of tweaking works great in Excel.

Testing it out on an actual arduino has highlighted some problems. I am assuming that this is being caused by the fact that, although the number resulting from the formula is always in the region of 1000-2000, during the calculation some of the numbers get extremly large.

I have tried setting the number type to long long but i am still having issues.

Below is an extract of the formula with variables replaced with the actual values, this is on the extream limit of how high the variables will be.

Value1 = (70070070099) / (700700);

This doesn't work but the below sum does.

Value1 = 33957000000 / 490000

What do I need to do to be able to get the first calculation working?

Thanks.

Value1. Is that an Uno Int, or a Mega int, or an ESP32 int?

You might want to use long or unsigned long on a Uno..

I was having trouble signing in on PC so posted that from my phone, now my PC is signed in below is the simple bit of code I wrote out to try it.

long long Value1;
long Value2;

void setup()
{
  Serial.begin(9600);
  Serial.println("Test Begin");
  Value1 = (700*700*700*99) / (700*700);
  Value2 = Value1;
  Serial.println(Value2);
  Value1 = 33957000000 / 490000;
  Value2 = Value1;
  Serial.println(Value2);
}

void loop()
{
  
}

The monitor shows: -
Test Begin
0
69300

This test is currently running on an Arduino Nano

Check if the following sketch is useful!

void setup()
{
  Serial.begin(9600);
  unsigned long long x1 = 700;
  unsigned long long x2 = 700;
  unsigned long long x3 = 700;
  unsigned long long x4 = 99;
  unsigned long long x5 = 700;
  unsigned long long x6 = 700;
  unsigned long long x = (x1 * x2 * x3 * x4) / (x5 * x6); //x = 69300 = 0x10EB4
  long z = (long)x & 0x00000000FFFFFFFF;
  Serial.print(z, DEC); //shows: 69300
}

void loop()
{

}

On an Arduino Nano, the default for the right hand side of this expression is 16 bit integer, so the calculation overflows several times.

  Value1 = (700*700*700*99) / (700*700);

Fix it by declaring at least one number in each set of parens as long:

  Value1 = (700L*700*700*99) / (700L*700);

jremington:
On an Arduino Nano, the default for the right hand side of this expression is 16 bit integer, so the calculation overflows several times.

  Value1 = (700*700*700*99) / (700*700);

Fix it by declaring at least one number in each set of parens as long:

  Value1 = (700L*700*700*99) / (700L*700);

Just tried the following code as you suggested but it is still not outputting the same result.

long long Value1;
long long test = 700;
long Value2;

void setup()
{
  Serial.begin(9600);
  Serial.println("Test Begin");
  Value1 = (700L*700*700*99) / (700L*700);
  Value2 = Value1;
  Serial.println(Value2);
  Value1 = 33957000000 / 490000;
  Value2 = Value1;
  Serial.println(Value2);
}

void loop()
{
  
}

Monitor shows: -

Test Begin
-821
69300

This works:

long Value1;
long Value2;

void setup()
{
  Serial.begin(9600);
  Serial.println("Test Begin");
  Value1 = (700LL*700LL*700LL*99LL) / (700LL*700LL);
  Serial.println(Value1);
  Value1 = 33957000000UL / 490000UL;
  Serial.println(Value1);
}

void loop()
{
 
}

(70070070099) does not fit in a long; 70070070099 = 0x7E7FEB340; one nibble (the first 7) too much which gets thrown away.

Use long long (as shown above) or int64_t; printing might become tricky though.

When I try the code posted in reply #5, I get the same results and a warning. If you turn warnings on in File, Preferences you would see the warning.

C:\Users\...\arduino_modified_sketch_7015\sketch_jun01a.ino: In function 'void setup()':

C:\Users\...\arduino_modified_sketch_7015\sketch_jun01a.ino:10:25: warning: integer overflow in expression [-Woverflow]

GolamMostafa:
Check if the following sketch is useful!

Thanks for the pointer.

I have just done some testing and by changing two of my int's into long long the formula now works how I want it to.

I need to do a bit more comprehensive testing but it looks good so far.

Thanks.

GForce2010, do you see the answer ? The correct answer has been given by GolamMostafa and jremington.

The Arduino Uno supports 'int64_t' or 'long long' even if it is a 8-bit microcontroller. That is done by the GCC compiler. However, the Arduino functions do not support that.

Use 'int64_t' or 'long long' for the variables. You can force a value to be 'long long' with '700LL'. Do the calculation with all 'int64_t' or 'long long'.
If you are sure that the result will fit in a 32 bit long, then you can put it in a 'long' variable by casting it and then you can use the Arduino Serial.println() to print it.

This is my own variation (tested on a Arduino Uno):

void setup()
{
  Serial.begin(9600);
  Serial.println( "With int64_t");

  int64_t A = 700LL;
  int64_t B = 700LL;
  int64_t C = 700LL;
  int64_t D =  99LL;
  int64_t P = 700LL;
  int64_t Q = 700LL;

  int64_t Value1 = ( A * B * C * D ) / ( P * Q );

  // Serial.println does not support int64_t, make it a 'long'.
  long Value1print = (long) Value1;
  Serial.println( Value1print);
}

void loop()
{}

This has to be an XY problem. I can't imagine any reason you would need an "expo" function accurate enough to count the number of atoms in the universe, for an RC transmitter...

Everything is working now.

I just wrote up a quick program to output the entire range that the formula will be working with to a .csv file and got Excel to make a chart.

Every test shows a beautifully smooth exponential curve both above and below the linear value.

Thanks again.