[Patch available] FPJSON writes strange float output
Summary
The fpjson library always writes float values in scientific notation, e.g. 0.5 is written as 5.0000000000000000E-001. This is less readable for a human user and takes more space if saved to a file.
System Information
- Operating system: Arch Linux (Should be OS independent)
- Processor architecture: x86-64 (Should be architecture independent)
- Compiler version: FPC 3.3.1 x86_64-linux-gtk2
- Device: Computer
Steps to reproduce
program test;
uses fpjson;
begin
with TJSONObject.Create(['value', 0.5]) do
begin
WriteLn(AsJSON);
WriteLn(FormatJSON);
Free;
end;
end.
What is the current bug behavior?
{ "value" : 5.0000000000000000E-001 }
{
"value" : 5.0000000000000000E-001
}
What is the expected (correct) behavior?
{ "value" : 0.5 }
{
"value" : 0.5
}
Possible fixes
See attached patch file. The proposed fix uses the FloatToStr() function instead of the Str() function. The FloatToStr() function automatically uses the most compact output (either decimal notation or scientific notation).
2141a2142,2163
> const
> // ensure thousandseparator and decimalseparator comply with JSON specification
> JSONFormatSettings: TFormatSettings = (
> CurrencyFormat: 1;
> NegCurrFormat: 5;
> ThousandSeparator: ',';
> DecimalSeparator: '.';
> CurrencyDecimals: 2;
> DateSeparator: '-';
> TimeSeparator: ':';
> ListSeparator: ',';
> CurrencyString: '$';
> ShortDateFormat: 'd/m/y';
> LongDateFormat: 'dd" "mmmm" "yyyy';
> TimeAMString: 'AM';
> TimePMString: 'PM';
> ShortTimeFormat: 'hh:nn';
> LongTimeFormat: 'hh:nn:ss';
> ShortMonthNames: ('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec');
> LongMonthNames: ('January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'); ShortDayNames: ('Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'); LongDayNames: ('Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday');
> TwoDigitYearCenturyWindow: 50
> );
2143,2146c2165
< Str(FValue,Result);
< // Str produces a ' ' in front where the - can go.
< if (Result<>'') and (Result[1]=' ') then
< Delete(Result,1,1);
---
> Result := FloatToStr(FValue, JSONFormatSettings);