ساخت ماشین حساب با آردوینو و اشتباه در محاسبات اعداد بزرگ؟!

3 سال قبل
497 بازدید

0

سلام

می خواستم با آردوینو و چندتا ماژول یه ماشین حساب درست کنم، ولی وقتی اعداد بزرگ را در هم ضرب می کنم حاصلضرب اشتباهی می دهد!

به عنوان مثال اگر عدد 9999999 را در 100 ضرب کنم نتیجه حاصل ضرب درست است، ولی اگر 9999999 را در 1000 ضرب کنم نتیجه ی اشتباهی می دهد! چرا؟

مشکل از کدهاست یا آردوینو توانایی محاسبه ندارد؟

 

این هم کد ماشین حساب:

فقط کافیه کد را روی برد کامپایل کنید و با ارتباط سریال محاسبات را انجام دهید و نیاز به اتصال ماژولی نیست.

/* Serial arduino calculator
in this project, you can make basic
arithmetic with the help of arduino,
almost like a very rustic calculator.
It accepts two numbers and a signal, and
makes the operation, witch can be of +, -, * or /.
E.G. : send "2+3" (Without quotes and with no
space separing the info), and arduino answers 5.
Digit "7-3" and arduino te responde com 4.
Criado por João Paulo Rodrigues Poltronieri

This code is on public domain
*/

// first of all, create variables to store
// the information sent to arduino

long number1; // first number of the calculation,
// sent through the Serial monitor

// If you take a look, it's a long varible, so
// we're able to use big numbers

long number2; // second number sent through the SM

char calSignal; // create a char variable to store
// the calcuation signal.

long result; // result of the calculation

void setup() {
  Serial.begin(9600); // begins serial communications
  Serial.println("Send me a calculation"); 
  Serial.println("E.G. : 2+3");
  Serial.println();
  // prints this to test serial communication, and
  // prints a line space
}

void loop() {
  while(Serial.available() > 0) {
    // while there are dada being sent to arduino,
    
    number1 = Serial.parseInt();
    // number1 will be the first number
    
    // Note the use of "Serial.parseInt, so,
    // in case you use 23, it stores in 
    // number1 the number 23
    
    // if we used Serial.read(), it would
    // only store 2
    
    calSignal = Serial.read(); // calSignal will be the first
    // info after the first number
    
    number2 = Serial.parseInt(); // stores the second
    // number in number2
    
    resolucao(); // Custom function to solve the calculations
 
    Serial.println("Resultado = ");
    Serial.println(result);
    // Prints the result of the calculation
    Serial.println(); // jumps a line
    Serial.println("Outra conta, por favor"); // prints
    Serial.println(); // jumps a line
  }
}

void resolucao() { // Custom function that
  // solves the calculations
  
  switch (calSignal) {
    // Here we use "switch...case" to save some space on
    // the sketch. It's, basicaly, a function that verifies
    // various "if" statements.
    
    // Here, it verifies what's the value held by 
    // calSigna. Basicaly, it verifies the "signal"
    // of the calculation
    
    case '+' : // if calSignal is '+'
    result = number1 + number2; // sums the numbers
    // and makes result hold the value of the calculation
    break; // break to exit the "case"
    case '-' : // if calSignal is '+'
    result = number1 - number2; // subtracts the numbers
    // and makes result hold the value of the calculation
    break; // break to exit the "case"
    case '*' : // if calSignal is '+'
    result = number1 * number2; // multiplies the numbers
    // and makes result hold the value of the calculation
    break; // break to exit the "case"
    case '/' : // se calSignal for '/'
    result = number1 / number2; // divides the numbers
    // and makes result hold the value of the calculation
    // PS: in case the division isn't exact, the result 
    // will be the nearest integrer
    break; // break to exit the "case"
    default : // If it's not any of these...
    Serial.println("CONTA INVÁVIDA");
    // Creates an "error"
    Serial.println();
    //result = 0;
  }
}
26 بهمن 00 در 05:11
محمد کریمی خوزانی
37

افزودن دیدگاه

3 پاسخ ثبت شده است
1

با سلام 

بنده فکر می‌کنم مشکل شما در نوع متغیری باشد که تعریف کرده اید.طبق عکس زیر محدوده مجاز برای هر متغییر را بیان می‌کند. شما متغیر محاسباتی خود را Long تعریف کردید و وقتی 9999999 را در 1000 ضرب می‌کنید، حاصل ضرب آن دو از مقدار بیان شده بیشتر می‌گردد. 

پیشنهاد بنده اینه که از متغیر float استفاده کنید و نتیجه را گزارش دهید. 

27 بهمن 00 در 05:57
shojaei
431

ممنون از پاسخی که لطف کردید و دادید. متاسفانه با متغیر float هم جواب درستی نمی دهد. حاصلضرب 99999999 در 100 را می دهد: 1410065280.00  – محمد کریمی خوزانی 00-11-27 در 10:28

افزودن دیدگاه

1

سلام

از متغییر uint64_t استفاده کنید.

01 اسفند 00 در 07:54
محمد دمیرچی
4280

سلام از چیزی که گفتی استفاده کردم ولی این پیغام را میده: error: call of overloaded 'println(uint64_t&)' is ambiguous کدش را هم ساده کردم [code] float a=99999999.0; float b=100.0; uint64_t c = 0; void setup() { // put your setup code here, to run once: Serial.begin(9600); } void loop() { // put your main code here, to run repeatedly: c= a*b; Serial.println(c); delay (1000); } [/code]  – محمد کریمی خوزانی 00-12-01 در 01:05

افزودن دیدگاه

1

از کد زیر استفاده کنید.

تست شده کار میکند.

فقط برای اینکه اعداد منفی را نیز ساپورت کند از int64_t استفاده شده است. اگر بخواهید عدد های بیشتری را نمایش بدهید و اعداد منفی برای شما مهم نبود به uint64_t تغییر بدهید.

int64_t a = 99999999999999;
int64_t b = 130;
int64_t c = 0;

void setup() {
  Serial.begin(9600);
} 
void loop() {
  c = a * b;
  print_uint64_t(c);
  
  delay (1000);
}

void print_uint64_t(int64_t num) {

  char rev[128]; 
  char *p = rev+1;

  while (num > 0) {
    *p++ = '0' + ( num % 10);
    num/= 10;
  }
  p--;
  /*Print the number which is now in reverse*/
  while (p > rev) {
    Serial.print(*p--);
  }
  Serial.println();
}
03 اسفند 00 در 07:49
محمد دمیرچی
4280

محمد جان خدا خیرت بده، عالی بود🌷. همینه  – محمد کریمی خوزانی 00-12-03 در 04:59

خواهش میکنم  – محمد دمیرچی 00-12-04 در 07:19

افزودن دیدگاه


انجمن کافه‌ربات © 1400