Eu estava lendo um artigo sobre más práticas de programação .
Mencionou -
"Código io-io" que converte um valor em uma representação diferente e depois o converte de volta para onde começou (por exemplo: converter um decimal em uma string e depois em um decimal ou preencher uma string e apará-la)
Não entendo por que o exemplo específico que ele dá é uma maneira ruim de escrever programas. Parece-me correto converter de volta se a situação exigir, para que o valor possa ser usado.
Alguém pode explicar mais sobre isso?
programming-practices
anti-patterns
user13107
fonte
fonte
"Roundabout code" that accomplishes in many instructions what could be done with far fewer (eg: rounding a number by converting a decimal into a formatted string, then converting the string back into a decimal)
.if the situation is so that they have to be used?
- que situação seria essa?decimal myValue = decimal.Parse(dataReader["myColumn"].ToString())
é uma irritação minha.Respostas:
Mesmo se você fazer necessidade tanto o numérico e a representação de cadeia de um número, é melhor para converter apenas uma vez e também ficar com o valor original, em vez de converter de novo cada vez que você precisar de um ou do outro.
O princípio é, como sempre, que o código que não existe não pode ter defeitos sutis , enquanto o código que existe frequentemente existe. Isso pode parecer paranóico, mas a experiência nos ensina que é apropriado. Se você aborda a programação com uma ansiedade leve permanente de "Não sou realmente inteligente o suficiente para entender esse sistema complexo", você está no caminho certo.
fonte
É ruim por três razões principais:
Suspeito que o motivo 1 seja o motivo pelo qual sua fonte estava pensando com base no contexto em que foi mencionado.
fonte
Eu reformularia a descrição como "código que converte um tipo em uma representação diferente com o objetivo de fazer algo que poderia ter sido feito tão bem ou melhor no original e depois o converte novamente. Existem muitas situações em que converter algo em um um tipo diferente, agir de acordo com ela e convertê-lo de volta é totalmente apropriado, e a falha nesse procedimento resultaria em comportamento incorreto.
Como um exemplo em que a conversão é boa:
um possui quatro
float
valores de sinais arbitrários cujas magnitudes podem diferir em um fator de até 1.000 e é necessário calcular a soma para 0,625 unidades em último lugar. Converter todos os quatro valores emdouble
, calcular a soma e converter o resultado emfloat
será muito mais eficiente do que qualquer abordagem usandofloat
sozinha.Os valores de ponto flutuante são precisos na melhor das hipóteses para 0,5 unidades em último lugar (ULP). Este exemplo exigiria que o erro de arredondamento do pior caso não fosse superior a 25% acima do erro ideal do pior caso. Usar um duplo produzirá um valor que será preciso dentro de 0,5001 ULP. Embora um requisito de 0,625 ULP possa parecer artificial, esses requisitos geralmente são importantes em algoritmos de aproximação sucessiva. Quanto mais rigorosamente especificado o limite de erro, menor o requisito de iteração do pior caso.
Como um exemplo em que a conversão é ruim:
um tem um número de ponto flutuante e deseja gerar uma string que representará seu valor exclusivamente. Uma abordagem é converter o número em uma string com um certo número de dígitos, tentar convertê-lo novamente e verificar se o resultado corresponde.
Mas esta é realmente uma abordagem ruim. Se uma string decimal representa um valor que fica quase precisamente no ponto intermediário entre dois valores de ponto flutuante, é bastante caro para um método string-to-float garantir que sempre produzirá o
float
valor mais próximo e muitos desses métodos de conversão não mantém tal garantia (entre outras coisas, isso exigiria, em alguns casos, a leitura de todos os dígitos de um número, mesmo que tivesse bilhões de dígitos).É muito mais barato para um método garantir que sempre retorne um valor que esteja dentro de 0,5625 unidades em último lugar (ULP) do valor representado. Uma rotina de formatação "reversível" robusta de decimal para string deve calcular a distância do valor correto ao valor correto e continuar a produzir dígitos até que o resultado esteja dentro de 0,375 (ULP), se não 0,25 (ULP). Caso contrário, pode gerar uma string que alguns métodos de conversão processarão corretamente, mas outros não.
Às vezes, é melhor gerar um dígito que pode não ser "necessário" do que gerar um valor que possa ser mal interpretado. A parte principal é que a decisão de quantos dígitos devem ser impressos deve ser tomada com base em cálculos numéricos relacionados ao processo de impressão, e não no resultado da tentativa de um método específico de converter a string novamente em um número.
fonte
Várias razões
É inútil e aumenta a complexidade - tanto na quantidade de código para escrever e manter, quanto na quantidade de tempo de CPU necessária
Pode perder precisão ou pior, corromper o valor inteiramente
Desperdiça memória (potencialmente, dependendo do idioma) à medida que você acaba armazenando mais representações de um número necessário
Uma boa prática é apenas manter a primeira representação mais precisa possível para todos os dados que você receber. Execute quaisquer cálculos usando esses dados e apenas os converta se precisar gerá-los ou exibi-los em um formato mais fácil de ler.
fonte
Por quê? Porque até os melhores de nós podem cometer erros.
Veja o que aconteceu quando a Microsoft tentou implementar um formato de "ida e volta" especificamente para garantir que as conversões de string <-> flutuantes fossem seguras: https://stackoverflow.com/q/24299692/541686
fonte
Quando eu estava na escola (e pós-graduação em engenharia elétrica), fomos ensinados a dividir depois de multiplicar. Divisão muitas vezes muitos dígitos e são arredondados. Multiplicar após a divisão multiplica o erro de divisão.
As conversões de tipo são as mesmas, você corre o risco de perder dados. CInt (1.3) = 1.
No meu idioma, Basic, apenas fazemos conversões de tipo (um programa VB6 gasta 90% do tempo fazendo conversão ANSI / Unicode, para todas as chamadas de API que o tempo de execução faz).
A conversão de tipo está implícita em tudo o que fazemos.
A cadeia "5" é impressa a partir do literal numérico.
O literal da string unicode é convertido em uma string ANSI e enviado para SetWindowsTextA pelo pacote de formulários.
Mesmo isso funciona no básico
Hoje sou um programador de variantes - nem penso em texto. Eu apenas confio nas autoconversões.
De qualquer forma, minhas 3 irritações são
Atribuir literais de string a variáveis para usá-los (desperdiça memória e lento)
Funções inúteis quando o código pode estar embutido (e o compilador provavelmente irá desfazer sua função e embutir mesmo assim)
Definir todos os objetos para nada como as últimas linhas antes de uma função final ou final do programa.
e um quarto para programas curtos
Escurecer inutilmente suas 3 variáveis em um programa de 5 linhas.
fonte