2009-11-07 14 views
9

Después de comprometerme más con la capacitación de nuevos ingenieros y la lectura de Jon Skeet's DevDays presentation, he comenzado a reconocer que muchos ingenieros no tienen claro cuándo utilizar qué tipos de datos numéricos. Aprecio el papel que desempeña un título formal en ciencias de la computación para ayudar con esto, pero veo muchos ingenieros nuevos que muestran incertidumbre porque nunca han trabajado con grandes conjuntos de datos o software financiero, ni programación de problemas de estadísticas o de archivos, ni problemas complejos de almacenamiento de datos. .Usando el tipo de datos numéricos correctos

Mi experiencia es que la gente realmente asimilen conceptos cuando se explican dentro de contexto. Estoy buscando buenos ejemplos de problemas de programación real donde ciertos datos se representan mejor utilizando el tipo de datos. Trate de mantenerse alejado de los ejemplos de libros de texto si es posible. Estoy Tagging esto con Java, pero no dude en dar ejemplos en otros idiomas y volver a etiquetar:

Entero, Largo, Double, Float, BigInteger, etc ...

Respuesta

26

Realmente no creo que necesite ejemplos o nada complejo. Esto es simple:

  • ¿Es un número entero?
    • ¿Puede ser> 2^63? BigInteger
    • ¿Puede ser> 2^31?
    • largo
    • De lo contrario int
  • ¿Es un número decimal?
    • ¿Es un valor aproximado correcto?
      • doble
    • ¿Tiene que ser exactos? (Ejemplo: los importes monetarios!)
      • BigDecimal

(Cuando digo ">", me refiero a "mayor en valor absoluto", por supuesto.) Nunca he usado un byte o un carácter para representar un número, y nunca he usado un período corto. Eso es en 12 años de programación Java. ¿Flotador? Meh. Si tiene una gran variedad y tiene problemas de memoria, supongo.

Tenga en cuenta que BigDecimal es algo mal llamada; sus valores do no tienen que ser grandes para necesitarlo.

+4

Me gusta mucho la forma en que lo rompiste. El 100% está de acuerdo contigo en char, short y Floats con Java. – Scanningcrew

+0

Una sugerencia adicional: si se trata de un número decimal, y debe ser exacto, pero la cantidad máxima de decimales se conoce de antemano (como con $ values: 2 dec. Places), entonces puede usar int/long, y divide la salida. Eso evita los problemas con BitDecimal (rendimiento, operadores incómodos). – sleske

4

BigDecimal es el mejor cuando se trata de mantener cálculos exactos de coma flotante y poder especificar la precisión deseada. Creo que Float (y hasta cierto punto el doble) ofrece beneficios de rendimiento sobre BigDecimal, pero a costa de la precisión y la facilidad de uso.

+0

+1 para contrarrestar a un idiota que ha votado esta respuesta – kar

+0

¡LOL, gracias! –

1

normalmente numérico si estamos hablando independenat máquina (32/64 bits) tamaño de tipo de datos son como abajo,

número entero: 4 bytes

largo: 8 bytes

decimal/float: 4bytes

dobles: 8 bytes

y los tamaños reducidos a un medio para valores con signo (por ejemplo: para 4bytes, sin signo = 4billions, = firmados 2billions)

bigInt (depende de la implementación del idioma) a veces hasta 10 bytes.

para el archivado de datos de gran volumen (como el motor de búsqueda) recomendaría byte y short para guardar espacios.

bytes: 1 byte, (0-256 sin firmar, -128-128 firmado)

corta: 2 bytes (65k sin firmar)


digamos que desea guardar el registro de la edad, ya que nadie vive más de 150, por lo que usaste el tipo de datos BYTE (lee arriba para el tamaño) pero si utilizas INTEGER ya has desperdiciado 3bytes extra y dime en serio que vivirás más de 4 billones de años.

+1

Ejemplo clásico de optimización prematura ... A menos que esté guardando una GRAN matriz o base de datos de personas de edades USE INT. No hay inconveniente si el tamaño no es un problema (y en la mayoría de los casos modernos no lo es) y lo bueno es que no se rinde a errores estúpidos como el error Y2K debido a la optimización prematura. –

+0

yo estaba hablando de la EDAD, no la fecha de nacimiento lol. Conozca los temas que he creado, he estado desarrollando un motor de búsqueda a escala web personalizado (formato de índice personalizado altamente optimizado) durante casi 2 años, y los índices de confianza en la web es un gran problema cuando se trata de la optimización del espacio en disco. y uso INT (32) y LONG (64) para la fecha para ahorrar espacio y evitar los límites de Y2K. – kar

+0

también solo FYI sawas, guardamos algunos de nuestros datos en 3bytes y 5bytes, cargamos en espacio de memoria en 4/8bytes normales para una máxima eficiencia de espacio en lugar de VInt (lucene) para obtener una velocidad extra al cargarlo. Así que sí, sé de qué estoy hablando. – kar

4

Un punto importante que quizás desee articular es que casi siempre es un error comparar los números de coma flotante para la igualdad. Por ejemplo, el siguiente código es muy probable que falle:

double euros = convertToEuros(item.getCostInDollars()); 
if (euros == 10.0) { 
    // this line will most likely never be reached 
} 

Ésta es una de las muchas razones por las que desea utilizar números discretos para representar la moneda.

Cuando absolutamente debe comparar los números de punto flotante, solo puede hacerlo aproximadamente; algo que en la medida de:

double euros = convertToEuros(item.getCostInDollars()); 
if (Math.abs(euros - 10.0) < EPSILON) { 
    // this might work 
} 

En cuanto a ejemplos prácticos, mi regla de oro es habitual algo como esto:

  • doble: pensar largo y tendido antes de utilizarla; ¿Vale la pena el dolor?
  • flotador: no lo use
  • bytes: más a menudo se utiliza como byte [] para representar algunos datos binarios sin
  • int: esta es su mejor amigo; Úselo para representar la mayoría de las cosas
  • de largo: utilice esto para marcas de tiempo e ID de base de datos
  • BigDecimal y BigInteger: si conoce estas posibilidades, es probable que sepa lo que hace, por lo que no necesita mi consejo

que se dan cuenta de que estos no son terriblemente reglas científicas del pulgar, pero si su público objetivo no son los informáticos, que podría ser el mejor pegarse a lo básico.

+0

No soy un gran admirador de su código de ejemplo, porque para empezar no debe usar el doble para datos monetarios. Deberías usar BigDecimal. Ver p. esto: http://stackoverflow.com/questions/965831/how-to-parse-a-currency-amount-us-or-eu-to-float-value-in-java/965858#965858 y el artículo 48 en el libro Effective Java (2nd ed). – Jonik

+2

Jonik - nos está mostrando por qué el doble es malo. Y él dice "he aquí cómo hacerlo * si es absolutamente necesario * usar punto flotante". No hay ninguna falta aquí. –

+0

Por cierto, creo que esta es una respuesta excelente, al menos tan buena como la mía. la única excepción es que BigDecimal realmente debería ser urgido como la única forma de manejar números decimales con precisión; no solo "oh, probablemente sabes lo que estás haciendo ...". –

1

VInt's en Lucene son el diablo. El pequeño beneficio en el tamaño se ve compensado enormemente por la penalización de rendimiento al leerlos byte por byte.

Algo bueno de lo que hablar es la compensación de espacio versus tiempo. Guardar 200mb fue excelente en 1996, pero en 2010, es terrible golpear búfer de IO leyendo un byte a la vez.

Cuestiones relacionadas