Ver Mensaje Individual
  #27  
Antiguo 28-02-2011
Avatar de Al González
[Al González] Al González is offline
In .pas since 1991
 
Registrado: may 2003
Posts: 5.604
Reputación: 29
Al González Es un diamante en brutoAl González Es un diamante en brutoAl González Es un diamante en brutoAl González Es un diamante en bruto
Cita:
Empezado por Delphius Ver Mensaje
Y como ha mencionado Al, por defecto se aplica el redondeo al par más cercano o también conocido como método del banquero.
No Marcelo, el método de redondeo que utilizan los motores de bases de datos para resolver números que están "a la mitad", no es el "del banquero" (al par más cercano), sino hacia el infinito, es decir, hacia el valor absoluto superior (1.5 queda como 2; 2.5 queda como 3; -1.5 queda como -2; -2.5 queda como -3). Esto según lo visto en el enlace que puse mensajes más arriba. Cabe decir que todavía no he tenido la suerte de mirar esa norma en ningún documento, a pesar de que tiene toda la pinta de ser una regla formal (sería mucha coincidencia que todos esos fabricantes de bases de datos hubiesen optado por el mismo tipo de redondeo sin un consenso previo).

Ahora, respecto a los resultados que todos nosotros hemos presentado en los mensajes más recientes, queda claro que el molde de tipo "Cast As Integer" trabaja de la misma manera en todas las versiones de Firebird, manera que, por cierto, es la esperada: números a la mitad "suben" (redondeo hacia el infinito). En esto no hay sorpresas.

La ÚNICA diferencia en todo esto es, según se ve, la forma en que cada versión de Firebird maneja las divisiones entre números de tipo entero. Unas versiones truncan la parte fraccionaria y otras no. Por ello es que la sentencia que por ahora valdría la pena probar es solamente la de una simple división entre enteros:
Código SQL [-]
Select 3 / 2 From RDB$DataBase
Ya vimos que una sentencia como esa, trunca la parte fraccionaria del resultado (1.5 -> 1), excepto en un rango de versiones que va, tentativamente, de la 1.5.5 a la 2.0.

Lo que convendría dejar claro es que, aun con esa diferencia de comportamiento entre un rango de versiones y el resto, ninguna versión de Firebird falla en redondear consistentemente un 1 como 1 y un 1.5 como 2 al aplicarle un Cast As Integer. ¿Estamos de acuerdo?

Despejado el problema, queda por un lado recomendarle a Joe_Balda, quien usa una de las versiones del "rango rebelde" (Firebird 2.0):

a) actualizarse a una versión superior.

b) hacer un truncamiento de la parte fraccionaria del resultado de la división, ya sea con una UDF, usando Substring, etc.

Por otra parte, la investigación de por qué unas versiones de Firebird truncan las divisiones de enteros y otras no. Y lo que son las cosas, mientras escribía estas líneas tuve la suerte de encontrar este documento:

http://www.firebirdsql.org/manual/qs...ebird-sql.html

Cita:
Firebird concuerda con el estándar SQL truncando el resultado (cociente) de un cálculo entero/entero hacia el siguiente entero más bajo. Esto puede tener resultados [que quizá le parezcan] raros a menos que usted esté consciente de ello [de esta regla del estándar SQL].

Por ejemplo, este cálculo es correcto en SQL:

1 / 3 = 0
La fuente del documento parece lo suficientemente oficial como para dar por sentado que:

Las versiones 1.5.5, 1.5.6 y 2.0 tienen un defecto (bug) con la división entre enteros.

Un abrazo acorde al estándar.

Al González.

Última edición por Al González fecha: 28-02-2011 a las 07:00:21.
Responder Con Cita