Eu me deparei com esse idioma de programação recentemente:
const float Zero = 0.0;
que é então usado nas comparações:
if (x > Zero) {..}
Alguém pode explicar se isso é realmente mais eficiente, legível ou sustentável do que:
if (x > 0.0) {..}
NOTA: Posso pensar em outras razões para definir essa constante. Estou apenas pensando em seu uso neste contexto.
x
tiver tipofloat
,x > 0.0
força a promoção paradouble
, o que pode ser menos eficiente. Essa não é uma boa razão para usar uma constante nomeada, apenas para garantir que suas constantes tenham o tipo correto (por exemplo0f
,float(0)
oudecltype(x)(0)
).13.37
não éfloat
, édouble
. Então, se você queria umfloat
, é concebível que seu tutor estivesse correto. Em alguns contextos (por exemplo, a atribuição a um flutuador)13.37
será implicitamente convertido para ofloat
que você queria, e em outros contextos (por exemplo, dedução de tipo de modelo) não será, enquanto ostatic const float
sempre começa como o tipo que você pretendia. Portanto, mais seguro para o tipo. Lembre-se, assim seria13.37f
! Existem outras razões para evitar a macro que não a "segurança de tipo", portanto, é tão provável que o tutor esteja argumentando mal.Respostas:
Os possíveis motivos são cache, nomeação ou forçar o tipo
Armazenamento em cache (não aplicável)
Você deseja evitar o custo de criar um objeto durante o ato de comparação. Em Java, um exemplo seria
isso envolve um processo de criação bastante pesado e é melhor atendido usando o método estático fornecido:
Isso permite comparações sem incorrer em um custo repetido de criação, pois o BigDecimal é pré-armazenado em cache pela JVM durante a inicialização.
No caso do que você descreveu, um primitivo está executando o mesmo trabalho. Isso é amplamente redundante em termos de cache e desempenho.
Nomeação (improvável)
O desenvolvedor original está tentando fornecer uma convenção de nomenclatura uniforme para valores comuns em todo o sistema. Isso tem algum mérito, especialmente com valores incomuns, mas algo tão básico quanto zero só vale a pena no caso do cache anterior.
Forçando o tipo (provavelmente)
O desenvolvedor original está tentando forçar um tipo primitivo específico para garantir que as comparações sejam convertidas no tipo correto e possivelmente em uma escala específica (número de casas decimais). Tudo bem, mas o nome simples "zero" provavelmente é um detalhe insuficiente para este caso de uso, com ZERO_1DP sendo uma expressão mais apropriada da intenção.
fonte
typedef
manteria o tipo da variável em exatamente um local e permitiria a alteração sem precisar alterar o código.0.0f
.byteVar1 = byteVar2 Or CB128
parece um pouco melhor do quebyteVar1 = byteVar2 Or CByte(128)
. Obviamente, ter um sufixo numérico adequado para bytes seria melhor ainda. Como o C # promove os operandos de bit a bit para os operadores,int
mesmo quando o resultado é garantido para caber em umbyte
, o problema não é tão relevante lá.É por causa do "Tooling Nagging"
Uma possível razão pela qual não vejo a lista aqui é porque muitas ferramentas de qualidade sinalizam o uso de números mágicos . Muitas vezes, é uma prática ruim ter números mágicos lançados em um algoritmo sem torná-los claramente visíveis para alterações posteriormente, especialmente se eles forem duplicados em vários locais do código.
Portanto, embora essas ferramentas tenham razão ao sinalizar esses problemas, elas geralmente geram falsos positivos para situações em que esses valores são inofensivos e provavelmente mais estáticos, ou apenas valores de inicialização.
E quando isso acontece, às vezes você enfrenta a escolha de:
Sobre o desempenho
Depende da linguagem, eu acho, mas isso é bastante comum em Java e não tem impacto no desempenho, pois os valores são incorporados no tempo de compilação se forem constantes reais
static final
. Não teria impacto em C ou C ++ se elas fossem declaradas como constantes ou mesmo como macros de pré-processador.fonte
Isso pode fazer sentido, pois define explicitamente
Zero
para ser do tipofloat
.Pelo menos em C e C ++, o valor
0.0
é do tipodouble
, enquanto o equivalentefloat
é0.0f
. Então, supondo quex
você compare também é sempre umfloat
ditadoenquanto, na verdade, promova
x
paradouble
corresponder ao tipo0.0
que pode levar a problemas (principalmente nos testes de igualdade). A comparação sem conversão seria, obviamente,que faz o mesmo que
No entanto, acho que seria muito mais útil habilitar avisos de conversões no compilador, em vez de fazer com que os usuários escrevessem códigos estranhos.
fonte
Primeiro de tudo, aqui zero é definido como
float
, nãoint
. Obviamente, isso não afeta nada na comparação, mas em outros casos, quando essa constante é usada, pode fazer diferença.Não vejo outra razão pela qual
Zero
seja declarada uma constante aqui. É apenas um estilo de codificação, e é melhor seguir o estilo, se ele for usado em qualquer outro lugar desse programa.fonte
É quase certamente exatamente tão eficiente durante a execução (a menos que seu compilador seja muito primitivo) e levemente menos eficiente durante a compilação.
Quanto a ser mais legível do que
x > 0
... lembre-se de que existem pessoas que honestamente, genuinamente, pensam que COBOL foi uma ótima idéia e um prazer trabalhar com ele - e também existem pessoas que pensam exatamente o mesmo sobre C. até que existem alguns programadores com a mesma opinião sobre C ++!) Em outras palavras, você não terá um acordo geral sobre esse ponto e provavelmente não vale a pena brigar.fonte
Se você estava escrevendo código genérico (isto é, não específico do tipo), então é muito possível. Uma
zero()
função pode ser aplicada a qualquer tipo algébrico ou qualquer tipo que seja uma adição de grupo. Pode ser um número inteiro, pode ser um valor de ponto flutuante, pode até ser uma função se sua variável for, digamos, uma função dentro de algum espaço linear (por exemplo, x é uma função linear da forma z -> a_x * z + b_x) e, em seguida,zero()
fornece à função a e b, sendo amboszero()
do tipo subjacente.Então, você esperaria esse código em, digamos, C ++ possivelmente (embora um
zero()
AFAIK não seja muito comum), ou em Julia, e talvez em outros idiomas.fonte