7

次の IronPython スクリプトがあるとします。

def Calculate(input):
    return input * 1.21

10 進数で C# から呼び出されると、この関数は 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); 

私には2つのオプションがあるようです:

まず、C# 側でキャストすることができました。精度が失われる可能性があるため、うまくいかないようです。

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

2 番目のオプションは、Python スクリプトで System.Decimal を使用することです。動作しますが、スクリプトが多少汚染されます...

from System import *

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

C#で「1.21m」表記を使用するのと同じように、数値1.21を10進数として解釈する必要がある省略表記DLRはありますか?または、double の代わりに使用する 10 進数を強制する他の方法はありますか?

4

2 に答える 2

6

python docsを見てください:

Decimal インスタンスは、整数、文字列、またはタプルから構築できます。float から Decimal を作成するには、最初にそれを文字列に変換します。これは、変換の詳細 (表現エラーを含む) を明示的に思い出させるものとして機能します。

残念ながら、お探しの略記はありません。pythonでさえ何もありません。小数を「ハードコーディング」する標準的な方法は、文字列表現を小数コンストラクターに渡すことです。

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

.net 相互運用機能の受け渡しに重点を置いたコードを作成している場合 (そうであるように思われます)、自分で提案したように、.net Decimal データ型をすぐに使用する方がよい場合があります。ただし、この例では浮動小数点数を 10 進数コンストラクターに渡すことに注意してください。数値の小数点以下の桁数がはるかに多い場合、変換の精度にわずかな誤差が生じる可能性があります。

from System import *
my_decimal = Decimal(1.21)

したがって、このコンストラクターのオーバーロードを使用する方がよい場合があります。

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

あなたが望むことを行うための最も美しく最短の方法ではありませんが、パフォーマンスと精度の点で最高です。

于 2010-04-09T09:04:11.977 に答える
3

精度を失う可能性があるため、うまくいかないようです。

ええ、他の方法でもそれを行います:

Decimal(1.21)

1.21それが浮動小数点数であると記述したら、それを Decimal コンストラクターに渡す前に、すでに完全な精度を失っています。そのため、Python のネイティブDecimalクラスは float ではなく文字列から初期化する必要があります。

decimal.Decimal('1.21')

.NET の Decimal に似たようなコンストラクターはないようですが、おそらく構成要素コンストラクターを使用してそれを行うことができます。

System.Decimal(121, 0, 0, False, 2)
于 2010-04-09T09:04:25.733 に答える