Есть ли буквальный обозначение для десятичного в Ironpython?

StackOverflow https://stackoverflow.com/questions/2605898

Вопрос

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

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

from System import *

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

Существует ли короткая нотация DLR, что номер 1.21 следует интерпретировать как десятичное, так много, как я бы использовал нотацию «1,21M» в C #? Или есть ли другой способ обеспечить применение десятичных для использования вместо двойного?

Это было полезно?

Решение

Посмотрите Python Docs.:

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

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

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

Если вы пишете код, который тяжелый на .NET Interop Passing (похоже, что вы есть), может быть лучше, просто используя десятичный тип DataType .NET .NET, как вы предложили себе. Однако осознайте, что вы проходите номер с плавающей запятой в десятичный конструктор в этом примере. Вы можете получить небольшую ошибку в точности от преобразования, если номер имеет гораздо более десятичные места:

from System import *
my_decimal = Decimal(1.21)

Таким образом, вы можете быть лучше, используя этот конструктор перегрузки:

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

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

Другие советы

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

Да, вы делаете это в другом методе тоже:

Decimal(1.21)

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

decimal.Decimal('1.21')

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

System.Decimal(121, 0, 0, False, 2)
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top