2010-04-09 6 views
5

suppose que j'ai le script IronPython suivant:Existe-t-il une notation littérale décimale dans IronPython?

def Calculate(input): 
    return input * 1.21 

Appelée de C# avec une décimale, cette fonction retourne un double:

var python = Python.CreateRuntime(); 
dynamic engine = python.UseFile("mypythonscript.py") 

decimal input = 100m; // input is of type Decimal 
// next line throws RuntimeBinderException: 
//  "cannot implicitly convert double to decimal" 
decimal result = engine.Calculate(input); 

Il me semble avoir deux options:

First , Je pourrais lancer au côté C#: ça me semble un non-aller car je pourrais perdre la précision.

decimal result = (decimal)engine.Calculate(input); 

Deuxième option est d'utiliser System.Decimal dans le script python: travaux, mais le script pollue un peu ...

from System import * 

def CalculateVAT(amount): 
    return amount * Decimal(1.21) 

Y at-il une notation sténographique DLR que le nombre devrait 1.21 être interprété comme une décimale, un peu comme si j'utilisais la notation '1.21m' en C#? Ou y a-t-il un autre moyen de forcer la décimale à être utilisée au lieu du double?

Répondre

4

Regardez le python docs:

instances décimales peuvent être construites à partir entiers, des chaînes ou tuples. Pour créer un nombre décimal à partir d'un flottant , convertissez-le d'abord en chaîne. Cela sert de rappel explicite de les détails de la conversion (y compris erreur de représentation).

Malheureusement, il n'y a pas de notation courte que vous recherchez. Même Python n'en a pas. La méthode standard de « codage dur » d'un nombre décimal est de passer une représentation de chaîne au constructeur décimal:

from decimal import Decimal 
my_decimal = Decimal("1.21") 

Si vous écrivez du code qui est lourd sur .net Interop en passant (il semble que vous êtes), il peut-être préférable d'utiliser le type de données .net Decimal tout de suite, comme vous l'avez vous-même proposé. Sachez toutefois que vous transmettez un nombre à virgule flottante au constructeur décimal dans cet exemple. Vous pouvez obtenir une petite erreur dans la précision de la conversion, si le nombre a beaucoup plus décimales:

from System import * 
my_decimal = Decimal(1.21) 

Ainsi, vous pouvez être mieux d'utiliser cette surcharge constructeur:

from System import * 
my_decimal = Decimal(121, 0, 0, False, 2) 

Pas la plus belle et le moyen le plus court de faire ce que vous voulez, mais le meilleur en termes de performance et de précision.

+0

Merci. Je vais m'en tenir à la notation décimale (1.21). Dans ce cas, je peux vivre avec le constructeur à partir d'un point flottant, car il n'y aura pas de perte de précision dans mon cas. J'étais plus préoccupé par le résultat du calcul. – jeroenh

3

ressemble à un non-go que je pourrais perdre la précision.

Oui, vous le faites dans l'autre méthode aussi:

Decimal(1.21) 

Une fois que vous avez écrit 1.21 qui est un nombre à virgule flottante et que vous avez déjà perdu toute précision avant même de passer à la Constructeur décimal.Voilà pourquoi la classe native Python Decimal doit être initialisés à partir d'une chaîne, pas un flotteur:

decimal.Decimal('1.21') 

Il ne semble pas être un constructeur similaire pour décimal de .NET, mais vous pourriez peut-être faire en utilisant la constituent parts constructor:

System.Decimal(121, 0, 0, False, 2) 
Questions connexes