IronPython中是否有小数字的表示法?

时间:2010-04-09 08:08:00

标签: c# types .net-4.0 ironpython literals

假设我有以下IronPython脚本:

def Calculate(input):
    return input * 1.21

当使用小数从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); 

我似乎有两种选择:

首先,我可以在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'符号一样?或者有没有其他方法来强制使用十进制而不是double?

2 个答案:

答案 0 :(得分:5)

查看python docs

  

十进制实例可以用整数,字符串或者构造   元组。从a创建一个Decimal   float,首先将其转换为字符串。   这可以作为一个明确的提醒   转换的细节   (包括表示错误)。

不幸的是,你找不到简写符号。即使是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)

不是做你想要的最美丽和最短的方式,但在性能和准确性方面是最好的。

答案 1 :(得分:3)

  

似乎是一种禁忌,因为我可能会失去精确度。

是的,你也可以用另一种方法做到这一点:

Decimal(1.21)

一旦你写了1.21这是一个浮点数,你甚至在将它传递给Decimal构造函数之前就已经失去了完整的精度。这就是为什么Python的本地Decimal类必须从字符串初始化,而不是浮点数:

decimal.Decimal('1.21')

.NET的Decimal似乎没有类似的构造函数,但您也许可以使用constituent parts constructor来完成:

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