Opened 14 years ago

Last modified 6 years ago

#312 new defect

Incorrect formatting with negative value of decimal places

Reported by: mloskot Owned by: strk
Priority: major Milestone: GEOS Fund Me
Component: Core Version: main
Severity: Significant Keywords: precision model
Cc:

Description (last modified by mloskot)

Testing GEOS PrecisionModel and WKTWriter with assumption taken from JTS implementation of jts/geom/PrecisionMode.java (version 1.7)

 /* For example, to specify 3 decimal places of precision, use a scale factor
  * of 1000. To specify -3 decimal places of precision (i.e. rounding to
  * the nearest 1000), use a scale factor of 0.001.
  */

Using scale value 0.001 leads to garbage formatter %.-1f which behaves differently with various C implementations. Here is test program that mimics formatting performed by GEOS:

#include <cmath>
#include <cstdio>
#include <string>
#include <iostream>

int main()
{
    double scale = 0.001; // -3 decimal places

    // PrecisionModel::getMaximumSignificantDigits
    const int digits = 1 + (int)std::ceil(std::log(scale) / std::log(double(10.0)));
    std::cout << digits << std::endl;

    // WKTWriter::createFormatter
    std::string fmt("%.");
    {
        char buffer[255] = { 0 };
        sprintf(buffer, "%i", digits);
        fmt.append(buffer);
        fmt.append("f");
        std::cout << fmt << std::endl;
    }

    // WKTWriter::writeNumber
    {
        const double n = 12345.54321;
        char buffer[255] = { 0 };
        sprintf(buffer, fmt.c_str(), n);  // writes n as -1f
        std::cout << buffer << std::endl;
    }

    return 0;
}
  • Visual C++ 10.0 outputs:
    -1       // digits
    %.-1f    // fmt
    -1f      // buffer
    
  • GCC 4.4.1 outputs:
    -1
    %.-1f
    %.0-1f
    

Change History (7)

comment:1 by pramsey, 14 years ago

Milestone: 3.2.1

comment:2 by strk, 14 years ago

Mat, do you have a clever C++ trick to handle this ?

comment:3 by mloskot, 14 years ago

Description: modified (diff)

comment:4 by mloskot, 14 years ago

Sandro, I don't have any trick that would make this concept working directly. In both, C printf-like functions and C++ streams, negative precision means precision omitted. See my reply to SO's negative precision values in ostream.

I suppose the whole formatting should be reimplemented with "manual" decisions on rounding and scaling depending on precision sign and value.

comment:5 by strk, 13 years ago

Milestone: 3.2.13.2.3

comment:6 by strk, 13 years ago

Milestone: 3.2.3GEOS Future

Being a C++ API only change I don't see any urgency to fix this...

comment:7 by robe, 6 years ago

Milestone: GEOS FutureGEOS Fund Me

Milestone renamed

Note: See TracTickets for help on using tickets.