Як правильно обробляти велику арифметику

просто питання, для чого потрібна проста відповідь. Як я ефективно та точно обробив велику кількість арифметичних кроків в arduino?

Наприклад, у мене є така функція коду:

void calc() {
  batterymoment = input*batterymass;
  totalmoment = 149650+batterymoment;
  buoyancymoment = buoyancymass*centrebuoyancy;
  wheelmoment = totalmoment - buoyancymoment;
  wheelweight = totalmass - buoyancymass;
  cgwheels = wheelmoment/wheelweight;
  maindistance = mainarm - wheelweight;
  nosedistance = wheelweight - nosearm;
  mainmass = (((wheelweight)*(1-((maindistance)/(maindistance+nosedistance))))/2);
  nosemass = (((wheelweight)*(1-((nosedistance)/(nosedistance+maindistance))))/2);
  mainmoment = mainmass*mainarm;
  nosemoment = nosemass*nosearm;
  netmoment = buoyancymoment+mainmoment+nosemoment;
  netcg = netmoment/totalmass;
  staticmargin = adc - netcg;
  answer = staticmargin/meanadc;

}

Тепер я правильно налаштував типи даних для всіх цих змінних, і вони є поєднанням функції float, int та long. Я не думаю, що це проблема з типом даних. Що я отримую, коли я друкую остаточну відповідь у серійному номері, той самий номер незалежно від входу, який вводить користувач.

Я гадаю, що мені потрібно форматувати код таким чином, щоб він виконував крок за кроком кожен рядок і перевірив відповідь, перш ніж переходити до наступної арифметичної лінії. Якщо так мені потрібна функція для кожного арифметичного кроку? Або є простий спосіб обробки цього, що мені не вистачає.

Будь-які вказівки оцінені. Дякую.

Ось код у повному обсязі:

unsigned long batterymoment,num1,num2,input,totalmoment;
double buoyancymoment,wheelmoment,cgwheels,mainmass,nosemass,maindistance,nosedistance;
double mainmoment,nosemoment,netmoment,netcg,staticmargin,answer;
double centrebuoyancy = 14.164;
double mainarm = 14.3;
double adc = 11.4;
double meanadc = 22.65;
double nosearm = 1.8;
int totalmass = 12404;
int batterymass = 720;
int buoyancymass = 4401;
int batteryposition,wheelweight;
boolean mySwitch = false;

void calc() {
  batterymoment = input*batterymass;
  totalmoment = 149650+batterymoment;
  buoyancymoment = buoyancymass*centrebuoyancy;
  wheelmoment = totalmoment - buoyancymoment;
  wheelweight = totalmass - buoyancymass;
  cgwheels = wheelmoment/wheelweight;
  maindistance = mainarm - wheelweight;
  nosedistance = wheelweight - nosearm;
  mainmass = (((wheelweight)*(1-((maindistance)/(maindistance+nosedistance))))/2);
  nosemass = (((wheelweight)*(1-((nosedistance)/(nosedistance+maindistance))))/2);
  mainmoment = mainmass*mainarm;
  nosemoment = nosemass*nosearm;
  netmoment = buoyancymoment+mainmoment+nosemoment;
  netcg = netmoment/totalmass;
  staticmargin = adc - netcg;
  answer = staticmargin/meanadc;  
 }

void setup() {
  Serial.begin(9600);
  num1=0;
  num2=0;
  Serial.println("Enter battery position");
 }

void loop() {
  while (Serial.available()){
    batteryposition = Serial.read();
    if(batteryposition>47 && batteryposition<58){  
      if(!mySwitch){
         num1=(num1*10)+(batteryposition-48);
      }else{
         num2=(num2*10)+(batteryposition-48);
        }
       }

if(batteryposition==61){
  input=num1+num2;
  calc();
  Serial.print("Static margin is: ");
  Serial.println(answer);
  num1=0;
  num1=0;
  mySwitch=false;
  }
 }
}

Отже, залежно від введення користувача, обчислення змінять кінцеву вихідну відповідь. Наприклад, якщо потрібно ввести 5, вихід має бути -4,22 на основі моїх розрахунків у форматі excel.

0
Будь ласка, покажіть декларації, фактичний результат і очікуваний результат. І поставте додатковий Serial.print ("answer:"); Serial.println (відповідь); налагодження коду, щоб допомогти вам ізолювати проблему.
додано Автор Dave X, джерело
І що це робить? Я поставив "input = 5;" в коді перед calc (), а потім спробуйте diffft debug printing у calc (), поки не отримаєте щось несподіване.
додано Автор Dave X, джерело
Знову ж таки, ви хочете двічі очистити num1 або ви збираєтесь очистити num2 після обробки.
додано Автор Dave X, джерело
Те, що я виявив корисним, полягає в тестуванні складних алгоритмів в електронній таблиці або невеликому консольному додатку (навіть не настільки складних). Як тільки я їх працюю, я перетворююсь на код Arduino, що досить простий. Це не гарантія коду без помилок, але це досить близько.
додано Автор Nayt Grochowski, джерело
він друкує -113,70 незалежно від введення @ DaveX
додано Автор TestOChangeO, джерело

2 Відповіді

Ви отримуєте однакову цінність кожен раз, оскільки це значення, яке обчислюється.

Я думаю, у вас є щось не так з тим, як ви реалізували вашу формулу. Якщо ви починаєте з "answer =" і неодноразово замінюєте змінні формулами або значеннями, які складають ті змінні, які ви закінчуєте цим:

answer = (11.4 - (((4401 * 14.164) + ((((((12404 - 4401) * (1 - ((14.3 - (12404 - 4401))/((14.3 - (12404 - 4401) (12404 - 4401 - 1,8)/((12404 - 4401 - 1,8) + (14,3 (12,404 - 4401 - 1,8)))))/2) - (12404 - 4401))))))/2) * 1.8))/12404))/22.65

Немає нічого зміненого про це взагалі.

Ваша вхідна величина використовується для розрахунку batterymoment . batterymoment використовується для розрахунку totalmoment . totalmoment використовується для обчислення wheel moment/. wheelmoment використовується для обчислення cgwheels . cgwheels ніколи не використовується ні за що .

3
додано

За вашими коментарями, функція calc() не діє, як очікувалося.

Змініть calc() на:

void calc() {
  Serial.print("input:");Serial.println(input);
  batterymoment = input*batterymass;
  totalmoment = 149650+batterymoment;
  buoyancymoment = buoyancymass*centrebuoyancy;
  wheelmoment = totalmoment - buoyancymoment;
  wheelweight = totalmass - buoyancymass;
  cgwheels = wheelmoment/wheelweight;
  maindistance = mainarm - wheelweight;
  nosedistance = wheelweight - nosearm;
  mainmass = (((wheelweight)*(1-((maindistance)/(maindistance+nosedistance))))/2);
  nosemass = (((wheelweight)*(1-((nosedistance)/(nosedistance+maindistance))))/2);
  mainmoment = mainmass*mainarm;
  nosemoment = nosemass*nosearm;
  netmoment = buoyancymoment+mainmoment+nosemoment;
  netcg = netmoment/totalmass;
  staticmargin = adc - netcg;
  answer = staticmargin/meanadc;
  Serial.print("answer:");Serial.println(answer);  
 }

і подивіться, чи отримує він очікувані дані і працює як очікується. Потім додайте налагоджувальні заяви в процесі, доки ви не виявите невідповідність.

Я б включив більше функцій або серію кращих функцій, а потім перевірив їх окремо.

Як ваш код, існує взаємодія між глобальними змінами, послідовний синтаксичний аналіз та розрахунки. Якщо ви розбиваєте його на окремі частини, ви можете ізолювати, де проблема.

0
додано