Установите точность с плавающей запятой с помощью rapidjson

Есть ли способ контролировать точность вывода в JSON, сгенерированного с помощью Rapidjson?

Например:

writer.String("length");
writer.Double(1.0 / 3.0);

Это генерирует что-то вроде:

{ length: 0.33333333 }

Я отправляю много значений, и для нескольких значений нужны только два десятичных знака.


person Drew Noakes    schedule 19.04.2013    source источник
comment
Похоже, это невозможно. Я открыл запрос функции для этой функции.   -  person Drew Noakes    schedule 19.04.2013


Ответы (2)


Для тех, кто наткнулся на этот случай, 11 февраля 2016 года в Rapidjson был добавлен этот метод:

rapidjson::Writer::SetMaxDecimalPlaces(int maxDecimalPlaces)

Предоставленный по умолчанию класс Writer более полный, чем другой ответ здесь, и его следует всегда использовать, если у вас нет особых потребностей.

person ncore    schedule 26.07.2021

Из источников

Writer& Double(double d)
{ 
   Prefix(kNumberType);
   WriteDouble(d);
   return *this; 
}

//! \todo Optimization with custom double-to-string converter.
void WriteDouble(double d) {
        char buffer[100];
#if _MSC_VER
    int ret = sprintf_s(buffer, sizeof(buffer), "%g", d);
#else
    int ret = snprintf(buffer, sizeof(buffer), "%g", d);
#endif
    RAPIDJSON_ASSERT(ret >= 1);
    for (int i = 0; i < ret; i++)
         stream_.Put(buffer[i]);
}

Для g стиля преобразования будет выполнено преобразование в стиль e или f.

f: Точность определяет минимальное количество цифр, которое должно появиться после символа десятичной точки. Точность по умолчанию - 6.

цитаты из здесь

Есть вариант, написать новый Writer класс и написать свою реализацию Double функции.

Простой пример последнего случая

template<typename Stream>
class Writer : public rapidjson::Writer<Stream>
{
public:
   Writer(Stream& stream) : rapidjson::Writer<Stream>(stream)
   {
   }
   Writer& Double(double d)
   {
      this->Prefix(rapidjson::kNumberType);
      char buffer[100];
      int ret = snprintf(buffer, sizeof(buffer), "%.2f", d);
      RAPIDJSON_ASSERT(ret >= 1);
      for (int i = 0; i < ret; ++i)
         this->stream_.Put(buffer[i]);
      return *this;
   }
};

использование как

int main()
{
   const std::string json =
      "{"
      "\"string\": 0.3221"
      "}";
   rapidjson::Document doc;
   doc.Parse<0>(json.c_str());

   rapidjson::FileStream fs(stdout);
   Writer<rapidjson::FileStream> writer(fs);
   doc.Accept(writer);
}

результат: {"строка": 0,32}

Конечно, если вы используете Writer вручную, вы можете написать функцию Double с параметром точности.

person ForEveR    schedule 19.04.2013
comment
Спасибо. Похоже, тогда это изначально невозможно. Я счастлив добавить перегрузку в их API, поэтому сделаю ее на основе ваших предложений. - person Drew Noakes; 19.04.2013