Mathematical Calculation Error

byte blockData [16] = {"123"};
uint16_t data=0;
void setup()
{
Serial.begin(9600);

// First method
int d1,d2,d3;
d1 = int((blockData[2])-48) * pow(10,0);
d2 = int((blockData[1])-48) * pow(10,1);
d3 = int((blockData[0])-48) * pow(10,2);
Serial.println(d1);
Serial.println(d2);
Serial.println(d3);
// Second Method
int i = 0;
while(blockData[i]!= NULL)
{
i=i+1;
}
for(int k=1;k<=i;k++)
{
data = int((blockData[i-k])- 48) * pow(10,(k-1));
Serial.println(data);
}
}
void loop() {
a
}

Output:
3
20
100
3
20
99

Can somebody help me with the mathematical error I'm facing with the above two methods in code. In first method I'm getting right value but in Second method I'm getting 2 places correct but third value is always less than 1 and if increase the inputs more than 3 digits, all the values after 2nd value is less than one. But if I add them together to form an Integer value ,I'm getting only -1 to the resultant. i,e.
if,
input = "1234"

output:
Second method:
4
30
19
99

Summation = 1233

I'm all confused!!!!!
Note: The above code was executed on Arduino Uno.

The "a" in loop() function happened while updating the forum kindly ignore and remove that before you test this code.

pow is notorious.
Avoid it.

Please remember to use code tags when posting code.

pow() returns a type of double.

Floating point constants are often not exact. Floating point calculations lead to round off errors and are certainly not necessary or even useful for your purpose.

Use the integer constants 10 and 100 instead of pow(10,1) and pow(10,2), etc.

And use character constants instead of magic numbers, e.g. '0' instead of 48.

1 Like

Here are two ways to do it in integers.

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

  // First method
  int d1, d2, d3;
  d1 = int((blockData[2]) - '0');
  d2 = int((blockData[1]) - '0') * 10;
  d3 = int((blockData[0]) - '0') * 100;
  Serial.println(d1);
  Serial.println(d2);
  Serial.println(d3);

  // Second Method
  int multiplier = 1;
  int digits = strlen((const char *)blockData);
  for (int k = digits - 1; k >= 0; k--)
  {
    int data = (blockData[k] - '0') * multiplier;
    Serial.println(data);
    multiplier *= 10;
  }
}

...especially pow(10,0) :slight_smile:

Thank you

Thank you so much.

Please explain :slight_smile:

You need to round floating point values.
This is how I might do it using pow:

  int d1 = (blockData[2] - '0') * int (round (pow (10.0, 2.0)) ;

However I'd never ever use a floating point function for integer manipulations like this, I'd just maintain a power of ten in an integer variable:

int power = 1 ;
for (int i = 0 ; i < 3 ; i++)
{
  Serial.println ((blockData [2-i] - '0') * power) ;
  power *= 10 ;
}

Note the use of '0' as the value of the ASCII digit zero. Using 48 is less readable in this context as it forces the reader to know the ASCII code.

@ thehardwareman

void setup ()
{
  Serial.begin (115200);
  for (int base = 2; base < 6; base++) {
    for (int power = 1; power < 9; power++) { 
      Serial.print (base);
      Serial.print (F(" to the "));
      Serial.print (power);
      Serial.print (F(" = "));
      float result = pow (base, power);
      Serial.print (result);
      Serial.print (F(" ("));
      Serial.print (result, 5);
      Serial.println (F(")"));
    }    
  }
}

void loop () {}

Enjoy.

1 Like

image

2 Likes