+15
- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
#include <iostream>
#include <functional>
template<class Container, class F, class A>
auto accumulate(Container c, F f, A acc) -> A
{
auto id = [](const A& a) -> const A& {return a;};
typedef decltype(std::begin(c)) Iterator;
const std::function<A(const Iterator& lst, const std::function<A(const A&)>&)> doIt =
[&](const Iterator& lst, const std::function<A(const A&)>& cont) -> A
{
if(lst==c.end())
return cont(acc);
else
{
auto conter=[&](const A& acc) -> A {return cont(f(*lst, acc));};
return doIt(lst+1, conter);
}
};
return doIt(std::begin(c), id);
}
int main() {
std::cout<<accumulate({1,2,3,4}, std::plus<int>(), 0);
return 0;
}
Похоже написал какой-то монадолог.
http://ideone.com/y4Dm9z
Пример использования accumulate сам накатал.
Я побаловался с этим примером, чтобы разобраться и GCC ожидаемо упал:
http://ideone.com/XWfuoP
Я убежден, что эта функция должна была выглядеть как-то так:
template<class Container, class F>
accumulate(const Container& c, const F& f=std::plus<decltype(*(std::begin(c)))>(), const decltype(*(std::begin(c))) acc=decltype(*(std::begin(c)))()) -> decltype(*(std::begin(c)))
{
return std::accumulate(c.begin(), c.end(), acc, f);
}
//Вызов этой функции:
accumulate({1,2,3,4});
Ну и я погуглил на тему этого говнокода и нашел на функциональном языке похожий:
let fold_right func acc list =
let rec loop list cont = //сюда мы передаем текущую функцию континуации
match list with
|[] -> cont acc //а вот и наше ключевое вычисление.
|head::tail -> loop tail (fun racc -> cont (func head racc))
loop list (fun x -> x)
Запостил:
LispGovno,
23 Ноября 2012
КРЕСТОБАТХЁРТ
Вообще как сейчас у современных процессоров с производительностью FPU и связь производительности с точностью и как с этим было раньше? У меня очень широкий парк машин. От самых современных до 486. И на всех это должно работать.
Что посоветуете? 64 или 80?
Некторые компиляторы могут трактовать его либо как "80-bit extended precision" либо как "128-bit quadruple precision". Понятно что скорости это не прибавит. На PowerPC с gcc этот тип будет в итоге "double-double" (128 бит, но с другим соотношением бит в мантиссе/экспоненте).
Так что, лучше отказатья от него и использовать double.
Также многие компиляторы (например интеловский) считают простой double вещественным с расширенной точностью (80-бит). Так-что возможно разницы вообще не будет.
А также:
можно провести объективный тест с передачей в функции, сложением, умножением и выбрать то, что будет быстрее.
http://govnokod.ru/12180#comment162162
http://ideone.com/rlTw1w
Сам удивился результатам.
1. Нет ощутимой разницы между float и double.
2. Совсем небольшое различие между double и long double.
3. sizeof(long double) == 12! (96 бит)
> sizeof(long double) == 12
Для выравнивания на 4 байта. Заполняться будут первые 10, в остальных окажется мусор.
> А что удивляться
Ты убиваешь всю магию.
Да и бонус можно получить только на джвух операциях - делении и корне. Говорят, что всякие синусы\косинусы от этого не ускоряются.
на -O2 компилятор выкидывает практически все, что ты понаписал (см gcc.godbolt.org)
http://ideone.com/oMMBWw