2016-05-23 4 views
1

Я использую файл XSLT для округления определенных значений в XML. Таким образом, эти значения должны округляться с точностью до десятичного значения 18 (до 18-го десятичного значения). Я попытался сделать это с Altova XMLSpy и Visual Studio. В обоих случаях значения были обрезаны после определенного количества цифр. Ниже мой код:Десятичная точность в xslt

XML

<DateReceived>20160509</DateReceived> 
<CurrentCommitment>0</CurrentCommitment> 
<InvestedCapital>1510650</InvestedCapital> 
<InsideExpenses>1.4556888888888888888495783095462397857346874356023496</InsideExpenses> 
<IEMF>2345.76454</IEMF> 

XSLT

<xsl:template match="ROW/InsideExpenses"> 
    <InsideExpenses> 
     <xsl:value-of select="format-number(round(1000000000000000000 * text()) div 1000000000000000000, '#.##################')"/> 
    </InsideExpenses> 

В случае Altova XML Spy значение в тег InsideExpenses был +1,4556888888888888 и в случае Visual Studio это было +1,45568888888889 (1 меньше десятичное пространство и 9 в конце). Было бы очень полезно узнать, почему это происходит, и как я могу округлить число до 18-го знака после запятой.

ответ

1

Прежде всего вам нужно четко рассказать о различиях между XSLT 2.0 и 1.0 здесь. XSLT 2.0 (который реализован в Altova, но это не значит, что вы его используете) поддерживает как xs: double, так и xs: десятичные числовые типы данных. XSLT 1.0 поддерживает только плавающие точки с двойной точностью (xs: double).

С плавающей точкой арифметика всегда будет производить ошибки округления, если результат не будет представлен точно в десятичном значении или будет содержать более 15 цифр точности. С xs: decimal реализация может поддерживать бесконечную точность, и в этом случае десятичные результаты будут точными или могут поддерживать фиксированную точность и, следовательно, округлять.

Так что, если вы хотите 18 цифр точности для числовых операций, вам действительно нужно использовать XSLT 2.0 и xs: десятичный тип данных.

+0

Спасибо! Я сделал именно то, что вы предлагали, и работал в Altova. Однако .NET не имеет встроенного процессора XSLT 2.0. Поэтому мне пришлось бы использовать сторонний процессор, такой как Saxon/XQSharp, или каким-то образом заставить его работать в XSLT 1.0. –

+1

Поскольку Microsoft прекратила делать дальнейшие разработки на своем процессоре XSLT около 15 лет назад, а поскольку на .NET есть как минимум три XSLT-процессора, которые уже давно настигли предложение Microsoft и находятся в активной разработке, а поскольку XSLT 2.0 дает вам хотя бы двойной производительность XSLT 1.0, вам действительно нужно подумать о продвижении вперед. –