Точный десятичный тип данных для С++?

PHP имеет десятичный тип, который не имеет "неточности" поплавков и удвоений, поэтому 2,5 + 2,5 = 5, а не 4.999999999978325 или что-то в этом роде.

Итак, интересно, существует ли такая реализация типа данных для C или С++?

Ответы

Ответ 2

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

#include <iostream>
#include <iomanip>
#include <boost/multiprecision/cpp_dec_float.hpp>

int main()
{
    namespace mp = boost::multiprecision;
    // here I'm using a predefined type that stores 100 digits,
    // but you can create custom types very easily with any level
    // of precision you want.
    typedef mp::cpp_dec_float_100 decimal;

    decimal tiny("0.0000000000000000000000000000000000000000000001");
    decimal huge("100000000000000000000000000000000000000000000000");
    decimal a = tiny;         

    while (a != huge)
    {
        std::cout.precision(100);
        std::cout << std::fixed << a << '\n';
        a *= 10;
    }    
}

Ответ 3

Всегда будет некоторая точность. На любом компьютере в любом представлении чисел всегда будут цифры, которые могут быть представлены точно, и другие числа, которые не могут.

  • Компьютеры используют базовую систему. Числа, такие как 0.5 (2 ^ -1), 0.125 (2 ^ -3), 0.325 (2 ^ -2 + 2 ^ -3), будут представлены точно (0,1, 0,001, 0,011 для вышеуказанных случаев).

  • В базовой системе 3 эти цифры не могут быть представлены точно (половина будет равна 0.111111...), но другие числа могут быть точными (например, 2/3 - 0,2)

  • Даже в системе человеческого основания 10 есть цифры, которые невозможно представить точно, например 1/3.

  • Вы можете использовать рациональное представление чисел, и все вышеперечисленное будет точным (1/2, 1/3, 3/8 и т.д.), но всегда будут иррациональные числа. Вы также практически ограничены размерами целых чисел этого представления.

  • Для каждого не представимого числа вы можете расширить представление, чтобы включить его явно. (например, сравнить рациональные числа и представление a/b + c/d*sqrt(2)), но всегда будет больше чисел, которые все еще не могут быть представлены точно. Существует математическое доказательство, которое так говорит.

Итак, позвольте мне спросить вас: что вам нужно? Может быть, точное вычисление на десятичных числах, например. в каком-то денежном выражении?

Ответ 4

То, что вы просите, - это анти-физика.

То, что phyton (и С++ также) делает, отключает неточность, округляя результат в то время, чтобы распечатать его, уменьшив количество значимых цифр:

double x = 2.5;
x += 2.5;
std::cout << x << std::endl;

просто заставляет x печатать с точностью до 6 десятичных цифр (в то время как сам x имеет более 12), и будет округлен как 5, отрезая неточность.

Альтернативы вообще не используют с плавающей запятой и реализуют типы данных, которые выполняют целую "арифметическую" масштабирование: 25/10 + 25/10 = 50/10;

Обратите внимание, однако, что это уменьшит верхний предел, представленный каждым целым типом. Усиление точности (и точности) приведет к более быстрому достижению переполнения.

Рациональная арифметика также возможна (каждое число представлено "numarator" и "знаменателем" ), без потери точности по отношению к делениям (что - по сути - не выполняется, если точно), но опять же, с увеличением значений по мере увеличения числа операций (чем меньше "рациональный" - это число, тем больше числитель и знаменатель) с большим риском переполнения.

Иными словами, факт, что используется конечное число бит (независимо от того, как организовано), всегда приведет к потере, которую вы должны заплатить со стороны малого на стороне больших чисел.

Ответ 5

Если вы ищете тип данных, поддерживающий деньги/валюту, попробуйте это: https://github.com/vpiotr/decimal_for_cpp

(это решение только для заголовка)

Ответ 6

Я предполагаю, что вы говорите о бинарном калькуляторе в PHP. Нет, нет ни одного в C runtime или STL. Но вы можете написать свое собственное, если вы так склонны.

Вот С++-версия BCMath, скомпилированная с использованием Facebook HipHop для PHP: http://fossies.org/dox/facebook-hiphop-php-cf9b612/dir_2abbe3fda61b755422f6c6bae0a5444a.html

Ответ 7

Будучи языком более высокого уровня PHP, вы просто отключаете то, что вы называете "неточностями", но это, безусловно, есть. В C/С++ вы можете добиться аналогичного эффекта, выведя результат в целочисленный тип.