2017-05-05 6 views
0

J'ai traduit le code IDL en Python et j'ai remarqué des différences dans les produits finaux. Les différences ne sont pas non plus négligeables (par exemple, via IDL, j'obtiens 19,03 tandis que Python donne 19,16). J'ai confirmé que les deux scripts produisaient les mêmes valeurs (ils diffèrent généralement dans la quatrième, cinquième ou sixième décimale) jusqu'au point où je commence à faire plusieurs opérations de tableau. Je soupçonne que la précision peut être la cause (les deux tableaux Python et IDL sont type=FLOAT). J'ai fait une expérience simple et je vois des différences significatives ici aussi.IDL vs Python Float

IDL

a = 0.01 
b = 0.0 

for r = 1,1000 do begin 
    b += a 
endfor 
c = a * 1000 

print,b 
    >>> 10.0001 
print,c 
    >>> 10.0000 

Python

a = 0.01 
b = 0.00 

for r in range(1000): 
    b += a 
c = a * 1000 

print(b) 
    >>> 9.999999999999831 
print(c) 
    >>> 10.0 

Certes, la différence est encore faible dans cet exemple, mais Python est clairement beaucoup plus proche de la vérité que ce qui est IDL. Je m'attendais à ce que les résultats soient identiques puisque les deux langues utilisent la précision FLOAT. L'essentiel est que les erreurs se propagent dans les deux langues de différentes manières, ce qui donne des résultats différents. Mes questions sont les suivantes:

  1. est-il une différence de précision entre les deux langues (à savoir ne je pense qu'il ne FLOAT signifie la même chose en IDL comme il le fait en Python,)?

  2. est-il un moyen de concilier les différences de précision?

  3. Je n'ai pas beaucoup d'expérience avec IDL; Ai-je manqué quelque chose d'évident?

PS:

Comme j'écrivais poste this sauté vers le haut. Je vois le même problème que ce OP (Python est correct).

IDL

>>> 3015/0.0002529821940697729 
>>> 11917835. 

python

>>> 3015/0.0002529821940697729 
>>> 11917834.814763514 
+0

'FLOAT' n'est pas une précision ... Aussi, vous n'utilisez pas' numpy' ici du tout ... –

+0

Assez juste juanpa. Je suppose que j'ai Numpy dans l'esprit ces jours-ci. Question maintenant corrigée. – tnknepp

Répondre

6

FLOAT en IDL est simple précision (32 bits), et DOUBLE est double précision (64 bits).

En python (et numpy), le type de virgule flottante par défaut est double précision (64 bits).

Vous pouvez recréer le calcul IDL simple précision en utilisant numpy comme suit:

In [9]: import numpy as np 

In [10]: a = np.array(0.01, dtype=np.float32) 

In [11]: b = np.array(0.0, dtype=np.float32) 

In [12]: for r in range(1000): 
    ...:  b += a 
    ...:  

In [13]: c = a*1000 

In [14]: print(b) 
10.000133514404297 

In [15]: print(c) 
9.99999977648 

Vous pouvez utiliser l'argument FORMAT de la déclaration d'impression IDL pour imprimer plus de chiffres de a et b, et de les comparer aux valeurs montré ci-dessus.

+0

C'est très utile. J'ai toujours supposé que "FLOAT" signifiait la même chose à travers les langues. Il est bon de savoir que ce n'est pas le cas. – tnknepp

+0

@tnkneep n'est pas seulement cohérent dans les langues, mais les primitives ne sont même pas cohérentes sur * plates-formes * dans la même langue.Double peut même ne pas être 64bits ou avoir une plus grande précision dans le calcul selon votre matériel (certains processeurs Intel ont par exemple des unités à virgule flottante 80bit qui effectuent des calculs à virgule flottante même si elles sont stockées en 64bits en interne) – snb