Show Posts
Pages: [1]
1  Forum 2005-2010 (read only) / Bugs & Suggestions / Re: long int multiplcation bug on Arduino 0016 on: September 03, 2009, 10:00:39 pm
Aha..

I just got around to reading the playground main page:

"""
Version 4.3.0 has a major bug which affects multiplication of long int's. This is the default version in Ubuntu Intrepid (8.10). Check using "avr-gcc --version" and upgrade if necessary.
"""

I'll be upgrading now.  An apparently we all shoud!

Cheers,
--Adam  :smiley
2  Forum 2005-2010 (read only) / Bugs & Suggestions / long int multiplcation bug on Arduino 0016 on: September 03, 2009, 09:47:06 pm
Hello,

I have come across what appears to be a bug with long integer multiplication on my Arduino Duemilanove.  I am using Arduino 0016 on Ubuntu Linux.  I have written a test driver to reproduce my issue and am posting it here so other users can verify that they have the same issue and/or see if it is resolved on their systems.  

I have heard that avr-gcc version 4.3.0 (which is the version I have) had problems with some long int multiplications.  I will upgrade that on my system and see if that resolves the issue with multiplication that I have seen.  If that works I will report back with my success or failure issues with the new avr-gcc version.  Maybe upgrading to 0017 of the IDE will help; I'll check that too.

Has anyone else seen this or something similar to it out there?

Here is the output from my test driver:
[size=10]
Testing multiplcation of longs

testRoutine(): Got byte argument 13
testRoutine(): Multiplicaton Result a = 13000
testRoutine(): Value of b After assignment from byte b = 13
testRoutine(): Multiplicaton Result b = b * 1000 was: 65
   ERROR: Expected Result of 13000, got this instead: 65
testRoutine(): Multiplicaton Result b = byteArg * 1000 13000[/size]


And here is the source code to reproduce it:

Code:
// ///////////////////////////////////////////////////////////////////////////
//
// Arduino code for testing multiplication of long numbers.
// 20090903, Adam E. Hampton.  This code is released to the public domain.
//
// ///////////////////////////////////////////////////////////////////////////
//
// The purpose of this code is to illustrate some odd behavior I see with
// "unsigned long int" variables being cast in from a byte.  It appears that
// tyring to multiply an "unsignled long int" after assigning it a value from
// a byte variable produces unexpected results.  
//
// Seen on: Arduino Duemilanove with an ATMega 186 @ 20MHz,
//          using Arduino 0016 on Ubuntu Linux 8.10.
//
// ///////////////////////////////////////////////////////////////////////////

// ///////////////////////////////////////////////////////////////////////////
void setup () {

  Serial.begin(9600); // Serial output to the computer on pin 1.
  delay(50);

}

// ///////////////////////////////////////////////////////////////////////////
void loop () {

  Serial.println("");
  Serial.println("Testing multiplcation of longs");
  Serial.println("");

  // Test Case: multiply some stuff by powers of 10.
  byte myByte = 13;
  testRoutine(myByte);

  delay(1000);

}

unsigned long int testRoutine (byte byteArg) {

  Serial.print("testRoutine(): Got byte argument ");
  Serial.println(byteArg, DEC);

  unsigned long int a = 0;
  a = byteArg * 1000;

  // This works correctly.  
  Serial.print("testRoutine(): Multiplicaton Result a = ");
  Serial.println(a);
  if (a != 13000) {
    Serial.println("   ERROR: Expected Result of 13000 for a, got something else.");
  }

  // Next lets try a direct assignment from the byte argument.  The assignment works.
  unsigned long int b = 0;  
  b = (unsigned long int) byteArg;
  Serial.print("testRoutine(): Value of b After assignment from byte b = ");
  Serial.println(b);

  // Next try multiplying the long integer by 10^3.  This is where things break.
  b = b * 1000;

  Serial.print("testRoutine(): Multiplicaton Result b = b * 1000 was: ");
  Serial.println(b);
  if (b != 13000) {
    Serial.print("   ERROR: Expected Result of 13000, got this instead: ");
    Serial.println(b);
  }
  else {
    Serial.println("   Got correct response from b = b * 1000.");
  }

  // Just for the purpose of a sanity check we test the original case again,
  // just like it was done with the "a" variable: direct product of the byte arg
  // and an integer.
  b = 0;
  b = byteArg * 1000;

  Serial.print("testRoutine(): Multiplicaton Result b = byteArg * 1000 ");
  Serial.println(b);
  if (b != 13000) {
    Serial.print("   ERROR: Expected Result of 13000, got this instead: ");
    Serial.println(b);    
  }
  else {
    Serial.println("   Got correct response from b = byteArg * 1000.");
  }
  
  // Next check to see if multiplying b but 1 (identity) fixes the issue.
  b = 0;  
  b = (unsigned long int) byteArg;
  Serial.print("testRoutine(): Value of b after assignment from byte = ");
  Serial.println(b);

  // Next try multiplying the long integer by 1
  
  // *** WHEN Un-Commented this block crashes my arduino.  It never comes
  // back from the b = b * 1 operation correctly.  The next time b is touched
  // the micro freezes.
  // b = b * 1;
  // Serial.print("testRoutine(): Multiplicaton Result b = b * 1 is : ");
  // Serial.println(b);  
  // if (b != 13) {
  //   Serial.print("   ERROR: Expected Result of 13, got this instead: ");
  //   Serial.println(b);
  // } else {
  //   Serial.println("   Got correct response from b = b * 1.");
  // }// *** WHEN Un-Commented this line crashes my arduino:

  // 1234 * 1234 = 1522756.  This routine checks to see if the Arduino agrees.
  unsigned long int c = 0;
  c = 1234;
  c = c * c;
  Serial.print("testRoutine(): 1234 * 1234 in c = ");
  Serial.println(c);
  if (c != 1522756) {
    Serial.print("   ERROR: Expected Result of 1522756, got this instead: ");
    Serial.println(c);
  }
  else {
    Serial.println("   Got correct response from c = 1234 * 1234.");
  }

  // 12345 * 67890 = 838102050.
  // This routine checks to see if the Arduino agrees.
  Serial.println("testRoutine(): Check sanity of 12345 * 67890 = ? ");

  unsigned long int x = 12345;
  unsigned long int y = 67890;
  unsigned long int z = 838102050;

  unsigned long p = x * y;
  if (p != z) {
    Serial.print("   ERROR: Did not get the expected 838102050.  Got this:  ");
    Serial.println(p);
  }
  else {
    Serial.print("   Got correct repsonse, 838102050, in variable:  ");
    Serial.println(p);
  }

}

Pages: [1]