IDE Arduino: 2*2/2=1 ?

Hi,
Board UNO, IDE (1.8.5 & 1.8.6(https://www.arduino.cc/download.php?f=/arduino-nightly-windows.zip)

uint8_t Number_1 = 228;  
uint8_t Number_2= 0;    

uint16_t num5000 = 255; 
uint16_t korr_VCC = 228; 
uint16_t result;
uint16_t mVAcc;

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

void loop(){
result = (Number_2<<8) | Number_1; 
mVAcc = num5000 * korr_VCC / result;
Serial.print(F("\tmVAcc: ")); Serial.println(mVAcc);
num5000++;
}

answer: 0-286, 0-287 !!! :o
Error calculations uint16_t.
If num5000 or korr_VCC = uint32_t then OK.

What is num5000 * korr_VCC when num5000 is 288 or larger?
Which values can uint16_t hold?

Is it difficult to run the example and see the result?
num5000 is just the number 5000 (means 5000 mV)

I have doubts that the IDE can be considered correct in other projects.

I wanted to get a simple power measurement:
ADMUX = _BV (REFS0) | _BV (MUX3) | _BV (MUX2) | _BV (MUX1);
ADCSRA | = _BV (ADSC); // Start conversion
while (bit_is_set (ADCSRA, ADSC)); // measuring
uint8_t low = ADCL; // must read ADCL first - it then locks ADCH
uint8_t high = ADCH; // unlocks both
What for to calculate so:
long result = (high << 8) | low;
result = my_vcc_const * 1023 * 1000 / result; or my_vcc_const * 1023000 / result; ??

uint8_t high + uint8_t low = uint16_t.

why do large numbers?
If:
float Real_Vcc = (korr_Vcc * 5.00 / result); // (in V)

Numbers with a floating point to calculate long, I want so:
mVAcc = korr_VCC * 5000 / result, where the same = my_vcc_const * 1023000 / result;

The result is correct only if korr_Vcc or num5000 = uint32_t (long)

I have doubts that the IDE can be considered correct in other projects.

The IDE is perfectly correct here. You chose the wrong data types for that calculation and it overflowed.

EmSerg:
I have doubts that the IDE can be considered correct in other projects.

The Arduino IDE uses the standard GCC compiler that is very widely used and very thoroughly tested. There may be bugs in it, but if so they will only arise in very very unusual circumstances.

If the choice is between a bug in your code (or mine) or in the GCC compiler then it is 99.999999999999999999% certain that it is is NOT in the compiler. Don't even waste time asking yourself is it possible.

...R

EmSerg:
Is it difficult to run the example and see the result?

Yes, not everybody always has an Arduino at hand and/or a PC.

EmSerg:
I have doubts that the IDE can be considered correct in other projects.

See other comments.

EmSerg:
The result is correct only if korr_Vcc or num5000 = uint32_t (long)

Using an 32 bit type forces the compiler to do the calculations with 32 bits; default is 16 bits calculations and your uint16_t overflows.

when you have the line

mVAcc = num5000 * korr_VCC / result;

and num5000 = 288 and korr_VCC = 228, that multiplication overflows 16 bits (65664) so it becomes 127 and then divided by 228 (result) which is 0 (integer division)

byte x = 228; // byte 0<X<255
int y=5000; // int 0<y<65535
int z; //

void setup() {
Serial.begin(9600);
z = x * y / x;
Serial.print(z);
}

RESULT IDE: z=113
correct value: int z=25888 or long 1140000.

Error IDE: the result is calculated not in Z, but in x or y.
correct value will be only if long x or long y.

Well then, that proves it. The GCC C++ compiler (for which BILLIONS of code lines have been successfully written) is wrong!!!

@EmSerg and his dinky little program are correct.

When we fix one error in the program, we add ten more. /Bug/

Version IDE 1.0; ........ 1.8.5; 1.8.6; ............ year 2020: version ??

Signed integer overflow is undefined behavior, so the results you see (or any results, for that matter) are "correct". Try changing int to uint16_t or unsigned int.

gfvalvo:
Well then, that proves it. The GCC C++ compiler (for which BILLIONS of code lines have been successfully written) is wrong!!!

@EmSerg and his dinky little program are correct.

The C or C++ language /preprocessor - when not told differently with a type or through a cast - performs operations for you as integers. On a target basic Arduino that means using 16 bit signed integer (and here it’s even done at compile time, your Arduino does not calculate anything since compiler can see the values won’t change)
This is the standard - so nothing wrong, you just failed to read the documentation

J-M-L:
The C or C++ language /preprocessor - when not told differently with a type or through a cast - performs operations for you as integers. On a target basic Arduino that means using 16 bit signed integer

This is the standard - so nothing wrong, you just failed to read the documentation

Did you miss my implied [sarcasm] [/sarcasm] tags?

irrelevant. look 1 post. uint16_t.

gfvalvo:
Did you miss my implied [sarcasm] [/sarcasm] tags?

I did miss it :slight_smile:

Hello!!??

int y = 5000; // int 0<y<65535

OOPS!

int y = 5000; // int 0<y<32767

228 * 5000 = 1,140,000

mod 32768 = 25,888

25,888 / 228 = 113

EmSerg:
byte x = 228; // byte 0<X<255
int y=5000; // int 0<y<65535
int z; //

void setup() {
Serial.begin(9600);
z = x * y / x;
Serial.print(z);
}

RESULT IDE: z=113
correct value: int z=25888 or long 1140000.

Error IDE: the result is calculated not in Z, but in x or y.
correct value will be only if long x or long y.

By my reckoning, the traditional result for x*y/x = y, so 5000 if we neglect any overflows. But the intermediate calculation overflows, so we get a different result…

int is -32K ~ 32K-1, not 0~64K - 0~64K is unsigned int.

The issue is that the intermediate calculations are done as signed integers.

So 228*5000 = 1140000. This overflows, so the intermediate value is 25888. Then that gets divided by 228, yielding 113.

Operands are type promoted to the larger of the two types involved, so declaring x or y as a long (or casting one of them to a long when you do the math, eg, z=((long) x)*y/x will result in the math being done as longs, so you get the “correct” result here.

unsigned int != uint16_t ?? (65535)

byte x = 228;
word y =5000;
word z;
z = x * y / x;
result IDE: 113

Yes. unsigned int is uint16_t

Before you criticize the compiler again, do the math.

1,140,000 mod 65,536 is still 25,888