Получить DECIMAL (10,2) в C ++ и показать это? - PullRequest
0 голосов
/ 07 февраля 2012

Есть небольшая проблема с десятичным форматом данных. Итак, код выглядит так:

        #define SHOW_MONEY                    "Money = %.2f!"
        QueryResult result = MyDatabase.PQuery("SELECT money FROM users WHERE user_id = '%u'", GetUserId());

        char str[64];

        Field *fields = result->Fetch();
        float money = fields[0].GetFloat();

        sprintf(str, SHOW_MONEY, money);
        user->ShowInformation(str, GetUserId(), true);

И когда поле содержит значения типа 12312313.95, вместо правильного значения отображается 12312314.00 (значение округлено). Существуют ли какие-либо встроенные методы для работы с десятичными данными в MySQL? Мне нужно получить точное значение и показать его пользователю. Есть предложения?

Ответы [ 2 ]

1 голос
/ 07 февраля 2012

float является ограниченным форматом данных и может содержать только столько бит информации (или std::numeric_limits<float>::digits10 десятичных знаков), в вашем случае достаточно только для 12312314, но не больше информации.

Какбыстрый обходной путь, который вы можете попробовать использовать double или даже long double, однако вам следует подумать о том, какими свойствами вы хотите, чтобы ваши числа обладали.Двоичные числа с плавающей запятой не могут даже точно представлять числа, такие как 0.1 (обширная информация по этому вопросу может быть найдена здесь ).

Поскольку вы имеете дело с денежными монетами, используйте десятичную с плавающей запятойбиблиотека или библиотека с фиксированной точкой может быть лучшей альтернативой.

1 голос
/ 07 февраля 2012

float слишком маленький формат.Используйте double, или, если ваш компилятор поддерживает его, long double для получения большей точности.

Однако эти типы с плавающей запятой не могут хранить точные значения, такие как 12312313.95.decimal является точным форматом: он может хранить точное значение, которое вы поместили в него с заданной точностью.Преобразование в long double всегда будет терять некоторую точность.
То, как вы их сейчас используете, с printf("%.2f") будет работать нормально (оно будет округляться в правильном направлении), но если вы собираетесь выполнять обширные вычисления над ними,возможно, было бы лучше сначала преобразовать их в long int (путем умножения на 100 и округления) и переключаться обратно на длинные двойные числа только при повторном сохранении их в базе данных.

...