simple Math

the result of this scetch:
23600=7200
20
3000=-5536
can anybody explain?

#include <UTFT.h>
#include <UTouch.h>

UTFT        myGLCD(ITDB32S, 38,39,40,41);   // Remember to change the model parameter to suit your display module!
UTouch      myTouch(6,5,4,3,2);

// Declare which fonts we will be using
extern uint8_t BigFont[];
extern uint8_t SevenSegNumFont[];
extern uint8_t SmallFont[];

#include <MemoryFree.h>;
#include <pgmStrToRAM.h>; // not needed for new way. but good to have for reference.


void setup()
{
  // Initial setup
  myGLCD.InitLCD();
  myGLCD.fillScr(VGA_NAVY);
  myTouch.InitTouch();
  myTouch.setPrecision(PREC_MEDIUM);

 myGLCD.setFont(BigFont);
myGLCD.setColor(VGA_RED); 
myGLCD.setColor(VGA_GREEN);
myGLCD.printNumI(2*3600,0,40);  
myGLCD.printNumI(20*3000,0,80);  

myGLCD.print(String(freeMemory()),150,160);
delay(5000);
}

void  loop(){  
}

kapelan:
the result of this scetch:
23600=7200
20
3000=-5536
can anybody explain?

Integer overflow.

The biggest number an int can hold is 32,767. After tht it rolls over to -32,768. Since 20 * 30000 is 60,000 it is too big. If you write 20 * 30000L then it will know to use long data types and it will calculate correctly.

Make sure the function you are sending that number to can take a long.

????
72000 overflow integer?

On arduino integer is 16 bits.

kapelan:
????
72000 overflow integer?

Arduinos Atmega controllers are 8-Bit controllers, with integers being 16 bit wide.

#define __STDC_LIMIT_MACROS
void setup() {
  Serial.begin(9600);
  Serial.print("INT16_MAX: ");Serial.println(INT16_MAX);
  Serial.print("UINT16_MAX: ");Serial.println(UINT16_MAX);
  Serial.print("INT32_MAX: ");Serial.println(INT32_MAX);
  Serial.print("UINT32_MAX: ");Serial.println(UINT32_MAX);
}

void loop() {}

Thank you,
I tried to verify float and long - it does not work as well:

#include <UTFT.h>
#include <UTouch.h>

UTFT        myGLCD(ITDB32S, 38,39,40,41);   // Remember to change the model parameter to suit your display module!
UTouch      myTouch(6,5,4,3,2);

// Declare which fonts we will be using
extern uint8_t BigFont[];
extern uint8_t SevenSegNumFont[];
extern uint8_t SmallFont[];

#include <MemoryFree.h>;
#include <pgmStrToRAM.h>; // not needed for new way. but good to have for reference.
#define __STDC_LIMIT_MACROS

void setup()
{
  // Initial setup
  myGLCD.InitLCD();
  myGLCD.fillScr(VGA_NAVY);
  myTouch.InitTouch();
  myTouch.setPrecision(PREC_MEDIUM);
 myGLCD.setFont(BigFont);
myGLCD.setColor(VGA_RED); 
myGLCD.setColor(VGA_GREEN);

long l=3*30000;
int s=l/3;
float f=3*30000;
myGLCD.printNumF(f,2,0,0);  
myGLCD.printNumI(s,0,20);  
myGLCD.print(String(s),40,40);  
myGLCD.printNumI(20*3000L,0,80);  

myGLCD.print(String(freeMemory()),150,160);
delay(5000);
}

void  loop(){  
}

only this line myGLCD.printNumI(20*3000L,0,80);
is working

unsigned int also is not working

unsigned int ui=4*30000;
s=ui/100;
myGLCD.printNumI(s,200,20);

kapelan:
unsigned int also is not working

unsigned int ui=4*30000;

s=ui/100;
myGLCD.printNumI(s,200,20);

That's not how you make it see them as longs. That works on the right side, treats them as ints, and then assigns the value to an unsigned int. The value on the right side overflows and that overflowed value gets put into the unsigned int. You have to put the L on the end of at least one of the constants to make the compiler do the math with longs.

Delta_G:

myGLCD.printNumI(20*3000L,0,80);

Let me make a guess: The function name printNumI() stands for "print numeric integer".

So if there is no funktion with the name myGLCD.printNumL(20*3000L,0,80); or similar to print "long" variables, you most likely have to:

  • format the long variable as a string
  • print the string to your display

this code does not work:

unsigned int ui=4*30000*1L;
int ss=ui/100;
myGLCD.printNumI(ss,200,20);

this is working:

long a=4;
long b=30000;
long c=a*b;
long d=c/100;
int res=d;
myGLCD.printNumI(res,100,80);

looks like if any value is integer it treats each of them as integer.
to work with long all of them should be long, right?

Rather than writing a lot of bad code, it would be far better if you read up on how c actually evaluates expressions. There are very clear, hard and fast rules about how numbers get parsed, and how expressions get evaluated - for example in what order the operations are carrried out - and when and how they get type-converted when evaluating expressions. Every one of the examples you think is "broken" is producing exactly the result it is supposed to. It is your code that is wrong. You MUST understand how c evaluates numbers and expressions in order to avoid getting erroneous results when working with different kinds of numbers.

Regards,
Ray L.

any link?

kapelan:
this code does not work:

unsigned int ui=4*30000*1L;

int ss=ui/100;
myGLCD.printNumI(ss,200,20);

You have that going into an unsigned int. A 16bit unsigned int can hold a value up to 65,535 before it overflows. As written, the right side gets evalutated to 120,000, but that's not going to make it fit into an unsigned int.

OK
it works:

long l=1L*3*30000;
int s=l/3;

this one - does not

long l=3*30000*1L;
int s=l/3;

i.e. compiler makes a decision by the first value

RayLivingston,
rather then critique a test code you can make a simple statement like "compiler makes a decision by the first value" or provide a link.

kapelan:
RayLivingston,
rather then critique a test code you can make a simple statement like "compiler makes a decision by the first value" or provide a link.

Use Google, and find ANY c language reference, and read the section on operators and expressions. When you're done, read it again, and again, until you understand it. It's FAR too much for anyone to explain here, and we could spend weeks explaining why each specific example you come up with is doing what it's doing. You can't learn a complex language just by asking others for help. You should take responsibility for doing some of the homework yourself. If you don't understand the rules, you'll never understand the behavior under all circumstances.

Regards,
Ray L.

kapelan:
RayLivingston,
rather then critique a test code you can make a simple statement like "compiler makes a decision by the first value" or provide a link.

I'm never really sure with type promotion, so I always just put the L on all of them.

Delta_G:
I'm never really sure with type promotion, so I always just put the L on all of them.

It's always best to force the conversions (by means of L for longs, adding decimal points for floats, or explicit type-casts), and make liberal use of parentheses in expressions, both to make the intent crystal clear, and to be certain expressions are evaluated, and precision maintained, as you intended.

Regards,
Ray L.