Есть ли буквальная запись десятичной дроби в IronPython? - PullRequest
6 голосов
/ 09 апреля 2010

предположим, у меня есть следующий скрипт 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); 

Второй вариант - использовать System.Decimal в скрипте python: работает, но несколько загрязняет скрипт ...

from System import *

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

Существует ли сокращенная запись DLR, что число 1.21 следует интерпретировать как десятичное число, так же, как я бы использовал запись '1.21m' в C #? Или есть какой-то другой способ применения десятичного числа вместо двойного?

Ответы [ 2 ]

5 голосов
/ 09 апреля 2010

Посмотрите на документы по питону :

Десятичные экземпляры могут быть построены из целых чисел, строк или кортежи. Чтобы создать десятичную из float, сначала преобразуйте его в строку. Это служит явным напоминанием о детали преобразования (включая ошибку представления).

К сожалению, нет коротких обозначений, которые вы ищете. Даже у питона нет ни одного. Стандартный способ «жесткого кодирования» десятичного числа - передать строковое представление конструктору десятичного числа:

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)

Не самый красивый и самый короткий способ делать то, что вы хотите, но лучший с точки зрения производительности и точности.

3 голосов
/ 09 апреля 2010

кажется запретным, так как я могу потерять точность.

Да, вы делаете это и другим способом:

Decimal(1.21)

Как только вы написали 1.21, это число с плавающей запятой, и вы уже потеряли полную точность, даже не передав его в конструктор Decimal. Вот почему собственный класс Decimal Python должен быть инициализирован из строки, а не с плавающей запятой:

decimal.Decimal('1.21')

Похоже, что нет аналогичного конструктора для десятичного .NET, но вы, возможно, могли бы сделать это, используя конструктор составных частей :

System.Decimal(121, 0, 0, False, 2)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...