¿Cero como constante?

14

Recientemente he encontrado este lenguaje de programación:

const float Zero = 0.0;

que luego se usa en las comparaciones:

if (x > Zero) {..}

¿Alguien puede explicar si esto es realmente más eficiente, legible o mantenible que:

if (x > 0.0) {..}

NOTA: puedo pensar en otras razones para definir esta constante, solo me pregunto sobre su uso en este contexto.

    
pregunta NWS 03.07.2012 - 12:42

6 respuestas

29

Los posibles motivos son el almacenamiento en caché, la asignación de nombres o el tipo de restricción

Almacenamiento en caché (no aplicable)

Desea evitar el costo de crear un objeto durante el acto de comparación. En Java un ejemplo sería

BigDecimal zero = new BigDecimal ("0.0");

esto implica un proceso de creación bastante pesado y se sirve mejor utilizando el método estático proporcionado:

BigDecimal zero = BigDecimal.ZERO;

Esto permite comparaciones sin incurrir en un costo repetido de creación, ya que la JVM precede en caché a BigDecimal durante la inicialización.

En el caso de lo que ha descrito, una primitiva está realizando el mismo trabajo. Esto es en gran medida redundante en términos de almacenamiento en caché y rendimiento.

Nombres (poco probable)

El desarrollador original está tratando de proporcionar una convención de nomenclatura uniforme para los valores comunes en todo el sistema. Esto tiene algún mérito, especialmente con valores poco comunes, pero algo tan básico como cero solo vale la pena en el caso del caso de almacenamiento en caché anterior.

Tipo de forzamiento (más probable)

El desarrollador original está intentando forzar un tipo primitivo particular para garantizar que las comparaciones se conviertan a su tipo correcto y posiblemente a una escala particular (número de lugares decimales). Esto está bien, pero el nombre simple "cero" probablemente no sea suficiente para este caso de uso, ya que ZERO_1DP es una expresión más apropiada de la intención.

    
respondido por el Gary Rowe 03.07.2012 - 13:02
6

Es debido a la "Regulación de herramientas"

Una posible razón que no veo en esta lista es porque muchas herramientas de calidad marcan el uso de números mágicos . A menudo es una mala práctica tener números mágicos introducidos en un algoritmo sin que sean claramente visibles para el cambio posterior, especialmente si están duplicados en varios lugares en el código.

Entonces, si bien estas herramientas tienen razón al señalar estos problemas, a menudo generan falsos positivos para situaciones en las que estos valores son inofensivos y es más probable que sean estáticos, o que solo sean valores de inicialización.

Y cuando eso sucede, a veces te enfrentas a la elección de:

  • marcándolos como falsos positivos, si la herramienta lo permite (generalmente con un comentario especialmente formateado, lo cual es molesto para las personas que NO usan la herramienta)
  • o extrayendo estos valores a constantes, ya sea que importe o no.

Acerca del rendimiento

Depende del lenguaje que supongo, pero esto es bastante común en Java y no tiene impacto en el rendimiento, ya que los valores están en línea en tiempo de compilación si son constantes reales static final . No tendría un impacto en C o C ++ si se declararan como constantes o incluso como macros de preprocesador.

    
respondido por el haylem 03.07.2012 - 13:11
5

Esto podría tener sentido ya que define explícitamente que Zero es del tipo float .

Al menos en C y C ++, el valor 0.0 es del tipo double , mientras que el equivalente float es 0.0f . Entonces, suponiendo que el x con el que se compara es también un float que dice

x > 0.0

mientras que en realidad promueve x a double para que coincida con el tipo de 0.0 , lo que podría llevar a problemas (especialmente con pruebas de igualdad). La comparación sin conversión sería, por supuesto,

x > 0.0f

que hace lo mismo que

float Zero = 0.0; // double 0.0 converted to float  
x > Zero

Sin embargo, creo que sería mucho más útil habilitar las advertencias de conversiones en el compilador en lugar de que los usuarios escriban código extraño.

    
respondido por el Benjamin Bannier 03.07.2012 - 13:10
1

En primer lugar, aquí el cero se define como float , no int . Por supuesto, esto no afecta a nada en la comparación, pero en otros casos, cuando se usa esta constante, puede hacer una diferencia.

No veo ninguna otra razón por la que Zero se declare constante aquí. Es solo un estilo de codificación, y es mejor seguir el estilo si se usa en cualquier otro lugar en ese programa específico.

    
respondido por el superM 03.07.2012 - 12:48
1

Es casi seguro que es igual de eficiente durante la ejecución (a menos que su compilador sea muy primitivo) y un poco menos eficiente durante la compilación.

En cuanto a si es más legible que x > 0 ... recuerde que hay personas que, sinceramente, piensan que COBOL fue una gran idea y un placer trabajar con ellos, y luego hay personas que piensan exactamente lo mismo sobre C. (Se rumorea que incluso existen programadores con la misma opinión sobre C ++!) En otras palabras, no va a obtener un acuerdo general sobre este punto, y probablemente no valga la pena luchar encima.

    
respondido por el Kilian Foth 03.07.2012 - 12:49
0
  

[es] esto es realmente más eficiente o legible o mantenible que:

if (x > 0.0) {..}

Si estaba escribiendo el código genérico (es decir, no específico del tipo), entonces muy posiblemente. Una función zero() podría aplicarse a cualquier tipo algebraico, o cualquier tipo que sea un grupo w.r.t. adición. Podría ser un número entero, podría ser un valor de punto flotante, incluso podría ser una función si su variable es, digamos, una función dentro de algún espacio lineal (por ejemplo, x es una función lineal de la forma z - > a_x * z + b_x) y luego zero() proporciona la función con a y b, ambos son zero() del tipo subyacente.

Por lo tanto, tal vez esperaría ese código en, digamos, C ++ (aunque un zero() no es un AFAIK muy común), o en Julia, y tal vez en otros idiomas.

    
respondido por el einpoklum 09.01.2018 - 15:35

Lea otras preguntas en las etiquetas