7

假设我有以下 IronPython 脚本:

def Calculate(input):
    return input * 1.21

当使用小数从 C# 调用时,此函数返回双精度:

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); 

我似乎有两个选择:

首先,我可以在 C# 方面进行转换:似乎不行,因为我可能会失去精度。

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

第二种选择是在 python 脚本中使用 System.Decimal:有效,但有点污染脚本......

from System import *

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

是否有一个简写符号 DLR,数字 1.21 应该被解释为十进制,就像我在 C# 中使用“1.21m”符号一样?或者有没有其他方法可以强制使用十进制而不是双精度?

4

2 回答 2

6

查看python 文档

可以从整数、字符串或元组构造十进制实例。要从浮点数创建小数,首先将其转换为字符串。这可以明确提醒转换的细节(包括表示错误)。

不幸的是,没有您正在寻找的简写符号。甚至 python 也没有。“硬编码”小数的标准方法是将字符串表示形式传递给小数构造函数:

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

如果您正在编写大量依赖 .net 互操作传递的代码(看起来您是这样),最好立即使用 .net Decimal 数据类型,就像您自己提出的那样。但是请注意,在此示例中,您将浮点数传递给十进制构造函数。如果数字有更多的小数位,您可能会从转换中得到一个小的准确性错误:

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类必须从字符串而不是浮点数初始化的原因:

decimal.Decimal('1.21')

.NET 的 Decimal 似乎没有类似的构造函数,但您也许可以使用组成部分构造函数来做到这一点:

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