Это мои добавочные заметки к главам 3 и 4 (арифметические операции и преобразование типов)
Натуральные числа (1, 2, 3, ...) как простейшие мат. модели множеств. Сумма, произведение, целая натуральная степень, разность большего и меньшего натурального числа - натуральны. Умножение на 1 не изменяет произведение. Деление нацело с возможным остатком.
Ноль как модель пустого множества (вычитание числа из самого себя). Сложение с нулём не изменяет сумму. Умножение на ноль даёт ноль. Деление на ноль не определено.
Отрицательные числа как модель нехватки или задолженности (вычитание сводится к сложению с отрицательным числом). Для каждого числа существует число с противоположным знаком, сложение с которым даёт ноль. Смена знака числа - это его умножение на -1.
Целые числа: положительные, отрицательные и ноль. Положительные >0. Неотрицательные не<0 (≥0).
К каждому целому числу можно прибавить или вычесть 1 и получить следующее или предыдущее число. Целое число a меньше целого числа b, если к a нужно прибавить несколько (в т.ч. "много") единиц, чтобы получить b (отношение порядка на множестве целых чисел, или числовой прямой).
Позиционные системы счисления. Две руки по пять пальцев на каждой. Двоичная система. Показать числа от 0 до 1023 на 10 пальцах (назначив каждому пальцу вес от 20 до 29). "Ёмкость" или "точность" двоичных чисел длиной n бит = 2n. Каждое число от 0 до 2n-1 представимо как сумма [некоторых, выбранных нами] степеней двойки от 0 до n. Например, 456=28+27+26+23. 1000=29+28+27+26+25+23. . Минимальное значение, представимое n битами - 0 (n 0-бит). Максимальное - 2n-1 (n единичных бит). Для представления самого́ числа 2n нам нужно уже n+1 бит (единица и n нулей). В компьютерных системах, использующих целые числа фиксированной точности (8/16/32/64 бита, называемые "байт", "слово", "двойное слово", "учетверённое слово"), это выглядит как двоичное переполнение или "перенос" и может либо вызывать ошибку, либо выделение памяти под дополнительные биты.
Целые числа произвольной точности представляются в виде последовательности бит (степеней двойки), разбитых на группы фиксированной длины (т.е. 1 или более чисел фиксированной точности). В Pythone (2**62-1)*2+1 - это наибольшее целое число, представимое в виде одного машинного слова. Если мы прибавим к нему 1, Python выделяет память для дополнительных бит и изображает число с суффиксом L (тип long, длинное). Если вычислять значение (2**62-1)*2+1 как 2**63-1, результат будет сразу иметь суффикс L (тип long).
Целые числа произвольной точности соответствуют своей мат.модели, при условии достаточного объёма памяти и процессорного времени для их обработки. Т.е. мы можем получить точное представление целых чисел 101000,101000+1,101000-1 и т.п.
Деление выводит нас из целых чисел в рациональные - соотношения двух целых (a/b). Рациональные числа включают в себя целые числа (b=1, a/1=a), правильные и неправильные дроби (a < b и a > b), десятичные дроби (b=10k), в т.ч. проценты (b=100 или b=102+k), и двоичные дроби (b=2k).
Сумма, разность, произведение, частное от деления на ненулевое рац. число, целая степень рац. числа (кроме 00) - рациональны.
Для ненулевого рац.числа a/b существует обратное число b/a, произведение которых даёт единицу. Это позволяет заменить деление умножением (на обратное число), а также вводит отрицательную степень (b/a = (a/b)-1). Другие свойства степеней : (a*/b)n = (an)*/(bn) ; (an)*/(am) = a(n+-m); 0n=0 (при n ≠ 0); n0=1 (при n ≠ 0); 1n=1
Пропорции: если a/b = c/d, то a/c = b/d и a*d = b*c
10=2*5, т.е. 1/2 = 5/10 и 1/2n = 5n/10n
Из делимости 10 на 2 следует, что любая двоичная дробь может быть представлена в виде десятичной : a/2k = a*5k/10k
Но не любая десятичная дробь может быть представлена в виде двоичной с конечным числителем и знаменателем. К примеру, 1/10 (0.1 или 1e-1) представимо только в виде суммы бесконечного ряда двоичных дробей - именно из-за того, что 1 не делится на 5 нацело.
Плавающие числа в компьютерных системах имеют точность 32, 64, 128 или более бит и хранятся в виде двоичных дробей (a/2k). Чаще всего используется двойная точность - 64 бит. Из которых 1 бит отводится под знак, 11 бит под показатель степени двойки (знаковое число k) и 52 бита под мантиссу (a - дробную часть, умножаемую или делимую на степень двойки).
Это обеспечивает точность около 16 десятичных знаков.
Самые простые операции над плавающими числами (двоичными дробями) - это их умножение или деление на 2 (или на степень двойки), которые сводятся только к увеличению или уменьшению показателя степени двойки (k).
Потерю точности при сложении/вычитании плавающих чисел можно наблюдать уже на самых простых примерах : 1.1-1.0-0.1 ; 0.6-0.4-0.2 и т. п.
Эти маленькие остатки являются плавающими числами, т.е. двоичными дробями. Умножая их на степень двойки, можно получить значение числителя двоичной дроби в целом виде : (1.1-1.0-0.1) = 3/255 = 3*555/1055 , 0.6-0.4-0.2 = -1/254 и т.п.
Абсолютная погрешность в этих примерах имеет десятичный порядок -16..-17, что соответствует точности 16 десятичных знаков.
При этом изменение порядка операций в одних случаях можеть дать правильный ответ (0) : 1.1-0.1-1.0 ; а в других нет : 0.6-(0.4+0.2)
print в Pythone печатает плавающие числа с округлением до 12 знаков, так что при выводе результатов через print эти погрешности незаметны (только при вычислении в интерактивной командной строке).
В десятичных калькуляторах потеря точности начинается только при сложении достаточно малых чисел с достаточно большими. Если оба числа умещаются в точность, предоставляемую калькулятором, их сумма и разность оказываются точными.
Большие целые числа, превышающие 253, хранятся в плавающем виде a*2k (где a<253), что также позволяет сохранить не более 16 значащих десятичных цифр.
В формате float к числу 253 уже невозможно прибавить единицу без потери точности, т.е. float(2**53), float(2**53)+1.0 и float(2**53+1) оказываются равными между собой (что также полезно помнить программистам на JavaScript). Таким образом, в компьютерных системах (но не в математике) существует граница, выше которой плавающие числа перестают вести себя как целые. Мы ещё можем вычесть единицу из плавающего представление 2**53 (т.е. представить в плавающем виде 2**53-1 без потери точности). Но мы уже не можем вычесть 1 из плавающего представления 2**53+2: a=float(2**53+2) ; a-(a-1) (= 2.0 вместо 1.0).
Если десятичные плавающие числа вида 1*10N (1eN) преобразовывать в целые и вычитать из них целые степени 10**N, потеря точности начинается с N>=23 : int(1e23)-10**23 . Для N=308 абсолютная погрешность выглядит как 292-значное целое число, но и в этом случае соответствует точности плавающего представления не более 16 десятичных знаков (308-292).
Наибольшее целое положительное число, которое мы можем преобразовать во float в Pythone : 2**1024-2**970-1 . Если убрать -1, float() вызывает переполнение.
Для большинства инженерно-физических расчётов 64-битные floatы обеспечивают приемлемую на практике точность, особенно если избегать сложения/вычитания слишком малых и слишком больших чисел.
Если решаемая задача требует бо́льшей точности, Python предоставляет модули(библиотеки) fractions для расчётов в рациональных числах (произвольной точности) и decimal для десятичных (точность по выбору, 28 десятичных знаков по умолчанию).
no subject
Date: 2015-03-01 08:30 pm (UTC)no subject
Date: 2015-03-04 12:27 am (UTC)Не останавливайся!!!
))))