Ответ 1
Да:
Существуют библиотеки произвольной точности для С++.
Хорошим примером является Арифметическая библиотека с несколькими точками GNU.
PHP имеет десятичный тип, который не имеет "неточности" поплавков и удвоений, поэтому 2,5 + 2,5 = 5, а не 4.999999999978325 или что-то в этом роде.
Итак, интересно, существует ли такая реализация типа данных для C или С++?
Да:
Существуют библиотеки произвольной точности для С++.
Хорошим примером является Арифметическая библиотека с несколькими точками GNU.
Библиотека 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;
}
}
Всегда будет некоторая точность. На любом компьютере в любом представлении чисел всегда будут цифры, которые могут быть представлены точно, и другие числа, которые не могут.
Компьютеры используют базовую систему. Числа, такие как 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)
), но всегда будет больше чисел, которые все еще не могут быть представлены точно. Существует математическое доказательство, которое так говорит.
Итак, позвольте мне спросить вас: что вам нужно? Может быть, точное вычисление на десятичных числах, например. в каком-то денежном выражении?
То, что вы просите, - это анти-физика.
То, что 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" и "знаменателем" ), без потери точности по отношению к делениям (что - по сути - не выполняется, если точно), но опять же, с увеличением значений по мере увеличения числа операций (чем меньше "рациональный" - это число, тем больше числитель и знаменатель) с большим риском переполнения.
Иными словами, факт, что используется конечное число бит (независимо от того, как организовано), всегда приведет к потере, которую вы должны заплатить со стороны малого на стороне больших чисел.
Если вы ищете тип данных, поддерживающий деньги/валюту, попробуйте это: https://github.com/vpiotr/decimal_for_cpp
(это решение только для заголовка)
Я предполагаю, что вы говорите о бинарном калькуляторе в PHP. Нет, нет ни одного в C runtime или STL. Но вы можете написать свое собственное, если вы так склонны.
Вот С++-версия BCMath, скомпилированная с использованием Facebook HipHop для PHP: http://fossies.org/dox/facebook-hiphop-php-cf9b612/dir_2abbe3fda61b755422f6c6bae0a5444a.html
Будучи языком более высокого уровня PHP
, вы просто отключаете то, что вы называете "неточностями", но это, безусловно, есть. В C/С++ вы можете добиться аналогичного эффекта, выведя результат в целочисленный тип.