Есть ли способ в Python подсчитать значащие цифры в двойном/плавающем/и т.д.? Я не вижу простого способа сделать это, но я ожидаю, что он будет в библиотеке.
Заранее спасибо.
Есть ли способ в Python подсчитать значащие цифры в двойном/плавающем/и т.д.? Я не вижу простого способа сделать это, но я ожидаю, что он будет в библиотеке.
Заранее спасибо.
Нет. Значащие цифры не так уж важны и мало поддерживаются компьютерными языками. Людям, выполняющим реальные вычисления, нужны планки погрешностей, которые имеют гораздо большую точность — реальные измерения говорят очень точные вещи, такие как «это 0,11 ± 0,03 мм», вместо того, чтобы говорить менее точные утверждения «это 0,1 мм» или «это 0,11 мм». », что заставляет вас выбирать степень десяти, даже если ваша неточность на самом деле не падает в степени десяти.
Вас может заинтересовать библиотека произвольной точности с плавающей запятой, такая как эта:
http://code.google.com/p/mpmath/
Я нашел решение этого сообщения в другом вопросе:
Python подсчитывает значащие цифры
Идея здесь заключается в том, что вы передаете методу число с плавающей запятой как строку, а затем метод использует регулярные выражения для подсчета количества значащих цифр путем разделения строк, где "e"
(для строки с плавающей запятой в научном формате) и где точка ( для обычных строк с плавающей запятой).
Кажется, он хорошо работает до 8 значащих цифр, но поведение после 9-го не гарантируется.
Тем не менее, я считаю, что это лучше, чем
«Значащие цифры не так уж важны и мало поддерживаются в компьютерных языках».
отклик. Это может быть непросто, но вы определенно сможете это сделать, пусть и не идеально.
Компьютеры просто так не работают, по крайней мере, если они не запрограммированы на это. Предполагается, что число, которое вы им даете, является точным. Если вы создадите число 2/3 как 0,6666666666666667, то все операции обработают его именно так. Эта ошибка в младшей значащей цифре может в конечном итоге распространиться на более крупные ошибки в последующих вычислениях, но это то, с чем должен иметь дело хороший код, используя алгоритмы, которые минимизируют эти проблемы, когда это возможно.
Однако, как я уже сказал, компьютеры делают то, что им говорят. Так что есть написанные пакеты, которые используют то, что называется интервальной арифметикой. Затем число может быть описано как интервал, поэтому мы можем создать 2/3 как интервал [0,6666666666666666,0,6666666666666667]. Мы можем работать с интервалами, складывать, вычитать, умножать и т. д. В этих операциях ширина интервала часто увеличивается по мере того, как мы работаем с ними.
Однако дело в том, что даже если вы используете инструменты интервальной арифметики, именно ВЫ должны знать в начале количество значащих цифр в ваших числах. Если вы создадите число как 2.2, сохранив его как двойное, то компьютер на самом деле попытается сохранить число как 2.200000000000000 и предположит, что все цифры в точности правильные. На самом деле, поскольку используется арифметика с плавающей запятой, число фактически будет храниться внутри как двоичное число. Таким образом, 2.2, вероятно, будет эффективно храниться как число:
2.20000000000000017763568394002504646778106689453125
потому что большинство десятичных дробных чисел не могут быть точно представлены в двоичной форме. Опять же, ко всему программному обеспечению следует подходить с осторожностью, но также и к тому, кто использует эти инструменты, чтобы понять, что на самом деле означают их числа.
Этот последний пункт важен. Многие люди относятся к числам, сгенерированным компьютером, как к истине, записанной компьютерным богом на каменной табличке. Если компьютер выводит 1,4523656535725, они верят каждой цифре того, что видят. Фактически, здесь необходимо применить здравый смысл, чтобы знать, что, возможно, это число было сгенерировано из данных, которые имели только 3 значащих цифры, поэтому вы можете полагаться только на первые несколько значащих цифр этого числа. И, конечно же, именно поэтому вас учат этой концепции в школе, чтобы знать, чему можно доверять, а чему не доверять. Помните, однако, что компьютеры, как правило, бесконечно доверяют. Именно вы должны применить фильтр.
Встроенная десятичная библиотека может очень хорошо помочь с это связано с тем, что он решает проблемы с использованием аппаратных чисел с плавающей запятой. Он имеет внутреннее представление, которое содержит только значащие цифры и показатель степени. Таким образом, вы можете использовать это для подсчета значащих цифр следующим образом:
from decimal import Decimal
def count_sigfigs(numstr):
return len(Decimal(numstr).normalize().as_tuple().digits)
Это работает очень хорошо для многих примеров, таких как эти (от этот связанный вопрос). Обратите внимание, что вам нужно вводить числа в виде строк, чтобы он работал правильно. Использование поплавков испортило бы это из-за их аппаратного представления.
tests = [('2', 1),
('1234', 4),
('2.34', 3),
('3000', 1),
('0.0034', 2),
('120.5e50', 4),
('1120.5e+50', 5),
('120.52e-50', 5)]
for num, expected in tests:
print(count_sigfigs(num) == expected)
Который дает:
True
True
True
True
True
True
True
True
К сожалению, это не совсем работает с такими числами, как 1.000, у которых 4 знака. Это просто дает 1. Поэтому для охвата всех случаев потребуется улучшение. Также он дает 1 вместо 0, хотя обычно это должно давать 0.
Если убрать normalize
, то работает для 1.000
, но не для 3000 (на нем написано 4, а не 1).