@@ -3062,8 +3062,8 @@ compare($N * $arg2, 0) eq compare($arg1, 0).</eg>
3062
3062
<p>The <code>$value</code> argument may be of any numeric data type
3063
3063
(<code>xs:double</code>, <code>xs:float</code>, <code>xs:decimal</code>, or their
3064
3064
subtypes including <code>xs:integer</code>). Note that if an <code>xs:decimal</code> is
3065
- supplied, it is not automatically promoted to an <code>xs:double</code>, as such
3066
- promotion can involve a loss of precision.</p>
3065
+ supplied, it is not automatically converted to an <code>xs:double</code>, as such
3066
+ conversion can involve a loss of precision.</p>
3067
3067
<p>If the supplied value of the <code>$value</code> argument is an empty sequence, the
3068
3068
function behaves as if the supplied value were the <code>xs:double</code> value
3069
3069
<code>NaN</code>.</p>
@@ -3928,8 +3928,8 @@ translate(value := '٢٠٢٣', replace := '٠١٢٣٤٥٦٧٨٩', with := '01234
3928
3928
ref="ieee754-2019"
3929
3929
/> specification of the <code>pown</code> function applied to a
3930
3930
64-bit binary floating point value and an integer.</p>
3931
- <p>Otherwise <code>$y</code> is converted to an <code>xs:double</code> by numeric
3932
- promotion, and the result is <code>$x</code> raised to the power of
3931
+ <p>Otherwise <code>$y</code> is cast to an <code>xs:double</code>,
3932
+ and the result is <code>$x</code> raised to the power of
3933
3933
<code>$y</code> as defined in the <bibref
3934
3934
ref="ieee754-2019"
3935
3935
/> specification of the
@@ -8373,7 +8373,7 @@ xs:dayTimeDuration($arg2) div xs:dayTimeDuration('PT1S')
8373
8373
<p>The result of <code>seconds($n)</code> is approximately equal to the result of
8374
8374
the expression <code>xs:dayTimeDuration('PT1S') * $n</code>. The equivalence is only
8375
8375
approximate, because <code>seconds($n)</code> uses the exact <code>xs:decimal</code>
8376
- value supplied, whereas multiplying a duration by a number first promotes the number
8376
+ value supplied, whereas multiplying a duration by a number first converts the number
8377
8377
to an <code>xs:double</code> value, which may lose precision.</p>
8378
8378
</fos:notes>
8379
8379
<fos:examples>
@@ -14428,29 +14428,9 @@ return exists($break)
14428
14428
</ulist>
14429
14429
14430
14430
14431
- <p diff="del" at="A"
14432
- >If the input sequence contains values of different numeric types that differ from each
14433
- other by small amounts, then the eq operator is not transitive, because of rounding
14434
- effects occurring during type promotion. In the situation where the input contains three
14435
- values <code>A</code>, <code>B</code>, and <code>C</code> such that <code>A eq B</code>,
14436
- <code>B eq C</code>, but <code>A ne C</code>, then the number of items in the result
14437
- of the function (as well as the choice of which items are returned) is <termref
14438
- def="implementation-dependent"
14439
- >implementation-dependent</termref>, subject only to the constraints that (a) no two
14440
- items in the result sequence compare equal to each other, and (b) every input item that
14441
- does not appear in the result sequence compares equal to some item that does appear in
14442
- the result sequence.</p>
14443
-
14444
- <p diff="del" at="A">For example, this arises when computing:</p>
14445
-
14446
- <eg diff="del" at="A"><![CDATA[ distinct-values(
14447
- (xs:float('1.0'),
14448
- xs:decimal('1.0000000000100000000001',
14449
- xs:double('1.00000000001'))]]></eg>
14431
+
14450
14432
14451
- <p diff="del" at="A"
14452
- >because the values of type <code>xs:float</code> and <code>xs:double</code> both compare
14453
- equal to the value of type <code>xs:decimal</code> but not equal to each other. </p>
14433
+
14454
14434
</fos:rules>
14455
14435
<fos:notes>
14456
14436
<p>If <code>$values</code> is the empty sequence, the function returns the empty sequence.</p>
@@ -17152,26 +17132,21 @@ declare function equal-strings(
17152
17132
</fos:summary>
17153
17133
<fos:rules>
17154
17134
<p>If <code>$values</code> is the empty sequence, the empty sequence is returned.</p>
17155
- <p>If <code>$values</code> contains values of type <code>xs:untypedAtomic</code> they are cast
17156
- to <code>xs:double</code>. </p>
17157
- <p>Duration values must either all be <code>xs:yearMonthDuration</code> values or must all
17158
- be <code>xs:dayTimeDuration</code> values. For numeric values, the numeric promotion
17159
- rules defined in <specref
17160
- ref="op.numeric"
17161
- /> are used to promote all values to a single
17162
- common type. After these operations, <code>$values</code> must satisfy the following condition:</p>
17163
- <p>There must be a type <var>T</var> such that:</p>
17135
+ <p>Any item in <code>$values</code> that is an instance of <code>xs:untypedAtomic</code>
17136
+ is cast to <code>xs:double</code>. </p>
17137
+ <p>After this conversion, one of the following conditions must be true:</p>
17164
17138
<olist>
17165
- <item><p>every item in <code>$values</code> is an instance of <var>T</var>.</p></item>
17166
- <item><p><var>T</var> is one of <code>xs:double</code>, <code>xs:float</code>,
17167
- <code>xs:decimal</code>, <code>xs:yearMonthDuration</code>, or
17168
- <code>xs:dayTimeDuration</code>.</p></item>
17139
+ <item><p>Every item in <code>$values</code> is an instance of <code>xs:yearMonthDuration</code>.</p></item>
17140
+ <item><p>Every item in <code>$values</code> is an instance of <code>xs:dayTimeDuration</code>.</p></item>
17141
+ <item><p>Every item in <code>$values</code> is an instance of <code>xs:numeric</code>.</p></item>
17169
17142
</olist>
17170
-
17143
+
17171
17144
17172
17145
<p>The function returns the average of the values as <code>sum($values) div
17173
17146
count($values)</code>; but the implementation may use an otherwise equivalent algorithm
17174
- that avoids arithmetic overflow.</p>
17147
+ that avoids arithmetic overflow. Note that the <function>fn:sum</function> function
17148
+ allows the input sequence to be reordered, which may affect the result in edge cases
17149
+ when the sequence contains a mixture of different numeric types.</p>
17175
17150
17176
17151
</fos:rules>
17177
17152
<fos:errors>
@@ -17219,6 +17194,16 @@ declare function equal-strings(
17219
17194
code="0006"/>. </p>
17220
17195
</fos:example>
17221
17196
</fos:examples>
17197
+ <fos:changes>
17198
+ <fos:change issue="1682" date="2025-01-27">
17199
+ <p>In 3.1, given a mixed input sequence such as (1, 3, 4.2e0), the specification
17200
+ was unclear whether it was permitted to add the first two integer items using
17201
+ integer arithmetic, rather than converting all items to doubles before
17202
+ performing any arithmetic. The 4.0 specification is clear that this is
17203
+ permitted; but since the items can be reordered before being added, this
17204
+ is not required.</p>
17205
+ </fos:change>
17206
+ </fos:changes>
17222
17207
</fos:function>
17223
17208
17224
17209
<fos:function name="max" prefix="fn">
@@ -17558,34 +17543,36 @@ declare function equal-strings(
17558
17543
<p>Returns a value obtained by adding together the values in <code>$values</code>.</p>
17559
17544
</fos:summary>
17560
17545
<fos:rules>
17561
- <p>Any values of type <code>xs:untypedAtomic</code> in <code>$values</code> are cast to
17546
+ <p>The result of the function when a single argument
17547
+ is supplied is the result of the expression: <code>fn:sum($arg, 0)</code>.</p>
17548
+ <p>Any value of type <code>xs:untypedAtomic</code> in <code>$values</code> is cast to
17562
17549
<code>xs:double</code>. The items in the resulting sequence may be reordered in an
17563
17550
arbitrary order. The resulting sequence is referred to below as the converted
17564
17551
sequence.</p>
17565
- <p diff="chg" at="2023-01-17" >If the converted sequence is empty, then the function returns
17552
+ <p>If the converted sequence is empty, then the function returns
17566
17553
the value of the argument <code>$zero</code>, which defaults to
17567
17554
the <code>xs:integer</code> value <code>0</code>.</p>
17568
- <p>If the converted sequence contains the value <code>NaN</code>, <code>NaN</code> is
17569
- returned.</p>
17570
- <p>All items in <code>$values</code> must be numeric or derived from a single base type. In
17571
- addition, the type must support addition. Duration values must either all be
17572
- <code>xs:yearMonthDuration</code> values or must all be
17573
- <code>xs:dayTimeDuration</code> values. For numeric values, the numeric promotion
17574
- rules defined in <specref
17575
- ref="op.numeric"
17576
- /> are used to promote all values to a single
17577
- common type. The sum of a sequence of integers will therefore be an integer, while the
17578
- sum of a numeric sequence that includes at least one <code>xs:double</code> will be an
17579
- <code>xs:double</code>. </p>
17580
- <p>The result of the function is the value of the
17555
+ <p>In other cases the items in the converted sequence are added pairwise according
17556
+ the rules of the <code>+</code> operator.</p>
17557
+
17558
+ <p>Specifically, the result of the function is the value of the
17581
17559
expression:</p>
17582
17560
<eg xml:space="preserve">
17583
17561
if (empty($c)) then $zero
17584
17562
else if (count($c) eq 1) then $c
17585
17563
else head($c) + sum(tail($c))</eg>
17586
17564
<p>where <code>$c</code> is the converted sequence.</p>
17587
- <p>The result of the function <phrase diff="chg" at="2023-01-17">when a single argument is supplied</phrase> is the result of the expression:
17588
- <code>fn:sum($arg, 0)</code>.</p>
17565
+
17566
+ <p>This has the effect that a type error will occur unless one of the following
17567
+ conditions is satisfied:</p>
17568
+
17569
+ <olist>
17570
+ <item><p>Every item in <code>$values</code> is an instance of <code>xs:yearMonthDuration</code>.</p></item>
17571
+ <item><p>Every item in <code>$values</code> is an instance of <code>xs:dayTimeDuration</code>.</p></item>
17572
+ <item><p>Every item in <code>$values</code> is an instance of <code>xs:numeric</code>.</p></item>
17573
+ </olist>
17574
+
17575
+
17589
17576
17590
17577
</fos:rules>
17591
17578
<fos:errors>
@@ -17604,7 +17591,20 @@ else head($c) + sum(tail($c))</eg>
17604
17591
the <code>$zero</code> argument is used only when the input sequence is empty, not
17605
17592
when a non-empty sequence sums to zero. For example, <code>sum((-1, +1), xs:double('NaN'))</code>
17606
17593
returns the <code>xs:integer</code> value <code>0</code>, not <code>NaN</code>.</p>
17607
- <p> If the converted sequence contains exactly one value then that value is returned.</p>
17594
+ <p>The sum of a sequence of integers will be an integer, while the
17595
+ sum of a numeric sequence that includes at least one <code>xs:double</code> will be an
17596
+ <code>xs:double</code>.</p>
17597
+ <p>If the converted sequence contains exactly one value then that value is returned.</p>
17598
+ <p>If the converted sequence contains the value <code>NaN</code>, <code>NaN</code> is
17599
+ returned.</p>
17600
+ <p>In edge cases the fact that the input sequence may be reordered makes the result
17601
+ slightly unpredictable. For example, if the input contains two <code>xs:decimal</code>
17602
+ values and an <code>xs:float</code>, then the decimal values might be added using
17603
+ decimal arithmetic, or they might both be converted to <code>xs:float</code>
17604
+ (potentially losing precision) before any arithmetic is performed.
17605
+ </p>
17606
+
17607
+
17608
17608
</fos:notes>
17609
17609
<fos:examples>
17610
17610
<fos:variable name="d1" id="v-sum-d1" select="xs:yearMonthDuration("P20Y")"/>
@@ -17678,6 +17678,16 @@ else head($c) + sum(tail($c))</eg>
17678
17678
/>. </p>
17679
17679
</fos:example>
17680
17680
</fos:examples>
17681
+ <fos:changes>
17682
+ <fos:change issue="1682" date="2025-01-27">
17683
+ <p>In 3.1, given a mixed input sequence such as (1, 3, 4.2e0), the specification
17684
+ was unclear whether it was permitted to add the first two integer items using
17685
+ integer arithmetic, rather than converting all items to doubles before
17686
+ performing any arithmetic. The 4.0 specification is clear that this is
17687
+ permitted; but since the items can be reordered before being added, this
17688
+ is not required.</p>
17689
+ </fos:change>
17690
+ </fos:changes>
17681
17691
</fos:function>
17682
17692
<!--<fos:function name="to" prefix="op">
17683
17693
<fos:signatures>
@@ -18249,7 +18259,7 @@ return tokenize(normalize-space($s), ' ')[. castable as xs:IDREF]</eg>
18249
18259
<p>If <code>$source</code> is the empty sequence, the result is an empty sequence.</p>
18250
18260
<p>If <code>$source</code> is a relative URI reference, it is resolved relative to the value
18251
18261
of the <term>static base URI</term> property from the static context. The resulting absolute URI is
18252
- promoted to an <code>xs:string</code>.</p>
18262
+ cast to an <code>xs:string</code>.</p>
18253
18263
<p>If the <term>available documents</term> described in <xspecref spec="XP31"
18254
18264
ref="eval_context"
18255
18265
/> provides a mapping from this string to a document node, the
0 commit comments