segunda-feira, 26 de agosto de 2019

Uma pequena vingança

Isto aconteceu por volta de 1991 na faculdade.

Um determinado computador num laboratório que eu frequentava tinha duas placas de vídeo, sendo que uma era especializada para tratamento de imagens. O monitor dela funcionava na mesma frequência das TVs, ou seja, 60 Hz na vertical e 15750 Hz na horizontal.

Em um dia uma garota que não sabia nada de eletrônica, de como um monitor funcionava etc, (não era culpa dela, pois era no Departamento de Geografia) estava usando este computador, mas eu sabia bem devido meus estudos de eletrônica.

Meu ouvido é (ou era) muito sensível a agudos, exceto o 15750 Hz e vizinhança próxima, pois toda TV faz este apito agudo. Eu escutava, mas não me incomodava.

Ela toda hora resetava o computador, o que fazia o segundo monitor sair de sincronismo na frequência horizontal. Isto me incomodava muito. Eu ficava escutando o barulho agudo fora de frequência certa.

Ela dava boot no computador, chamava o programa, carregava uma imagem, e aí tentava ajustar o monitor, e eu escutando o assovio por este tempo todo.

Aí começava outro martírio meu. Ela não virava o ajuste devagar. Ela ia rapidamente de ponta a ponta, fazendo toda a gama de assovios que aquele oscilador, com a alta tensão do monitor, eram capazes de fazer. E depois de várias tentativas, o comparador de fase do monitor conseguia travar na frequência certa. Mas o oscilador estava ajustado para operar naturalmente em outra frequência, pois dependia de onde ela parasse durante o ajuste.

Eu ainda tinha a certeza, devido aos meus conhecimentos de eletrônica, que ela estava fazendo errado. Isto também me incomodava.

Depois de um tempo de uso ela resetava o computador de novo. E começava tudo de novo. E de novo. E de novo. Etc.

Foram vários ciclos assim. Sei que tem gente que teria surtado, que teria passado bronca nela etc, mas usei outro método.

Em um dos resets que ela deu eu me levantei, fui até o monitor, e comecei a ajustar o monitor de ouvido até que chegasse o mais perto possível da frequência que deveria oscilar, 15750 Hz. Enquanto eu fazia isto ela falou:

- Espere eu colocar uma imagem.

Quando ela colocou a imagem o monitor funcionou direitinho. Em sincronismo. Ela ficou me olhando.

Ela devia estar pensando "Como eu tenho dificuldade de fazer isto com imagem, e ele fez sem imagem no monitor?".

Fiz um sinal do tipo "Ok" com a cabeça, e voltei para o meu canto da sala, onde eu estava trabalhando.

Como vingança, não contei como fiz isto.

Acho que eu tive a vantagem de perceber o que me incomodava, como me incomodava, porque me incomodava, e sabia como resolver. Nem todo mundo tem esta vantagem em muitas situações de incômodo. Acredito que inclusive eu em alguns casos.

domingo, 2 de junho de 2019

Ordem de testes

No outro dia me deparei com um código mais ou menos assim:

int f( bool a, int b, int c, int d )
{
  if( b > c && a == false )
    return 1 ;
  else if( c < d && a == false )
    return 2 ;
  else if( a == true )
    return 3 ;
  else
    return 4 ;
}


Olhem para ele e digam o que está errado, o que pode ser melhorado. Depois de pensar nele, cliquem em "Mais informações" para ver o resto da discussão.

quinta-feira, 7 de fevereiro de 2019

LEDs queimam? Normalmente não, mas...

Apesar de ter criado este blog para falar principalmente de computação, ele não é restrito a isto. Ele é para falar de nerdices, e como sou um nerd antigo, comecei pela eletrônica na minha adolescência, tal como muitos nerds da minha geração. Na década de 1980 ainda era caro ter um computador em casa.

Este texto é sobre LED (Light Emitting Diode - Diodo Emissor de Luz). Ele é um semicondutor que emite luz quando devidamente polarizado, com uma corrente passando por ele da forma direta. Como retificador ele é muito ruim, apesar de ser um diodo semicondutor. Mas é muito bom, eficiente e durável para pequenas fontes de luz. E nos últimos anos, com as melhorias tecnológicas, passaram a ser usados em sinais de trânsito (Uso que eu imaginava desde a década de 1980.), iluminação etc.

Uma das características dos LEDs é uma luz de espectro estreito, com uma cor bem definida, o que é bom para luzes indicadoras, sinais de trânsito, iluminações coloridas etc. LEDs brancos na realidade não existem. Já tratei sobre luz branca usando LEDs aqui.

Mas o assunto aqui é "LEDs queimam?".

quarta-feira, 22 de agosto de 2018

C: Imprimindo percentual

É muito comum uma saída com percentual, e com o símbolo '%' depois do número, mas a printf() usa este caractere para formatação de saída. Qual é a solução?

Já vi muitas vezes sendo resolvido assim:

printf( "%f %s\n",pecent,"%" );

Isto está errado, realmente muito errado. Mas por que está errado, e qual é a solução?

C: Ponteiros para função

Em C existe um recurso muito incomum. Ponteiros para funções. Não sei de outra linguagem que tenha isto, além de C e C++. Não sei se outras linguagens derivadas do C, como Java e C# tem isto (Podem responder nos comentários). Dá para fazer em Assembly, mas isto não conta.

Qual é o uso disto? Depende do caso. É possível passar uma função, aliás, o endereço de uma função, como parâmetro para outra função, para que ela a chame dentro dela, por exemplo.

Então vamos a um exemplo prático:

terça-feira, 17 de abril de 2018

Testando os quadrados por somas de ímpares de Pitágoras e otimização

Eu vi a seguinte publicação no Facebook e pensei em testar computacionalmente até um limite grande. Para quem não quer, ou não tem como, acessar o Facebook, reproduzo a imagem abaixo:


Quando escrevia o programa notei que estava fazendo errado, que o código iria gastar tempo demais inutilmente, então reescrevi o código resolvendo isto.

A primeira versão do programa foi:

#include        <stdio.h>

int     main()
{
        register unsigned long long numero, impar, soma ;

        for( numero = 1 ; numero <= 1000000000 ; numero++ )
        {
                register int    i ;

                for( i = numero, impar = 1, soma = 0 ; i ; i--, impar +=2 )
                        soma += impar ;

                if( soma != numero*numero )
                        printf( "Falhou para o numero %llu\n",numero );
        }
}


Esta é a descrição literal do problema, mas nem sempre a descrição literal é a melhor a ser implementada. O que está errado neste programa?

sexta-feira, 13 de novembro de 2015

C: Strings e ponteiros, um caso para pensar

O que está errado com função abaixo:

char mensagem[100] ;

processa()
{
    /* processa */
    if( /* uma condição de erro */ )
        strcpy( mensagem,"Deu erro 1" );
    else
    {
        /* processa */
        if( /* uma condição de erro */ )
            strcpy( mensagem,"Deu erro 2" );
        else
        {
            /* processa */
            if( /* uma condição de erro */ )
                strcpy( mensagem,"Deu erro 3" );
            else
                strcpy( mensagem,"Funcionou direitinho" );
        }
    }
}

Antes de prosseguir lendo, pare e pense um pouco.

C: Sobre strings e uma pequena eliminação de strlen, strcpy

Existem alguns truques que podem ser usados para acelerar processamento de strings, mas exigem uma compreensão de como funcionam as strings em C.

As strings em C são chamadas de Null Terminated Strings, ou strings terminadas por nulo. O caractere null, que é equivalente ao número inteiro zero (note, não é o caractere zero), estará logo após do último caractere da string, marcando que a string terminou.

E o conceito de string se confunde com o array de caracteres. Na realidade, é um array de caracteres, e o que vai ditar se é uma string ou um array de caracteres banal é a forma com que o programador fez o código lidar com ela.

quarta-feira, 16 de setembro de 2015

A fonte de dores de cabeça

Tive umas instabilidades no meu computador, especialmente ligadas a discos.

Eram discos que ficavam erráticos, dando erros, causando panes no sistema etc. Sorte que o FreeBSD, o sistema que uso, lida relativamente bem com estas coisas, dentro do possível. Na versão 10, se um disco dá problemas, sem ser um dos fundamentais do sistema, ele é abandonado, mas o sistema dificilmente dá pane. A versão 11, que estou usando, e que ainda está em desenvolvimento, me pareceu lidar pior com isto.

Eu aposentei alguns HDs por que deram algumas panes, mas paradoxalmente o S.M.A.R.T. tinha me dito que estavam bons. Troquei alguns adaptadores de alimentação, do tipo MOLEX  para SATA, e alguns cabos SATA, e tive poucas melhoras.

Um dos HDs aposentados era o antigo do meu notebook, que estava em um gabinete externo. Ele tinha parado de funcionar.

Recentemente a situação ficou pior, e cheguei a pensar que o HD novo de 4 TB estava morrendo, pois ele dava pane e era abandonado pelo sistema com muita frequência. A piora, em parte, coincidiu com a colocação de um SSD, além dos 5 HDs que costumavam ficar ligados.

Mas a coisa estava caótica demais para parecer que era ele. Fiz trocas de cabos SATA e não deu em nada.

Comecei a desconfiar de problemas de fonte de alimentação, mesmo com o sistema dando panes relacionadas com HDs, e não com placa mãe. A fonte poderia não estar aguentando tanta carga de HDs.

A BIOS tem um recurso que é mostrar as tensões da fonte de alimentação, então, depois de uma das muitas panes, entrei nela para ver. As tensões de 3.3V e 5.0V estavam muito baixas, com cerca de 3.0V e 4.5V respectivamente. Estavam com 10% de erro, que é mais do que os 5% permitidos no padrão esperado. A de 12V estava boa.

Como muita da eletrônica dos HDs dependem da alimentação de 5.0V, usando a de 12V só para os motores, pensei em panes das controladoras dos HDs. E o SSD não tem motor, portanto só deve usar a alimentação de 5.0V, talvez tenha aumentado mais ainda a carga sobre ela.

Num teste rápido, eu desliguei o gravador de DVD e um dos HDs, e as fontes de 3.3V e 5.0V melhoram um pouquinho, com a segunda marcando 4.6V. Mesmo assim o sistema ficou instável, só que menos instável.

Então resolvi arriscar comprar uma fonte nova, de 500W, como a antiga (que eu pensava se de 430W). Foi uma boa compra. Ela é mais silenciosa, e a medição de tensão ficou praticamente cravada, variando cerca de 1% por volta da valor nominal. Isto com 5 HDs internos, um USB e um SSD.

Fui colocando carga, fazendo os testes nos discos, colocando o gravador de DVD etc. O sistema se mostrou estável, bem estável.

No momento estou com 5 HDs internos, 2 USB (o antigo do notebook mencionado acima voltou a funcionar, portanto deveria ser problema com a alimentação de 5.0V), 1 SSD, o gravador de DVD plugados, e está tudo estável.

Fontes de alimentação podem ser fontes de grandes dores de cabeça, além de serem a peça mais chata para substituir num computador. Elas podem sutilmente lhe infernizar a vida.

PS: Agora tenho que retestar um bando de HDs aposentados. Sorte que não joguei-os no lixo.

domingo, 25 de março de 2012

C: Um exemplo de simplificação de expressão lógica

No outro dia vi uma expressão assim:

        if(((situacao == situacao_a) ||
            ((
situacao == situacao_b) && (strcmp(string,UMA_MACRO) == 0))) ||
            ((
situacao == situacao_c) ||
            ((
situacao == situacao_d) && (strcmp(string,UMA_MACRO) == 0))))
        {

                        /* ... */
        }


Este código acima está abaixo do ótimo, tanto em geração de código quanto em desempenho. Mas como otimizar?

Antes de continuar lendo, que tal você mesmo tentar fazer uma versão melhor dele? O artigo sobre avaliação incompleta pode ajudar.