2012-06-20 28 views
6

Necesito convertir un Float a Decimal (28,10) en SQL Server. Mi problema es que, debido a la naturaleza del flotante y la forma en que se realizan las conversiones, simplemente lanzar el flotador puede hacer que parezca ser el número equivocado para mis usuarios.Convertir Flotante en Decimal (SQL Server)

Por ejemplo:

Float:    280712929.22 
Cast as Decimal:  280712929.2200000300 
What I think I want: 280712929.2200000000 

entiendo un poco acerca de las obras de flotador manera (que es un tipo de datos aproximados, etc.), pero ciertamente no es suficiente para entender por qué se añade el 300 al final. ¿Es simplemente basura como un efecto secundario de la conversión, o es de alguna manera una representación más exacta de lo que almacena el flotador? Para mí, parece que ha sacado precisión de la nada.

En última instancia, necesito que sea preciso, pero también que luzca "bien". Creo que necesito obtener ese número inferior, ya que parece que acabo de agregar ceros finales. es posible? ¿Es esta una buena o mala idea, y por qué? Otras sugerencias son bienvenidas.

Algunos otros ejemplos:

Float:   364322379.5731 
Cast as Decimal: 364322379.5730999700 
What I want:  364322379.5731000000 

Float:   10482308902 
Cast as Decimal: 10482308901.9999640000 
What I want:  10482308902.0000000000 

Nota al margen: la nueva tabla de base de datos que estoy poniendo estos valores en mi es legible por el usuario. En realidad, solo necesitan dos decimales en este momento, pero eso podría cambiar en el futuro, así que decidimos ir con Decimal (28,10). El objetivo a largo plazo es convertir también las columnas flotantes de las que estoy obteniendo mis datos a decimal.

EDITAR: A veces las carrozas que tengo tienen más decimales que las que necesitaré, por ejemplo: -0.628475064730907. En esta situación, el elenco a -0.6284750647 está bien. Básicamente necesito mi resultado para agregar ceros al final del flotante hasta que tenga 10 lugares decimales.

+0

Tal vez he encontrado la respuesta. http://stackoverflow.com/questions/34316871/how-can-the-following-result-of-casting-from-float-to-numeric-be-explained –

Respuesta

8

, es necesario especificar una vez para todo el año, y una vez para añadir cifras decimales vuelta (hay otras maneras también, sin duda, el uso de STR, ROUND etc.):

DECLARE @c TABLE(x FLOAT); 

INSERT @c SELECT 280712929.22; 
INSERT @c SELECT 364322379.5731; 
INSERT @c SELECT 10482308902; 

SELECT x, 
    d = CONVERT(DECIMAL(28,10), x), 
    rd = CONVERT(DECIMAL(28,10), CONVERT(DECIMAL(28,4), x)) 
FROM @c; 

Resultados:

x    d      rd 
-------------- ---------------------- ---------------------- 
280712929.22 280712929.2200000300 280712929.2200000000 
364322379.5731 364322379.5730999700 364322379.5731000000 
10482308902  10482308902.0000000000 10482308902.0000000000 

Si quiere que sea preciso y se vea bien, deje de usar FLOAT, que es un tipo de datos aproximado y desafía la lógica para la mayoría de la gente que no sea estrictamente matemática. Use DECIMAL con una escala mayor a la que necesita y formatéela con la cantidad de decimales que necesita ahora (en sus consultas, o cree una vista, o cree una columna calculada). Si almacena más información de la que necesita ahora, siempre puede exponerla más tarde. También puede optar por no dar a los usuarios acceso directo a su mesa.

+0

la cantidad de números decimales puede diferir, al menos eso es lo que pienso. –

+0

Eso ayuda hasta cierto punto.Sin embargo, eso significa que estaré truncando los dígitos de las carrozas donde en realidad tengo más de 4 lugares decimales en primer lugar, es decir: 517822.18109027. Edita la publicación para aclarar. –

+2

Si necesita decidir condicionalmente cuántas posiciones decimales debe mostrar en cada fila, según el valor de esa fila, creo que está cruzando en el territorio de formateo/procesamiento de cadenas. Probablemente esto se haga mejor en la capa de presentación, no en la base de datos. –

1

No estoy seguro de si esto cae bajo necroposting, pero tuve un problema similar recientemente, así que pensé que podría publicar.

Esto puede ser feo como el pecado, pero parecía funcionar (modificado a partir de la respuesta de Aaron anterior).

DECLARE @myTable TABLE(x FLOAT); 

INSERT INTO @myTable VALUES 
    (280712929.22), 
    (364322379.5731), 
    (10482308902), 
    (-0.628475064730907); 

SELECT x, 
     d = CONVERT(DECIMAL(28,10), x),     
     NewDec = CONVERT(DECIMAL(28,10),   
         CONVERT(DECIMAL(16,15), 
           LEFT(CONVERT(VARCHAR(50), x, 2),17)) 
         * POWER(CONVERT(DECIMAL(38,19),10), 
           RIGHT(CONVERT(varchar(50), x,2),4)))      
FROM @myTable; 

Resultados:

x     d      NewDec 
------------------ ---------------------- ---------------------- 
280712929.22  280712929.2200000300 280712929.2200000000 
364322379.5731  364322379.5731000300 364322379.5731000000 
10482308902   10482308902.0000000000 10482308902.0000000000 
-0.628475064730907 -0.6284750647   -0.6284750647 
Cuestiones relacionadas