Среднее арифметическое 3-х чисел
От: ArtDenis Россия  
Дата: 21.01.06 18:01
Оценка:
Существует ли в природе алгоритм нахождения средненего арифметического
3-х целых беззнаковых чисел без использования такой медленной операции,
как деление?
Posted via RSDN NNTP Server 2.0
[ 🎯 Дартс-лига Уфы | 🌙 Программа для сложения астрофото ]
Re: Среднее арифметическое 3-х чисел
От: _gc Россия  
Дата: 21.01.06 20:19
Оценка:
Как вариант можно умножить на 1/3, но там будет хитрый случай, если при реализации mul вам попадётся число, кратное трём (:
Error checking omitted for clarity. © Microsoft
Re: Среднее арифметическое 3-х чисел
От: Xander Zerge Россия www.zerge.com
Дата: 21.01.06 21:04
Оценка:
Здравствуйте, ArtDenis, Вы писали:

А двух? И почему целочисленное деление — медленная операция? Боюсь соврать, но уже Pentium'ы делали это за такт.

AD>Существует ли в природе алгоритм нахождения средненего арифметического

AD>3-х целых беззнаковых чисел без использования такой медленной операции,
AD>как деление?
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Серёжа Новиков,
программист
Re[2]: Среднее арифметическое 3-х чисел
От: _gc Россия  
Дата: 21.01.06 21:40
Оценка:
XZ>А двух? И почему целочисленное деление — медленная операция? Боюсь соврать, но уже Pentium'ы делали это за такт.

Для двух — это битовый сдвиг (: А Pentium'ы делили целые дворды за 41 такт.


[offtopic]
Пользуясь случаем, хочу выразить своё мнение по поводу Flaredance Screensaver:
1) Как пользователь — я очень падок до всяких фейерверков, и сам когда-то писал, но flaredance мне не понравился. одинаковые выстрелы, мало блюра, не похоже на реальный. Из плюсов — очень понравилось освещение горизонта, сполохи
2) Как программист — это хорошо, что вы там чем-то запаковали программу, софтайс плохо с ней дружит (: Но бряки на виндовые сообщения проходят нормально, и это плохо. для вас.
Error checking omitted for clarity. © Microsoft
Re[2]: Среднее арифметическое 3-х чисел
От: ArtDenis Россия  
Дата: 21.01.06 21:44
Оценка:
Xander Zerge пишет:
> И почему целочисленное деление — медленная операция? Боюсь соврать, но уже Pentium'ы делали это за такт.

Просто код пишется не для пентиума.
Posted via RSDN NNTP Server 2.0
[ 🎯 Дартс-лига Уфы | 🌙 Программа для сложения астрофото ]
Re[3]: Среднее арифметическое 3-х чисел
От: Xander Zerge Россия www.zerge.com
Дата: 21.01.06 23:53
Оценка:
Здравствуйте, _gc, Вы писали:

XZ>>А двух? И почему целочисленное деление — медленная операция? Боюсь соврать, но уже Pentium'ы делали это за такт.


_gc>Для двух — это битовый сдвиг (: А Pentium'ы делили целые дворды за 41 такт.

Жуть какая. Не знал. Мои познания — справочник по системе команд. Сейчас полезу освежу.

_gc>[offtopic]

_gc>Пользуясь случаем, хочу выразить своё мнение по поводу Flaredance Screensaver:
Спасибо!
_gc>1) Как пользователь — я очень падок до всяких фейерверков, и сам когда-то писал, но flaredance мне не понравился. одинаковые выстрелы, мало блюра, не похоже на реальный. Из плюсов — очень понравилось освещение горизонта, сполохи
Всё впереди — было желание попробовать тормознуть и пораньше выпустить первую версию.
_gc>2) Как программист — это хорошо, что вы там чем-то запаковали программу, софтайс плохо с ней дружит (: Но бряки на виндовые сообщения проходят нормально, и это плохо. для вас.
Зелёный зверёк с крокодиловой кожей. За два года (другие сэйверы на том же движке с той же защитой) ещё не отломали (ТТТ) — и это уже хорошо.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Серёжа Новиков,
программист
Re[3]: Среднее арифметическое 3-х чисел
От: Xander Zerge Россия www.zerge.com
Дата: 21.01.06 23:53
Оценка:
Здравствуйте, ArtDenis, Вы писали:

>> И почему целочисленное деление — медленная операция? Боюсь соврать, но уже Pentium'ы делали это за такт.

AD>Просто код пишется не для пентиума.
Ага. Тогда — сумма трех чисел с последующим делением сдвигами.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Серёжа Новиков,
программист
Re: Среднее арифметическое 3-х чисел
От: korzhik Россия  
Дата: 22.01.06 00:02
Оценка:
Здравствуйте, ArtDenis, Вы писали:

AD>Существует ли в природе алгоритм нахождения средненего арифметического

AD>3-х целых беззнаковых чисел без использования такой медленной операции,
AD>как деление?

В книге Генри Уоррена младшего "Алгоритмические трюки для программистов" приводится такой код (страница 157):

  li    M, 0xAAAAAAAB  ; загрузка магическго числа (2^32 + 1) / 3
  mulhu q, M, n        ; q = floor(M * n / 2^32)
  shri  q, q, 1        ; 

  muli  t, q, 3        ; вычисляем остаток по формуле
     sub   r, n, t        ; r = n - q * 3


здесь:
n — входное целое число (числитель)
M — сюда загружается "магическое число"
t — временный регистр
q — в нём будет размещено частное
r — в нём будет размещён остаток
------------------------------------
li RT,I — загружает I в RT
mulhu RT,RA,RB — загружает в RT старшие 32 бита произведения RA и RB
shri RT,RA,I — RT <- RA сдвиг вправо на I
muli RT,RA,I — RT <- RA * I
sub RT,RA,RB — RT <- RA — RB

В этой книжке так же рассказано как вычислять магические числа и для не 32-ух битных машин.
Re[2]: Среднее арифметическое 3-х чисел
От: _gc Россия  
Дата: 22.01.06 00:27
Оценка:
Здравствуйте, korzhik, Вы писали:

K>
K>  li    M, 0xAAAAAAAB  ; загрузка магическго числа (2^32 + 1) / 3
K>  mulhu q, M, n        ; q = floor(M * n / 2^32)
K>  shri  q, q, 1        ; 

K>  muli  t, q, 3        ; вычисляем остаток по формуле
K>     sub   r, n, t        ; r = n - q * 3
K>


Я это и имел ввиду, говоря про умножение на 1/3 в первом посте. Только вот:
1) как ваша программа себя поведёт при n, не кратном 3?
2) зачем здесь сдвиг вправо?
Error checking omitted for clarity. © Microsoft
Re: Среднее арифметическое 3-х чисел
От: McSeem2 США http://www.antigrain.com
Дата: 22.01.06 06:07
Оценка: :)
Здравствуйте, ArtDenis, Вы писали:

AD>Существует ли в природе алгоритм нахождения средненего арифметического

AD>3-х целых беззнаковых чисел без использования такой медленной операции,
AD>как деление?

А чем не подходит такое?
(((a + b) >> 1) + c) >> 1

Здесь, конечно, возникает некоторая дополнительная погрешность в нижнюю сторону, но ее можно попытаться скомпенсировать добавлением единицы в одну из сумм.
McSeem
Я жертва цепи несчастных случайностей. Как и все мы.
Re[2]: Среднее арифметическое 3-х чисел
От: McSeem2 США http://www.antigrain.com
Дата: 22.01.06 06:15
Оценка:
MS>
MS>(((a + b) >> 1) + c) >> 1
MS>

Пардон, фигню-с спорол-с.
McSeem
Я жертва цепи несчастных случайностей. Как и все мы.
Re[2]: Среднее арифметическое 3-х чисел
От: ArtDenis Россия  
Дата: 22.01.06 07:39
Оценка:
_gc пишет:
> Как вариант можно умножить на 1/3, но там будет хитрый случай, если при реализации mul вам попадётся число, кратное трём (:

А как можно умножить на 1/3 без деления?
Posted via RSDN NNTP Server 2.0
[ 🎯 Дартс-лига Уфы | 🌙 Программа для сложения астрофото ]
Re[2]: Среднее арифметическое 3-х чисел
От: ArtDenis Россия  
Дата: 22.01.06 07:40
Оценка:
korzhik пишет:
> В книге Генри Уоррена младшего "Алгоритмические трюки для программистов" приводится такой код (страница 157):
Спасибо, сейчас буду пробовать.
Posted via RSDN NNTP Server 2.0
[ 🎯 Дартс-лига Уфы | 🌙 Программа для сложения астрофото ]
Re: Среднее арифметическое 3-х чисел
От: ArtDenis Россия  
Дата: 22.01.06 08:14
Оценка:
Пока что сделал вот так:

result = 85*summa/256; // 85/256 — это примерно 1/3

В сишном варианте это выглядит вот так:

result = (summa+(summa<<2)+(summa<<4)+(summa<<6))>>8;


Но этот код даёт достаточно большие погрешности когда summa превышает
256...
Posted via RSDN NNTP Server 2.0
[ 🎯 Дартс-лига Уфы | 🌙 Программа для сложения астрофото ]
Re[2]: Среднее арифметическое 3-х чисел
От: ArtDenis Россия  
Дата: 22.01.06 08:28
Оценка: 3 (1)
ArtDenis пишет:
> Но этот код даёт достаточно большие погрешности когда summa превышает
> 256...

Оказалось, что эта погрешность довольно хорошо компенсируется
добавлением ещё одного слогаемого: (summa >> 4)

В результате получается
result = ((summa >> 4)+summa+(summa<<2)+(summa<<4)+(summa<<6))>>8;


Хоть результат получился с небольшой погрешностью, но можно сказать, что
вопрос решён
Posted via RSDN NNTP Server 2.0
[ 🎯 Дартс-лига Уфы | 🌙 Программа для сложения астрофото ]
Re[3]: Среднее арифметическое 3-х чисел
От: korzhik Россия  
Дата: 22.01.06 08:30
Оценка:
Здравствуйте, _gc, Вы писали:

_gc>Здравствуйте, korzhik, Вы писали:


K>>
K>>  li    M, 0xAAAAAAAB  ; загрузка магическго числа (2^32 + 1) / 3
K>>  mulhu q, M, n        ; q = floor(M * n / 2^32)
K>>  shri  q, q, 1        ; 

K>>  muli  t, q, 3        ; вычисляем остаток по формуле
K>>     sub   r, n, t        ; r = n - q * 3
K>>


_gc>Я это и имел ввиду, говоря про умножение на 1/3 в первом посте. Только вот:

_gc>1) как ваша программа себя поведёт при n, не кратном 3?

нормально ведёт себя, вот можете проверить:
unsigned arithmetic_mean_asm(unsigned a, unsigned b, unsigned c)
{
    __asm {
        mov         eax, a;
        mov         ecx, b;
        mov         edx, c;
        add         ecx, edx; 
        add         ecx, eax; 
        mov         eax, 0AAAAAAABh; 
        mul         ecx;
        shr         edx, 1;
        mov         eax, edx;
    };
}


_gc>2) зачем здесь сдвиг вправо?

не знаю не разбирался я с алгоритмом.

Кстати VC7.1 использует точно такой же подход.
Для функции:
unsigned arithmetic_mean(unsigned a, unsigned b, unsigned c)
{
    return (a + b + c) / 3;
}

получается такой асм:
00401013  mov         eax,dword ptr [esp] 
00401016  mov         ecx,dword ptr [esp+4] 
0040101A  mov         edx,dword ptr [esp+8] 
0040101E  add         edx,ecx 
00401020  add         edx,eax 
00401022  mov         eax,0AAAAAAABh 
00401027  mul         eax,edx 
00401029  shr         edx,1 
0040102B  mov         dword ptr [esp+8],edx
Re[4]: Среднее арифметическое 3-х чисел
От: ArtDenis Россия  
Дата: 22.01.06 08:40
Оценка:
Вариант хороший, но удалось реализовать деление без использования явного
умножения (хоть и с погрешностью). Но, оказалось, что даже небольшая
погрешность меня устраивает...
Posted via RSDN NNTP Server 2.0
[ 🎯 Дартс-лига Уфы | 🌙 Программа для сложения астрофото ]
Re[3]: Среднее арифметическое 3-х чисел
От: Аноним  
Дата: 23.01.06 15:49
Оценка: -1
Здравствуйте, ArtDenis, Вы писали:

AD>ArtDenis пишет:

>> Но этот код даёт достаточно большие погрешности когда summa превышает
>> 256...

AD>Оказалось, что эта погрешность довольно хорошо компенсируется

AD>добавлением ещё одного слогаемого: (summa >> 4)

AD>В результате получается

AD>
AD>result = ((summa >> 4)+summa+(summa<<2)+(summa<<4)+(summa<<6))>>8;
AD>


AD>Хоть результат получился с небольшой погрешностью, но можно сказать, что

AD>вопрос решён

Мдя!!!
Енто будет работать на intel архитектуре как минимум в 3 раза дольше чем (a+b+c)/3
Во первых целочисленное умножение внутри проца уже давно реализуется за счет вещественного.
Во вторых и целочисленное и вещественное оба работают максимум за 1 такт.
В третих, как заметили выше, деление на константу всегда можно осуществить умножением на обратную к ней константу
и последующим сдвигом, а любой нормальный компилер прекрасно об этом осведомлен.
Так что лучше чем (a+b+c)/3 не напишешь.
Re[4]: Среднее арифметическое 3-х чисел
От: McSeem2 США http://www.antigrain.com
Дата: 23.01.06 16:17
Оценка: +2
Здравствуйте, Аноним, Вы писали:

А>Мдя!!!

А>Енто будет работать на intel архитектуре как минимум в 3 раза дольше чем (a+b+c)/3
А>Во первых целочисленное умножение внутри проца уже давно реализуется за счет вещественного.
А>Во вторых и целочисленное и вещественное оба работают максимум за 1 такт.
А>В третих, как заметили выше, деление на константу всегда можно осуществить умножением на обратную к ней константу
А>и последующим сдвигом, а любой нормальный компилер прекрасно об этом осведомлен.
А>Так что лучше чем (a+b+c)/3 не напишешь.

Уважаемый Аноним, прежде чем высказывать подобную ахинею, не мешало бы просто взять и проверить. Деление у него за один такт работает. С плавающей точкой. Ага, шас.

А>целочисленное умножение внутри проца уже давно реализуется за счет вещественного


Ссылки в студию!
McSeem
Я жертва цепи несчастных случайностей. Как и все мы.
Re[2]: Среднее арифметическое 3-х чисел
От: gear nuke  
Дата: 23.01.06 17:54
Оценка:
Здравствуйте, korzhik, Вы писали:

K>В книге Генри Уоррена младшего "Алгоритмические трюки для программистов" приводится такой код (страница 157):


[]

K>В этой книжке так же рассказано как вычислять магические числа и для не 32-ух битных машин.


Звёзды мне говорят, что компилятор сделает то же самое
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.