Как получить максимально возможную точность?(Python - десятичный) - PullRequest
0 голосов
/ 07 декабря 2018

Я использую класс Десятичный для операций, требующих точности.

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

Чтобы установить определенную точность, все просто:

import decimal
decimal.getcontext().prec = 123 #123 decimal precision

Я пытался определить максимальную точностьКласс 'Decimal' может вычислять:

print(decimal.MAX_PREC)
>> 999999999999999999

Поэтому я попытался установить максимальную точность (зная, что это, вероятно, не сработает ..):

decimal.getcontext().prec = decimal.MAX_PREC

Но,конечно, это выдает Ошибка памяти (при делении)

Итак, мой вопрос: как определить максимальную точность, с которой может справиться текущая система?

Extraинформация:

import sys
print(sys.maxsize)
>> 9223372036854775807

Ответы [ 4 ]

0 голосов
/ 18 декабря 2018

Из вашего ответа выше:

Что, если я просто хочу найти больше цифр в пи, чем уже найдено?Что, если я хочу проверить иррациональность е или константы мельницы.

Я понял.Я действительно так делаю.Мой один SO вопрос , несколько лет, о библиотеках с плавающей точкой произвольной точности для Python.Если это те типы числовых представлений, которые вы хотите создать, будьте готовы к глубокому погружению.Арифметика десятичной дроби / FP общеизвестно хитрая в области компьютерных наук.

Некоторые программисты, столкнувшись с проблемой, думают: «Я знаю, я буду использовать арифметику с плавающей запятой». Теперь у них проблемы 1.999999999997.- @ tomscott

Я думаю, что когда другие говорят, что это "ошибка" или "это зависит", задаюсь вопросом, какова максимальная точность для десятичного типа Python на данной платформеОни воспринимают ваш вопрос более буквально, чем я предполагаю.Вы спрашивали о десятичном типе Python, но если вас интересует арифметика FP для образовательных целей - «чтобы найти больше цифр в пи» - вам понадобятся более мощные, более гибкие инструменты, чем Десятичная или float .Эти встроенные типы Python даже не подходят close .Возможно, они достаточно хороши для НАСА, но у них есть ограничения ... на самом деле, те самые пределы, о которых вы спрашиваете.

Это то, что плавающая множественная точность (или произвольная точность )точечные библиотеки предназначены для: произвольно точных представлений.Хотите вычислить pi на следующие 20 лет?Десятичный тип в Python даже не проведет вас через день .

Дело в том, что двоичная арифметика FP с множественной точностью все еще является довольно сложной наукой.Для Python вам нужно установить библиотеку GNU MPFR на вашем компьютере с Linux, затем вы можете использовать библиотеку Python gmpy2 , чтобы погрузиться так глубоко, как вам хочется.

Тогда вопрос не в том, «Какова максимальная точность, которую может использовать моя программа?»

Это «Как мне написать мою программу, чтобы она работала до тех пор, пока не исчезнет электричество»out? "

И это совсем другая проблема, но, по крайней мере, она ограничена вашим алгоритмом, а не оборудованием, на котором она работает.

0 голосов
/ 16 декабря 2018

Максимальная точность класса Decimal является функцией памяти на устройстве, поэтому нет хорошего способа установить ее для общего случая.По сути, вы выделяете всю память на одной переменной, чтобы получить максимальную точность.

Если математическая операция поддерживает это, длинные целые числа дадут вам неограниченную точность.Тем не менее, вы ограничены целыми числами.

Сложение, вычитание, умножение и простые экспоненты могут выполняться точно с длинными целыми числами.

До Python 3 встроенная longТип данных будет выполнять вычисления произвольной точности.https://docs.python.org/2/library/functions.html#long

В Python> = 3 тип данных int теперь представляет длинные целые числа.https://docs.python.org/3/library/functions.html#int

Одним из примеров 64-разрядного целочисленного вычисления является реализация bitcoind, где для расчетов транзакций требуются точные значения.Однако точность транзакций в биткойнах ограничена 1 сатоши;каждый биткойн определяется как 10 ^ 8 (целое число) сатоши.

Десятичный класс работает аналогично под капотом.Десятичная точность 10 ^ -8 аналогична парадигме Биткойн-Сатоши.

0 голосов
/ 17 декабря 2018

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

Ваши операции фактически не потребуют "максимально возможной" точности, даже если этобыло четко определенное понятие.Либо они требуют точную арифметику, в этом случае decimal.Decimal является совершенно неправильным инструментом, и вам следует рассмотреть что-то вроде fractions.Fraction или символьное вычисление, или они не требуют такой большой точности, и вы должныопределите, сколько точности вам действительно нужно и используйте ее.

Если вы все еще хотите использовать всю точность, которую можете решить в своей задаче, то насколько точная точность будет зависеть от того, какого родаматематики, которую вы делаете, и сколько нелепо точных цифр вы пытаетесь сохранить в памяти одновременно.Это можно определить, проанализировав вашу программу и требования к памяти для объектов Decimal, или вместо этого вы можете взять точность в качестве параметра и выполнить бинарный поиск наивысшей точности, которая не вызывает сбой.

0 голосов
/ 15 декабря 2018

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

def find_optimum(a,b, max_iter):
    for i in range(max_iter):
        print(i)
        c = int((a+b)/2)
        decimal.getcontext().prec = c
        try:
            dummy = decimal.Decimal(1)/decimal.Decimal(7) #your operation
            a = c
            print("no fail")
        except MemoryError:
            print("fail")
            dummy = 1
            b = c
        print(c)
        del dummy

Это просто вдвое сокращает интервалы один шаг за раз и выглядитесли произошла ошибка.Вызов с max_iter=10 и a=int(1e9), b=int(1e11) дает:

>>> find_optimum(int(1e9), int(1e11), 10)
0
fail
50500000000
1
no fail
25750000000
2
no fail
38125000000
3
no fail
44312500000
4
fail
47406250000
5
fail
45859375000
6
no fail
45085937500
7
no fail
45472656250
8
no fail
45666015625
9
no fail
45762695312

Это может дать приблизительное представление о том, с чем вы имеете дело.Это заняло примерно полчаса на i5-3470 и 16 ГБ ОЗУ, так что вы действительно использовали бы его только для тестирования.

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

РЕДАКТИРОВАТЬ Я чувствую, что это действительно нужно добавить, так какЯ читаю ваши комментарии под постом с самым высоким рейтингом здесь.Использование произвольно высокой точности таким способом - это не тот способ, которым люди вычисляют константы.Вы могли бы запрограммировать что-то, что будет разумно использовать дисковое пространство (например, вычислять кучу цифр в ОЗУ и записывать эту кучу в текстовый файл), но никогда не использовать только RAM / swap, потому что это всегда будет ограничивать ваши результаты.С современными алгоритмами для вычисления числа пи вам не нужно бесконечное ОЗУ, вы просто вставляете в машину еще один жесткий диск объемом 4 ТБ и позволяете ему записать следующие цифры.Что касается математических констант.

Теперь о физических константах: они не точны.Они полагаются на измерение.Я не совсем уверен, atm (будет редактировать), но я думаю, что физическая константа самая точная имеет ошибку 10 ** (- 8).Прибавляя к этому больше точности, это не делает его более точным, вы просто вычисляете больше неправильных чисел.

В качестве эксперимента это была забавная идея, поэтому я даже опубликовал ответ в первую очередь..

...