Question

Est-ce que quelqu'un sait pourquoi, avec SQLServer 2005

SELECT CONVERT(DECIMAL(30,15),146804871.212533)/CONVERT(DECIMAL (38,9),12499999.9999)

me donne 11.74438969709659,

mais lorsque j'augmente le nombre de décimales sur le dénominateur à 15, je reçois une réponse moins précise:

SELECT CONVERT(DECIMAL(30,15),146804871.212533)/CONVERT(DECIMAL (38,15),12499999.9999)

donnez-moi 11.74438969

Était-ce utile?

La solution

Pour la multiplication, nous additionnons simplement le nombre de décimales dans chaque argument (en utilisant un crayon et du papier) pour calculer les décimales en sortie.

Mais la division vous coupe la tête. Je vais me coucher maintenant.

Toutefois, en termes SQL, exactement comme prévu.

--Precision = p1 - s1 + s2 + max(6, s1 + p2 + 1)
--Scale = max(6, s1 + p2 + 1)

--Scale = 15 + 38 + 1 = 54
--Precision = 30 - 15 + 9 + 54 = 72
--Max P = 38, P & S are linked, so (72,54) -> (38,20)
--So, we have 38,20 output (but we don use 20 d.p. for this sum) = 11.74438969709659
SELECT CONVERT(DECIMAL(30,15),146804871.212533)/CONVERT(DECIMAL (38,9),12499999.9999)


--Scale = 15 + 38 + 1 = 54
--Precision = 30 - 15 + 15 + 54 = 84
--Max P = 38, P & S are linked, so (84,54) -> (38,8)
--So, we have 38,8 output = 11.74438969
SELECT CONVERT(DECIMAL(30,15),146804871.212533)/CONVERT(DECIMAL (38,15),12499999.9999)

Vous pouvez faire le même calcul si vous suivez cette règle . aussi, si vous traitez chaque paire de nombres comme

  • 146804871.212533000000000 et 12499999.999900000
  • 146804871.212533000000000 et 12499999.999900000000000

Autres conseils

En bref, utilisez DECIMAL (25,13) et tout ira bien pour tous les calculs - vous obtiendrez la précision exacte telle que déclarée: 12 chiffres avant le point décimal et 13 chiffres décimaux après. La règle est: p + s doit être égal à 38 et vous serez en sécurité! Pourquoi est-ce? En raison de la très mauvaise implémentation de l'arithmétique dans SQL Server! En attendant de résoudre le problème, suivez cette règle.

J'ai remarqué que si vous convertissez la valeur de division en float, vous obtenez la réponse correcte, c'est-à-dire:

.
select 49/30                   (result = 1)

deviendrait:

select 49/cast(30 as float)    (result = 1.63333333333333)

Nous étions perplexes devant la transition magique,

  

P & amp; S sont liés, donc:

     
      
  1. (72,54) - > (38,29)

  2.   
  3. (84,54) - > (38,8)

  4.   

En supposant que (38,29) est une faute de frappe et devrait être (38,20) , voici le calcul:

  1. i. 72 - 38 = 34, ii. 54 - 34 = 20

  2. i. 84 - 58 = 46, ii. 54 - 46 = 8

Et voici le raisonnement:

i. La précision de sortie, moins la précision maximale, correspond aux chiffres que nous allons jeter.

ii. Ensuite, l’échelle de sortie moins ce que nous allons jeter nous donne ... les derniers chiffres de l’échelle de sortie.

J'espère que cela aidera tout le monde à essayer de comprendre.

Convertissez l'expression et non les arguments.

select  CONVERT(DECIMAL(38,36),146804871.212533 / 12499999.9999)

L'utilisation de ce qui suit peut vous aider:

SELECT COL1 * 1.0 / COL2
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top