Відповіді0 / 8
правильних: 0
Питання 1 / 8
Скільки буде -7 // 2 у Python і чому саме так?
Чому так. Оператор
// округлює вниз, до мінус нескінченності: −3.5 йде до −4, а не до −3. Це не примха: тільки так виконується рівність b*(a//b) + a%b == a з остачею, що має знак дільника, тому -7 % 2 дає 1. Варіант «−3» — це поведінка C і Java, де остача виходить відʼємною (−1).Питання 2 / 8
0.1 + 0.2 дає 0.30000000000000004. Що саме там сталося?
Чому так. Округлень тут три:
0.1 і 0.2 зберігаються трохи більшими за справжні, їхню точну суму процесор округлює до найближчого представного числа, а літерал 0.3 округлився в інший бік — трохи вниз. Саме додавання виконується точно; і JavaScript, і C, і Java дадуть той самий результат — це властивість формату IEEE 754, а не мови.Питання 3 / 8
Обчислена величина має бути нулем, але math.isclose(x, 0.0) завжди повертає False. У чому причина?
Чому так.
math.isclose за замовчуванням дає відносний допуск: різниця порівнюється з rel_tol × max(|a|,|b|). Якщо одне з чисел — нуль, а друге крихітне, то й поріг виходить крихітним, і будь-яка різниця його перевищує. Правильно так: math.isclose(x, 0.0, abs_tol=1e-9). Зменшення rel_tol тільки погіршить ситуацію.Питання 4 / 8
round(2.675, 2) дає 2.67, а не 2.68. Чому?
Чому так. Це навіть не половинний випадок: найближчий до 2.675 двійковий дріб дорівнює
2.67499999999999982236…, тобто трохи менший. Тому найближчі два знаки — це 2.67, і round() спрацював абсолютно правильно над тим числом, яке йому дали. Банківське округлення тут ні до чого — воно вмикається лише на точних половинках, як у round(2.5).Питання 5 / 8
2 ** 1000 обчислюється миттєво, а 2.0 ** 1024 кидає OverflowError. Чому такий контраст?
Чому так. У 64-бітному
float під поле порядку відведено рівно 11 бітів, тому найбільший степінь двійки трохи менший за 21024 — далі лише inf. int у CPython — це масив «цифр» по 30 бітів: щоб зберегти більше число, додається ще одна цифра. Тому 2 ** 1024 — звичайне ціле на 309 десяткових цифр і 152 байти памʼяті.Питання 6 / 8
math.fsum([0.1] * 3) — чи дорівнює це рівно 0.3?
Чому так.
math.fsum підсумовує точно й округлює один раз у кінці — але підсумовує він ті числа, які йому дали. А кожне збережене 0.1 уже трохи більше за одну десяту, тому їхня точна сума більша за 0.3, і результат — 0.30000000000000004. Жоден алгоритм підсумовування не може виправити похибку, яка сидить у самих доданках; тут рятує лише Decimal.Питання 7 / 8
Ти рахуєш гроші й пишеш Decimal(0.1) + Decimal(0.2). Що вийде?
Чому так.
Decimal(0.1) чесно копіює точне значення переданого float — усі 55 цифр 0.1000000000000000055511…. Decimal рятує тільки тоді, коли створений із рядка: Decimal(ʼ0.1ʼ) + Decimal(ʼ0.2ʼ) дає рівно Decimal(ʼ0.3ʼ). Тому правило просте: у гроші число потрапляє з рядка, ніколи через float.Питання 8 / 8
int(-3.9) дає -3, а -3.9 // 1 дає -4.0. Чому на тому самому числі різні відповіді?
Чому так.
int() завжди рухається до нуля: −3.9 → −3, 3.9 → 3. // завжди рухається вниз, до мінус нескінченності: −3.9 → −4. На додатних числах ці напрямки збігаються, тому різницю видно лише на відʼємних. Якщо потрібне саме округлення до найближчого — бери round().