Go Down

Topic: write a function to add numbers to a sum? (Read 196 times) previous topic - next topic

flyandance



The code below adds all the numbers in an array to a sum, but I don't really want to use an array here. I only want a simple function that can be used to add any amount of numbers to a sum.

such as this:
Code: [Select]
int total=add(num1, num2)
int total=add(num1, num2, num3)
int total=add(num1, num2, num3, num4.....)


here is my failed code:
Code: [Select]
byte love[]={1,2,3,4,5,6,8,9,10};


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

void loop() {

  int buf= adding (love, sizeof(love));
  Serial.println(buf);
  delay(2000); 
}


int adding (byte *hate, byte len){
    int buf=0;
    for (byte i=0; i<len; i++){
    buf+= hate[i];
    }
  return buf; 
  }

el_supremo

#1
Mar 18, 2017, 09:47 pm Last Edit: Mar 18, 2017, 09:51 pm by el_supremo
In what way does it fail?

Oh, you mean it uses an array and you don't want to do that.
Hmmm. I think there is a way to specify a variable number of arguments but I forget, or never knew, how to do it :)

Pete
Don't send me technical questions via Private Message.


flyandance

Take a look:

https://www.tutorialspoint.com/cprogramming/c_variable_arguments.htm
http://www.cplusplus.com/reference/cstdarg/va_copy/

getting 2089 with this code. Should be 14.
Code: [Select]


#include <stdarg.h>
byte love[]={1,2,3,4,5,6,8,9,10};

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

void loop() {

  int buf= adding (love, sizeof(love));
  Serial.println(buf);

  int buff= add (4,1,2,3,4);
  Serial.println(buff);
   
  delay(2000); 
}


int adding (byte *hate, byte len){
    int buf=0;
    for (byte i=0; i<len; i++){
    buf+= hate[i];
    }
  return buf; 
  }

int add (int n, ...){
  int buf=0;
  int val=n;
  int counter=0; 
 
  va_list adding, count;
  va_start (adding, n);
 
  va_copy (count, adding);
  while (val!=0){
    val=va_arg (count, int);
    ++counter;
  }
  va_end(count);
 
  for (; counter>0; counter--){
  buf+=va_arg (adding, int);
  }
  va_end(adding);
 
    return buf;
  }





econjack

This seems like using an H-bomb to kill an ant. Why do you want to do it this way?

flyandance

This seems like using an H-bomb to kill an ant. Why do you want to do it this way?
This is the part of a library that I am writing. I need to figure out a way to do it properly in its simplest form first.

user091ard

getting 2089 with this code. Should be 14.
Code: [Select]

void loop() {

  int buf= adding (love, sizeof(love));
  Serial.println(buf);

  int buff= add (4,1,2,3,4);
  Serial.println(buff);
   
  delay(2000); 
}

add(4, 1, 2, 3, 4) should be 1+2+3+4 = 10. The first argument is the number of arguments.


Try this solution (I don't have a board beside me, so I can't test this):

Code: [Select]

#include <stdarg.h>

int sum(int num,...)
{
   va_list valist;
   va_start(valist, num);

   int sum = 0;
   for (int i = 0; i < num; i++)
   {
      sum += va_arg(valist, int);
   }

   va_end(valist);

   return sum;
}

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

void loop()
{
   int result = sum(4, 1, 1, 1, 1);
   Serial.println(result);

   delay(2000);
}



flyandance

add(4, 1, 2, 3, 4) should be 1+2+3+4 = 10. The first argument is the number of arguments.


Try this solution (I don't have a board beside me, so I can't test this):

Code: [Select]

#include <stdarg.h>

int sum(int num,...)
{
   va_list valist;
   va_start(valist, num);

   int sum = 0;
   for (int i = 0; i < num; i++)
   {
      sum += va_arg(valist, int);
   }

   va_end(valist);

   return sum;
}

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

void loop()
{
   int result = sum(4, 1, 1, 1, 1);
   Serial.println(result);

   delay(2000);
}



This should work, but I don't want to enter the "first argument as the number of arguments". I want every argument to be added to the sum, so sum(4, 1, 1, 1, 1) = 8, not 4;

The va_copy should do the trick, but It doesn't work for me.

user091ard

#8
Mar 19, 2017, 09:30 pm Last Edit: Mar 19, 2017, 09:49 pm by user091ard
Try this code (the only restriction is that your last argument has to be 0):

Code: [Select]

#include <stdarg.h>

int add(int num, ...)
{
int total = num;
int counter = 0;
int val = num;

va_list adding, count;
va_start (adding, num);

va_copy(count, adding);
while (val != 0)
{
val = va_arg(count, int);
++counter;
}
va_end(count);

for (int i = 0; i < counter - 1; ++i)
{
total += va_arg (adding, int);
}
va_end(adding);

return total;
}

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

void loop()
{
int buff = add(1, 2, 3, 4, 0);
Serial.println(buff);
delay(2000);
}


Or this solution (with INT_MAX):

Code: [Select]

#include <stdarg.h>
#include <limits.h>

int add(int num, ...)
{
int total = num;
int counter = 0;
int val = num;

va_list adding, count;
va_start (adding, num);

va_copy(count, adding);
while (val != INT_MAX)
{
val = va_arg(count, int);
++counter;
}
va_end(count);

for (int i = 0; i < counter - 1; ++i)
{
total += va_arg (adding, int);
}
va_end(adding);

return total;
}

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

void loop()
{
int buff = add(1, 2, 3, 4, 5, 1, INT_MAX);
Serial.println(buff);
delay(2000);
}

flyandance

Try this code (the only restriction is that your last argument has to be 0):

Code: [Select]

#include <stdarg.h>

int add(int num, ...)
{
int total = num;
int counter = 0;
int val = num;

va_list adding, count;
va_start (adding, num);

va_copy(count, adding);
while (val != 0)
{
val = va_arg(count, int);
++counter;
}
va_end(count);

for (int i = 0; i < counter - 1; ++i)
{
total += va_arg (adding, int);
}
va_end(adding);

return total;
}

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

void loop()
{
int buff = add(1, 2, 3, 4, 0);
Serial.println(buff);
delay(2000);
}


Or this solution (with INT_MAX):

Code: [Select]

#include <stdarg.h>
#include <limits.h>

int add(int num, ...)
{
int total = num;
int counter = 0;
int val = num;

va_list adding, count;
va_start (adding, num);

va_copy(count, adding);
while (val != INT_MAX)
{
val = va_arg(count, int);
++counter;
}
va_end(count);

for (int i = 0; i < counter - 1; ++i)
{
total += va_arg (adding, int);
}
va_end(adding);

return total;
}

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

void loop()
{
int buff = add(1, 2, 3, 4, 5, 1, INT_MAX);
Serial.println(buff);
delay(2000);
}

ok, thanks a lot. so using va_copy really doesn't work. It can't exit the arguments counting while loop by itself. while for a summing function, adding a zero to the end is okay, but it really doesn't work for me here, as I am not necessarily write a summing function. I will figure it out.

boolrules


GoForSmoke

If you check AVR-LibC where Arduino gets its standard C libraries

http://www.nongnu.org/avr-libc/user-manual/modules.html

you may notice that there is no stdarg.h.

With more checking you can find that the AVR-LibC stdio.h does use va_list.

So just on instinct and a whim I decided to see if AVR-LibC in Arduino IDE has stdarg by default. It does.

sketch:
Code: [Select]

int x, y, z;

int addEmUp( int n, ... )
{
  x = n;
  y = 0;

  va_list vList;
  va_start( vList, n );
  
  for ( int i = 0; i < n; i++ )
  {
    z = va_arg( vList, int );
    y += z;
    Serial.println( z );
  }
  return y;
}

void setup()
{
  Serial.begin( 250000 );
  z = addEmUp( 5, 1,2,3,4,5 );
    Serial.println();
    Serial.println( z );
}

void loop()
{

}


output:
Quote
1
2
3
4
5

15
Nick Gammon on multitasking Arduinos:
1) http://gammon.com.au/blink
2) http://gammon.com.au/serial
3) http://gammon.com.au/interrupts

Go Up
 


Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

Arduino
via Egeo 16
Torino, 10131
Italy