Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Вычисление процентов трех величин чья сумма = 100% 
:(
    Опции темы
santey
Дата 20.9.2010, 22:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 101
Регистрация: 31.12.2005

Репутация: -1
Всего: -1



Имеются 3 величины, которые в сумме составляют 100 процентов

первая - 1000
вторая - 38
третья - 20 

необходимо точно вычислить какой процент составляет каждая величина от общей суммы.

для этого сложим 3 суммы и умножим на 0.01 и получим величину одного процента,
которая равна 10.58, далее каждую величину разделим на один процент и получим

первая - 94.5179
вторая -  3.5916
третья -  1.8903

так вот как эти величины правильно округлить так, чтобы получились правильные значения
в процентах переменной в int?


Если округлять вверх то получится
первая - 95%
вторая -  4%
третья -  2%
здесь 95+4+2=101%  неправильно

Если округлять вниз то получится
первая - 94%
вторая -  3%
третья -   1%
здесь 94+3+1=98% тоже неправильно

Может быть имеются функции выделяющие правильный процент из определенной величины?
                

Это сообщение отредактировал(а) santey - 20.9.2010, 22:52
PM MAIL   Вверх
ИванМ
Дата 20.9.2010, 23:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1260
Регистрация: 19.6.2006
Где: СПб

Репутация: 5
Всего: 23



Цитата(santey @  20.9.2010,  22:50 Найти цитируемый пост)
так вот как эти величины правильно округлить так, чтобы получились правильные значения
в процентах переменной в int?

Вычислить то, что на самом деле, потом понизить ту величину, у которой дробная часть самая маленькая.

Цитата(santey @  20.9.2010,  22:50 Найти цитируемый пост)
Может быть имеются функции выделяющие правильный процент из определенной величины?

Нет такой функции
PM MAIL   Вверх
casey
Дата 21.9.2010, 08:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 74
Регистрация: 20.12.2006
Где: Украина

Репутация: нет
Всего: 2



Я бы так сделал:

Округлить все числа вверх.

Если в сумме 102 - 2 числа с наименьшей дробной частью округлять вниз, оставшееся вверх.
    если в сумме 101 - 1 число с наименьшей дробной часть округлять вниз , оставшиеся 2 вверх.
    если в сумме 100 - все числа округлять вверх (или вниз как нравится - потому что 100 получится только когда все числа целые)           

PM MAIL WWW   Вверх
t4aynik
Дата 23.9.2010, 16:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 15
Регистрация: 5.6.2010

Репутация: нет
Всего: нет



100*1000/(1000+38+20)=~95%
(100-95)*38/(38+20)=~3%
100-95-3=2%

то что с ~ округляй как хочешь.
так не пойдет?


Это сообщение отредактировал(а) t4aynik - 23.9.2010, 16:34
PM MAIL   Вверх
santey
Дата 23.9.2010, 18:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 101
Регистрация: 31.12.2005

Репутация: -1
Всего: -1



Цитата(t4aynik @ 23.9.2010,  16:33)
100*1000/(1000+38+20)=~95%
(100-95)*38/(38+20)=~3%
100-95-3=2%

то что с ~ округляй как хочешь.
так не пойдет?

Конечно не пойдет.

А как узнать в какую сторону округлять? в большую или меньшую.
Имею в виду первое число ~95
PM MAIL   Вверх
santey
Дата 23.9.2010, 19:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 101
Регистрация: 31.12.2005

Репутация: -1
Всего: -1



Цитата(ИванМ @  20.9.2010,  23:03 Найти цитируемый пост)
Вычислить то, что на самом деле, потом понизить ту величину, у которой дробная часть самая маленькая.



Данный способ не работает, если 2 величины имеют равное значение.
PM MAIL   Вверх
ИванМ
Дата 24.9.2010, 00:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1260
Регистрация: 19.6.2006
Где: СПб

Репутация: 5
Всего: 23



Вот что пока получилось. Страшно, ужасно и коряво, но вроде работает.
Код

#include <iostream>
#include <algorithm>

bool less(double* v1, double* v2)
{
    return (*v1-(int)(*v1))<(*v2-(int)(*v2));
}

bool great(double* v1, double* v2)
{
    return (*v1-(int)(*v1))>(*v2-(int)(*v2));
}

void go(double* v1, double* v2, double* v3)
{
    double *arr[3]={v1, v2, v3};
    double v=0.01*((*v1)+(*v2)+(*v3));
    for(size_t i=0;i<3;++i)
    {
        (*arr[i])=((*arr[i])/v);
    }

    int val=((int)(*arr[0])+(int)(*arr[1])+(int)(*arr[2]));
    if(val>100)
        std::sort(arr, arr+3, less);
    else if(val<100)
        std::sort(arr, arr+3, great);
    else
    {
        *arr[0]=(int)(*arr[0]);
        *arr[1]=(int)(*arr[1]);
        *arr[2]=(int)(*arr[2]);
        return;
    }

    size_t pos=0;

    while(true)
    {
        int val=((int)(*arr[0])+(int)(*arr[1])+(int)(*arr[2]));

        if(val>100)
        {
            --(*arr[pos]);
            ++pos;
        }
        else if(val<100)
        {
            ++(*arr[pos]);
            ++pos;
        }
        else
        {
            *arr[0]=(int)(*arr[0]);
            *arr[1]=(int)(*arr[1]);
            *arr[2]=(int)(*arr[2]);
            return;
        }
    }
}

int main(int argc, char* argv[])
{
    double v1=1000, v2=38, v3=20;
    std::cout<<v1<<" "<<v2<<" "<<v3<<std::endl;
    go(&v1, &v2, &v3);
    std::cout<<v1<<" "<<v2<<" "<<v3<<std::endl;
    std::system("pause");
    return 0;
}


PM MAIL   Вверх
t4aynik
Дата 24.9.2010, 09:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 15
Регистрация: 5.6.2010

Репутация: нет
Всего: нет



Цитата(santey @  23.9.2010,  18:48 Найти цитируемый пост)
А как узнать в какую сторону округлять? в большую или меньшую.Имею в виду первое число ~95

smile
По правилам математики: 94.7 = 95, 95.3 = 95.
а вообще вы вносите неплохую погрешность преобразуя результаты к целому.
PM MAIL   Вверх
santey
Дата 24.9.2010, 22:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 101
Регистрация: 31.12.2005

Репутация: -1
Всего: -1



Все варианты перебрал и либо громоздкая функция, вычисляющая целые проценты или же очень простая но дающая 100 процентные проценты это double с одним значением после запятой.

Например, для своей программы сделал

double TFormMain::Procent(int S[3],int number)
{
   //определяем процент значения number
   double pr_number=(double)S[number]/((S[0]+S[1]+S[2])*0.01);      

   //отделяем дробную часть и переводим в целое число
   int a=Frac(pr_number)*1000;        

   //отделяем по значению и округляем его, если надо                       
   for(int i=0;i<2;i++)        a=a/10+(fmod(a,10)>5 ? 1 : 0);

   //возвращаем полученный результат
   return floor(pr_number)+a*0.1;
}

Это сообщение отредактировал(а) santey - 24.9.2010, 22:26
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++ Builder"
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по С++ Builder обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Настоятельно рекомендуем заглянуть в DRKB (Delphi Russian Knowledge Base) - крупнейший в рунете сборник материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C++ Builder | Следующая тема »


 




[ Время генерации скрипта: 0.0461 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.