Функция умножения float чисел

387
25 декабря 2016, 20:46

Пытаюсь написать функцию с переменным числом параметров без использования доп библиотек. Функция такого вида: sum(int к-во элементов,элемент1,элемент2 и тд) Уже битый час пытаюсь заставить мою функцию считать float числа, но тщетно. Что я делаю не так?

    #include <iostream>
    #include <conio.h>
    float sum (int n, float,...)
    {  int *p = &n; float s = 1;
       for (int i = 1; i <= n; i++)
         s*= *(++p);
        return s;
    }
    void main()
    {  std::cout << sum(3,2.2,2.1,2.5);
getch();
     }

На выходе получаю float числа в огромных степенях.

Answer 1

Все правильно делаете, не учли только одного: вещественные константы по умолчанию имеют тип double (8 байт), а не float (4 байта), из-за чего значения считываются из стека некорректно (точнее, помещается туда не то, что ожидается). Вот правильный вызов и немного откорректированный вариант:

#include <iostream>
#include <conio.h>
float sum (int n, float,...)
{  
  float *p = (float *)&n;
  float s = 1;
  while (n--)
    s *= *++p;
  return s;
}
int main()
{  
  std::cout << sum(3,2.2f,2.1f,2.5f);
  getch();
  return 0;
}

Запускаем и получаем:

-8.855

Что только кажется правильным. В результате из двух ответов собираем один - и способ имеет право на существование (в учебных целях), и @AnT прав насчет double. Получаем такой вариант:

#include <iostream>
#include <conio.h>
double sum (int n, double,...)
{  
  double *p = (double *)(&n+1);
  double s = 1;
  while (n--)
    s *= *p++;
  return s;
}
int main()
{  
  std::cout << sum(3,2.2,2.1,2.5);
  getch();
  return 0;
}

И правильный вывод 11.55

Answer 2

Во-первых, доступ к variadic параметрам в С и С++ делатся через макросы группы va_list/va_start/va_arg. Никаким другим способом этот доступ осуществить нельзя. Откуда вы взяли вот эту манеру доступа через int *p = &n; - мне не ясно.

Во-вторых, при передаче float значений через variadic параметры, они всегда неявно преобразуются к значениям типа double. Поэтому никакого float внутри функции тут не может быть в принципе.

В-третиьх, значения вида 2.2, 2.5 и т.п. - это уже double, то есть никакого float вы даже и не пытаетесь передавать.

Поэтому доступ тут делается только и именно через va_arg(..., double).

READ ALSO
Поиск подстроки без учёта регистра [требует правки]

Поиск подстроки без учёта регистра [требует правки]

Нужно найти подстроку, в строке wstring, без учёта регистраОС - Windows

328
Qt custom geoservice plugin

Qt custom geoservice plugin

Использую Map компонент под QML и кровь из носа нужно сделать поддержку различных поставщиков карт, таких как Yandex, Google, Yahoo и тд

379
Синхронизация потоков с помощью Event c++

Синхронизация потоков с помощью Event c++

Необходимо, чтобы нить t4 ждала события просчета времени "time = 1000 * (getTime() - time);" и после этого запускаласьКак реализовать? Нужен именно Event (такое...

389
QSqlTableModel и таблица с одинарной кавычкой (MS SQL)

QSqlTableModel и таблица с одинарной кавычкой (MS SQL)

Всем привет в базе данных присутствуют таблицы, которые содержат одинарные кавычкиТаблицы содержащие кавычку в названии не выгружают данные...

404