* XPath: number-to-string conversion is now compliant to the specs (no scientific notation, decimal separator is a hardcoded period, correct output values for INF/NAN) + tests.

git-svn-id: trunk@13389 -
This commit is contained in:
sergei 2009-07-15 09:56:48 +00:00
parent 14107b42b2
commit a9d9841eee
2 changed files with 87 additions and 4 deletions

View File

@ -1486,9 +1486,78 @@ begin
end;
function TXPathNumberVariable.AsText: DOMString;
var
frec: TFloatRec;
i, nd, reqlen: Integer;
P: DOMPChar;
begin
// TODO: Decimal separator!!!
Result := FloatToStr(FValue);
FloatToDecimal(frec, FValue, fvExtended, 17, 9999);
// TODO: remove workaround after #14143 is fixed
if {frec.Exponent = -32768} frec.Digits[0] = 'N' then
begin
Result := 'NaN'; // do not localize
Exit;
end
else if {frec.Exponent = 32767} (frec.Digits[0] = 'I') or ((frec.Digits[0] = '+') and (frec.Digits[1] = 'I')) then
begin
if frec.Negative then
Result := '-Infinity' // do not localize
else
Result := 'Infinity'; // do not localize
Exit;
end
else if frec.Digits[0] = #0 then
begin
Result := '0';
Exit;
end
else
begin
nd := StrLen(@frec.Digits[0]);
reqlen := nd + ord(frec.Negative); // maybe minus sign
if frec.Exponent > nd then
Inc(reqlen, frec.Exponent - nd) // add this much zeroes at the right
else if frec.Exponent < nd then
begin
Inc(reqlen); // decimal point
if frec.Exponent <= 0 then
Inc(reqlen, 1 - frec.Exponent); // zeroes at the left + one more for the int part
end;
SetLength(Result, reqlen);
P := DOMPChar(Result);
if frec.Negative then
begin
P^ := '-';
Inc(P);
end;
if frec.Exponent <= 0 then // value less than 1, put zeroes at left
begin
for i := 0 to 1-frec.Exponent do
P[i] := '0';
P[1] := '.';
for i := 0 to nd-1 do
P[i+2-frec.Exponent] := WideChar(ord(frec.Digits[i]));
end
else if frec.Exponent > nd then // large integer, put zeroes at right
begin
for i := 0 to nd-1 do
P[i] := WideChar(ord(frec.Digits[i]));
for i := nd to reqlen-1-ord(frec.Negative) do
P[i] := '0';
end
else // 0 < exponent <= digits, insert decimal point into middle
begin
for i := 0 to frec.Exponent-1 do
P[i] := WideChar(ord(frec.Digits[i]));
if frec.Exponent < nd then
begin
P[frec.Exponent] := '.';
for i := frec.Exponent to nd-1 do
P[i+1] := WideChar(ord(frec.Digits[i]));
end;
end;
end;
end;

View File

@ -542,7 +542,8 @@ const
'<b ns1:attrib2="test"/>'#10+
'</doc>';
StringTests: array[0..75] of TTestRec = ( // numbers refer to xalan/string/stringXX
StringTests: array[0..84] of TTestRec = ( // numbers refer to xalan/string/stringXX
(expr: 'string(0)'; rt: rtString; s: '0'),
(expr: 'string(5)'; rt: rtString; s: '5'), // #38/39
(expr: 'string(0.5)'; rt: rtString; s: '0.5'),
(expr: 'string(-0.5)'; rt: rtString; s: '-0.5'),
@ -634,7 +635,20 @@ const
(data: str30; expr: 'local-name(baz2:b)'; rt: rtString; s: 'b'), // namespace07
(data: str30; expr: 'local-name(baz2:b/@baz1:attrib2)'; rt: rtString; s: 'attrib2'), // namespace09
(data: str30; expr: 'local-name()'; rt: rtString; s: 'doc') // namespace26
(data: str30; expr: 'local-name()'; rt: rtString; s: 'doc'), // namespace26
// tests for number->string conversions at boundary conditions
(expr: 'string(123456789012345678)'; rt: rtString; s: '123456789012345680'), // #132.1
(expr: 'string(-123456789012345678)'; rt: rtString; s: '-123456789012345680'), // #132.2
(expr: 'string(.10123456789234567893)'; rt: rtString; s: '0.10123456789234568'), // #133.1
(expr: 'string(-.10123456789234567893)'; rt: rtString; s: '-0.10123456789234568'), // #133.2
(expr: 'string(9.87654321012345)'; rt: rtString; s: '9.87654321012345'), // #134.1
(expr: 'string(98765432101234.5)'; rt: rtString; s: '98765432101234.5'), // #134.2
(expr: 'string(.0000000000000000000000000000000000000000123456789)'; rt: rtString; // #135.1
s: '0.0000000000000000000000000000000000000000123456789'),
(expr: 'string(-.0000000000000000000000000000000000000000123456789)'; rt: rtString; // #135.2
s: '-0.0000000000000000000000000000000000000000123456789')
);
ax114='<doc>'+