Sunday 13 August 2017

Ansi C Moving Average


Itoa com GCC Como eu uso itoa () com GCC Arrgghh C / C Parece que itoa () não é padrão ANSI C e não funciona com o GCC no Linux (pelo menos, a versão Im usando). Coisas assim são frustrantes, especialmente se você deseja que o seu código funcione em diferentes plataformas (Windows / Linux / Solaris / o que quer que seja). Muitas pessoas dizem que você deve usar o sprintf para escrever em uma string de caracteres, mas isso não permite um dos recursos do itoa () a capacidade de escrever em uma base diferente de 10. Esta página contém uma série de versões em evolução de um itoa implementação. Os mais antigos estão perto do topo e os últimos na parte inferior. Certifique-se de que você usa a versão mais recente. Antes de avançarmos, gostaria de agradecer às pessoas que contribuíram para as soluções abaixo. Esta função foi elaborada por contribuições de Stuart Lowe (esse eu), Robert Jan Schaper, Ray-Yuan Sheu, Rodrigo de Salvo Braz, Wes Garland, John Maloney, Brian Hunt, Fernando Corradi e Luk225s Chmela. O desenvolvimento abaixo é uma versão inicial descrita por Robert Jan Schaper nos grupos do Google: versão char. 0.1 Isso não se parece com a implementação que eu usei para o qual é mais como itoa (int value, char buffer, int radix). No final, criei minha própria versão que usa uma string std :: em vez de uma seqüência de caracteres. Std :: string version 0.1 Update: (2005/02/11) Ray-Yuan Sheu enviou-me um e-mail com uma versão melhorada que faz um pouco mais de erros ao verificar coisas como uma base que está fora do alcance e para números inteiros negativos. Atualização: (2005/04/08) Rodrigo de Salvo Braz detectou um erro que significava que nada foi retornado quando a entrada era zero. Agora ele retorna quot0quot. Este erro também foi detectado por Luc Gallant. Std :: string version 0.2 Update: (2005/05/07) Wes Garland diz que o lltostr existe no Solaris e em vários outros. Deve retornar um char de muito longo em várias bases numéricas. Há também ulltostr para valores não assinados. Atualização: (2005/05/30) John Maloney apontou vários problemas com a implementação anterior. Uma das principais questões foi a quantidade de alocação de pilha em curso. Ele sugeriu que muito disso fosse removido para acelerar o algoritmo. Abaixo estão duas versões baseadas em suas excelentes sugestões. A versão char é pelo menos 10 vezes mais rápida do que o código acima. A nova versão std :: string é 3 vezes mais rápida do que antes. Embora a versão de caracteres seja mais rápida, você deve verificar se você alocou espaço suficiente para manter a saída. Std :: versão da corda 0.3 charuto versão 0.2 Atualização: (2006/10/15) Luiz Gonlves me diz que, embora não seja um padrão ANSI, o itoa vem em muitos pacotes e está escrito em vários livros didáticos. Ele sugere uma versão escrita em puro ANSI C com base em uma versão da Kernighan Ritchies Ansi C. Um erro de base é relatado pelo retorno de uma string vazia, mas a função não verifica os tamanhos e nenhuma alocação. Esta versão é fornecida abaixo, juntamente com uma versão ligeiramente modificada (ajustes específicos da arquitetura), a versão string std :: C e a versão C char itoa (). Atualização: (2009/07/08) No ano passado, tive algumas sugestões para melhorias nas versões std :: string e char do código. Finalmente tive tempo de testá-los. Na versão std :: string, Brian Hunt sugeriu mover a reserva após a verificação da base para economizar alocações de memória. Isso agiliza as coisas um pouco. Std :: string version 0.4 Também houve várias sugestões para melhorias na versão char do código. Fernando Corradi sugeriu a mudança do abs () para que seja usado apenas uma vez e não usando o operador de módulo (), mas sim calculando-o manualmente, economizando uma divisão. Isso reduz as coisas um pouco: versão char 0.3. No entanto, a Luk225s Chmela reescreveu o código para que ele não tenha um erro de número mais negativo: versão char 0.4. As últimas versões abaixo são as versões mais recentes da função itoa usando char ou Std :: string como você prefere. Não incluí as versões baseadas em Kernighan Ritchie nesta seção porque não tenho certeza do que é o status de direitos autorais para essas. No entanto, as funções abaixo foram desenvolvidas pelas pessoas mencionadas nesta página e estão disponíveis para uso. Std :: versão da corda versão 0.4 char 0.4 Comparação de desempenho Eu fiz alguns testes das versões do itoa, encontrando o tempo médio necessário para realizar conversões, dos números inteiros na faixa -32768 a 32767, em cada base da base 2 à base 20 (O código funciona apenas para a base 16, de modo que as bases extra estão lá apenas como testes). O resumo é apresentado na tabela a seguir: eu sei que isso é viável com o aumento de acordo com: Mas eu realmente gostaria de evitar o uso de impulso. Eu mencionei e não encontrei nenhum exemplo adequado ou legível. Basicamente eu quero acompanhar a média móvel de um fluxo contínuo de um fluxo de números de ponto flutuante usando os números 1000 mais recentes como uma amostra de dados. Qual é a maneira mais fácil de conseguir isso, experimentei usar uma matriz circular, uma média móvel exponencial e uma média móvel mais simples e descobriu que os resultados da matriz circular correspondiam melhor às minhas necessidades. 12 de junho 12 às 4:38 Se suas necessidades são simples, você pode tentar usar uma média móvel exponencial. Simplificando, você faz uma variável de acumulador e, conforme seu código examina cada amostra, o código atualiza o acumulador com o novo valor. Você escolhe um alfa constante que está entre 0 e 1, e calcula isso: Você só precisa encontrar um valor de alfa onde o efeito de uma determinada amostra dura apenas cerca de 1000 amostras. Hmmm, na verdade, não tenho certeza de que isso é adequado para você, agora que eu coloquei aqui. O problema é que 1000 é uma janela bastante longa para uma média móvel exponencial. Não tenho certeza se houver um alfa que espalhe a média nos últimos 1000 números, sem fluxo inferior no cálculo do ponto flutuante. Mas se você quisesse uma média menor, como 30 números ou mais, esta é uma maneira muito fácil e rápida de fazê-lo. Respondeu 12 de junho 12 às 4:44 1 na sua postagem. A média móvel exponencial pode permitir que o alfa seja variável. Então isso permite que ele seja usado para calcular médias base de tempo (por exemplo, bytes por segundo). Se o tempo decorrido desde a última atualização do acumulador for superior a 1 segundo, você deixa alfa ser 1.0. Caso contrário, você pode deixar o alpha ser (usecs desde a última atualização / 1000000). Ndash jxh 12 de junho 12 às 6:21 Basicamente eu quero acompanhar a média móvel de um fluxo contínuo de um fluxo de números de ponto flutuante usando os 1000 números mais recentes como amostra de dados. Observe que as atualizações abaixo atualizam o total como elementos como adicionados / substituídos, evitando a passagem O (N) cara para calcular a soma - necessária para a média - na demanda. Total é feito um parâmetro diferente de T para suportar, e. Usando um longo tempo quando totalizando 1000 long s, um int para char s, ou um duplo para float total s. Isso é um pouco falho em que numsamples poderia ultrapassar o INTMAX - se você se importar, você poderia usar um sinal não assinado por muito tempo. Ou use um membro adicional de dados do bool para gravar quando o recipiente é preenchido pela primeira vez ao andar de bicicleta numsamples em torno da matriz (o melhor que renomeou algo inócuo como pos). Respondeu 12 de junho 12 às 5:19 um assume que quotvoid operator (T sample) quot é realmente quotvoid operatorltlt (T sample) quot. Ndash oPless Jun 8 14 às 11:52 oPless ahhh. Bem visto. Na verdade, eu quis dizer que ele seria um operador vazio () (amostra T), mas é claro que você poderia usar qualquer notação que você gostasse. Vou consertar, obrigado. Ndash Tony D 8 jun 14 às 14:27

No comments:

Post a Comment