Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Как вычислить проценты

35K
19 марта 2008 года
clear2121
6 / / 16.03.2008
Привет ВСЕМ!!!
Потребовалось вычислить проценты. Делаю по старинке
(a*100)/b
А есть ли способ сделать в Билдере с помощью функций? Или есть другой способ?

СПАСИБО!!!
1.9K
19 марта 2008 года
Anton Chik
175 / / 26.09.2005
есть отличный способ самому за 5 сек черкнуть ТАКУЮ функцию и юзать ее до конца жизни
35K
19 марта 2008 года
clear2121
6 / / 16.03.2008
Что я и сделал. В Билдере не нашел спец. функции. Может есть быстрый алгоритм? Или еще чего
11
19 марта 2008 года
oxotnik333
2.9K / / 03.08.2007
Цитата: Тень Пса
ну можешь поделить на 100 и умножить на нужное число процентов ))))))) (a/100)*b ))))

мож быстрее будет ;) (и правильнее....)



быстрее будет не делить на 100 а умножить на 0.01 ;)

92
19 марта 2008 года
Тень Пса
2.2K / / 19.10.2006
ну, да... блин. а нафик я удалил мессагу... :(
3
19 марта 2008 года
Green
4.8K / / 20.01.2000
Цитата: oxotnik333
быстрее будет не делить на 100 а умножить на 0.01 ;)


Нагляднее все же делить на 100, а компилятор умножит на 0.01 за тебя. :)

11
19 марта 2008 года
oxotnik333
2.9K / / 03.08.2007
Цитата: Green
Нагляднее все же делить на 100, а компилятор умножит на 0.01 за тебя. :)



наглядней, то оно наглядней... только делить он дольше будет чем умножать... не думаю что компиляторы берут на себя смелость по переводу деления на умножение на обратные величины

3
19 марта 2008 года
Green
4.8K / / 20.01.2000
Цитата: oxotnik333
не думаю что компиляторы берут на себя смелость по переводу деления на умножение на обратные величины


Не поверишь, они позволяют себе и более смелые вещи. :)

11
19 марта 2008 года
oxotnik333
2.9K / / 03.08.2007
Цитата: Green
Не поверишь, они позволяют себе и более смелые вещи. :)



 
Код:
double a, b;
b=300;
for (long int i=0; i<1000000000; i++)
      a=b/100;

  for (long int i=0; i<1000000000; i++)
        a=b*0.01;

2-й вариант выполняется в 4 раза быстрее
Делаю вывод что BCB6 не заменяет самостоятельно деление умножением
3
19 марта 2008 года
Green
4.8K / / 20.01.2000
Цитата: oxotnik333
 
Код:
double a, b;
b=300;
for (long int i=0; i<1000000000; i++)
      a=b/100;

  for (long int i=0; i<1000000000; i++)
        a=b*0.01;

2-й вариант выполняется в 4 раза быстрее
Делаю вывод что BCB6 не заменяет самостоятельно деление умножением


хм...
это дебаг или релиз?
что говорит дизассемблер?

11
19 марта 2008 года
oxotnik333
2.9K / / 03.08.2007
Цитата: Green
хм...
это дебаг или релиз?
что говорит дизассемблер?



и дебаг и релиз работают примерно однаково
дизасемблером пользоваться не умею а эезюшник сюда не прицепляется, говорят велик зараза... вот проект(если не лень заниматься):

ЗЫ: вот нашел алгоритм деления двоичных чисел, видно что он намного длинее алгоритма умножения

3
19 марта 2008 года
Green
4.8K / / 20.01.2000
У меня билдера нет. Так что поверю на слово.
2.1K
19 марта 2008 года
wAngel
129 / / 23.11.2004
Цитата: oxotnik333
 
Код:
double a, b;
b=300;
for (long int i=0; i<1000000000; i++)
      a=b/100;

  for (long int i=0; i<1000000000; i++)
        a=b*0.01;

2-й вариант выполняется в 4 раза быстрее
Делаю вывод что BCB6 не заменяет самостоятельно деление умножением



А как вы замеряли время выполнения? Использовали какие-то средства для профилирования?

11
19 марта 2008 года
oxotnik333
2.9K / / 03.08.2007
Цитата: wAngel
А как вы замеряли время выполнения? Использовали какие-то средства для профилирования?



проект открой, там все написано

2.1K
19 марта 2008 года
wAngel
129 / / 23.11.2004
Цитата: oxotnik333
проект открой, там все написано



А в вашем алгоритме каким либо образом учтена система выделения времени потокам в виндовс?
Что если какой-то процесс с более высоким приоритетов вклинился во время рассчета?

Хорошо, пусть будет ваш алгоритм замера производительности.
Не поленился и проверил.
Вот ваш немного модифицированный код.

Код:
float a, b;
    b=300;
    DWORD begin, end, time;

    begin = GetTickCount();
    for (long int i=0; i<1000000000; i++)
        a = b / 100;

    end = GetTickCount();
    time = end - begin; // in milliseconds

    wprintf(L"Time:%d\n", time);


    begin = GetTickCount();
    for (long int i=0; i<1000000000; i++)
        a = b * 0.01;

    end = GetTickCount();
    time = end - begin; // in milliseconds

    wprintf(L"Time:%d\n", time);

    wscanf(L"%d", &a);


В отладочной версии как и было вами замечано время выполнения сильно отличалось в двух вариантах:
 
Код:
Time:25578
Time:4062


А вот в релизной конфигурации с включенной оптимизацией
получилось вот так:
 
Код:
Time:0
Time:0


Отсюда можно сделать ряд выводов, например о том, что иногда нужно посмотреть нужные опции компилятора для включения оптимизации.
Кстати в данном случчае оптимизатор, проанализировав код, заметил, что после цикла, переменные ни где более не используются и просто удалил весь цикл, что видно и в дизассемблере.
Если хотите, могу скинуть дамп.
Такие дела.
11
19 марта 2008 года
oxotnik333
2.9K / / 03.08.2007
Цитата:
А в вашем алгоритме каким либо образом учтена система выделения времени потокам в виндовс?
Что если какой-то процесс с более высоким приоритетов вклинился во время рассчета?


я запускал оба алгоритма по нескольку раз и при этом все приложения позакрывал... так что вероятность вклинивания стороннего процесса весьма мала...

Цитата:
Кстати в данном случчае оптимизатор, проанализировав код, заметил, что после цикла, переменные ни где более не используются и просто удалил весь цикл, что видно и в дизассемблере.
Если хотите, могу скинуть дамп.


а ежели использовать результаты вычисления, что на это скажет оптимизатор?
ЗЫ: понятное дело, если он выкинул весь код, то и сравнивать нечего...
попробуйте потом применить эти переменные где нибудь (записать хотя бы в тот же TLabel::Caption = a), а потом делать выводы

2
19 марта 2008 года
squirL
5.6K / / 13.08.2003
не удержался и тоже поставил эксперимент.
Код:
div.c:
main() {
    double a, b;
    b=300;

    for (long int i=0; i<1000000000; i++)
        a=b/100;
}

mul.c:
main() {
    double a, b;
    b=300;

    for (long int i=0; i<1000000000; i++)
        a=b*0.01;
}

Цитата:

$ g++ div.c -o div
$ time ./div

real 0m21.291s
user 0m21.157s
sys 0m0.004s

$ g++ mul.c -o mul
$ time ./mul

real 0m3.617s
user 0m3.616s
sys 0m0.004s



теперь внимание.

Цитата:
$ g++ -O2 div.c -o div
$ g++ -O2 mul.c -o mul
$ time ./div

real 0m0.003s
user 0m0.004s
sys 0m0.000s
$ time ./mul

real 0m0.003s
user 0m0.000s
sys 0m0.004s



почуствуйте разницу :)
да, тестировалось на

Цитата:

gcc version 4.1.2 20061115 (prerelease) (Debian 4.1.1-21)

11
19 марта 2008 года
oxotnik333
2.9K / / 03.08.2007
к стати, если double заменить на int тогда деление быстрее умножения проходит...
ЗЫ: оно вобщем то и понятно почему...
2.1K
19 марта 2008 года
wAngel
129 / / 23.11.2004
Цитата: oxotnik333

ЗЫ: понятное дело, если он выкинул весь код, то и сравнивать нечего...
попробуйте потом применить эти переменные где нибудь (записать хотя бы в тот же TLabel::Caption = a), а потом делать выводы



Т.е. вы хотите сказать, что компилятор не может оптимизировать умножение и деление, хотя запросто может анализировать логику кода, удалять неиспользуемые блоки и т.д.?

Ладно, будем проверять дальше.
Вот код:

Код:
float a, b;
    b=300;
    DWORD begin, end, time;

    begin = GetTickCount();
    for (long int i=0; i<1000000000; i++)
    {
        a = b / 100;
        b = a;
    }
    end = GetTickCount();
    time = end - begin; // in milliseconds

    wprintf(L"Time:%f - %d\n", a, time);


    begin = GetTickCount();
    for (long int i=0; i<1000000000; i++)
    {
        a = b * 0.01;
        b = a;
    }
    end = GetTickCount();
    time = end - begin; // in milliseconds

    wprintf(L"Time:%f - %d\n", a, time);

    wscanf(L"%d", &a);


Результат:
 
Код:
Time:0.000000 - 29735
Time:0.000000 - 19969


Разница есть, но не такая большая :cool:
Все таки оптимизация есть... :)
11
19 марта 2008 года
oxotnik333
2.9K / / 03.08.2007
Цитата:
Т.е. вы хотите сказать, что компилятор не может оптимизировать умножение и деление, хотя запросто может анализировать логику кода, удалять неиспользуемые блоки и т.д.?


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

2.1K
19 марта 2008 года
wAngel
129 / / 23.11.2004
Заменил
 
Код:
a = b * 0.01;

на
 
Код:
a = b * 1 / 100;


И.. о чудо :)
Результаты почти сравнялись, что можно отнести на сторонние потоки.
 
Код:
Time:0.000000 - 30187
Time:0.000000 - 28750


Делайте выводы и как сказал squirL, чувствуйте разницу :)
11
19 марта 2008 года
oxotnik333
2.9K / / 03.08.2007
я так предполагаю, что если не определять жестко переменную b, а сделать ее допустим рандомную, то оптимизация компилятора сведется практически на нет...
11
19 марта 2008 года
oxotnik333
2.9K / / 03.08.2007
Цитата: wAngel
Заменил
 
Код:
a = b * 0.01;

на
 
Код:
a = b * 1 / 100;


И.. о чудо :)
Результаты почти сравнялись, что можно отнести на сторонние потоки.
 
Код:
Time:0.000000 - 30187
Time:0.000000 - 28750


Делайте выводы и как сказал squirL, чувствуйте разницу :)



я даже могу предположить как происходила оптимизация деления: т.к. 1 (единица) и 100 являются константными, а деление и умножение равные по приоритету задачи, оптимизатор заранее высчитал 1/100 и подставил 0,01, что равно формуле умножения, а разница во времени появилась из за того что все таки пришлось вычислять 0,01

2.1K
20 марта 2008 года
wAngel
129 / / 23.11.2004
Цитата: oxotnik333
я даже могу предположить как происходила оптимизация деления: т.к. 1 (единица) и 100 являются константными, а деление и умножение равные по приоритету задачи, оптимизатор заранее высчитал 1/100 и подставил 0,01, что равно формуле умножения, а разница во времени появилась из за того что все таки пришлось вычислять 0,01



Оптимизация происходит на этапе компиляции а не во время выполнения.

11
20 марта 2008 года
oxotnik333
2.9K / / 03.08.2007
Цитата: wAngel
Оптимизация происходит на этапе компиляции а не во время выполнения.



ну вот на этапе компиляции он 1/100 превратил в переменную "с" а чуть выше цикла сделал примерно так c=1/100... ну это так, чисто теоретические догадки и предположения...

263
20 марта 2008 года
koltaviy
816 / / 16.12.2004
А всё так невинно начиналось ;)
92
20 марта 2008 года
Тень Пса
2.2K / / 19.10.2006
koltaviy, +1 :)
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог