DEV: Рубиновые тона
3.22K subscribers
143 photos
2 videos
8 files
972 links
Анонсы новых видео о программировании (Ruby/Rails, Solidity/Ethereum, Python, JS и не только), практические советы, обзор полезных инструментов и новости из мира IT
Download Telegram
Теперь поговорим о дробных числах и их представлении в компьютере, в частности, о том, как их описывает стандарт IEEE 754, принятый в 1985 году.

Чтобы было проще, начнём с обычного десятичного числа 35.42, у которого, как можно видеть, имеется дробная часть. Как ещё можно записать это число? Ну, к примеру, вот так:

3 * (10 ** 1) + 5 * (10 ** 0) + 4 * (10 ** -1) + 2 * (10 ** -2)


То есть тут повторяется ситуация с порядковыми номерами, которую мы видели ранее при обсуждении целых чисел. Каждая цифра здесь привносит определённое значение в зависимости от своего порядкового номера.

При этом цифрам, стоящим после точки, мы просто присваиваем отрицательные индексы. В принципе, это же число можно представить как 35 + (42 / 100), суть та же.

Ясное дело, этот принцип можно применить и двоичным числам. К примеру, если взять двоичное 101.11, то у нас выйдет:

1 * (2 ** 2) + 0 * (2 ** 1) + 1 * (2 ** 0) + 1 * (2 ** -1) + 1 * (2 ** -2)


Или, проще говоря,

4 + 0 + 1 + (1/2) + (1/4)


То есть мы видим, что после точки у нас появляются дроби со степенями двойки: 1/2, 1/4, 1/8, и так далее. Так мы можем легко представить дробь 3/16 (или 0.1875), это будет 0.0011. Хотя такой подход в теории можно использовать, он не слишком удобен, особенно для очень больших чисел.

Поэтому стандарт IEEE 754 представляет дробные числа в виде формулы:

((-1) ** s) * M * (2 ** E)


Здесь три параметра, и в компьютере каждый хранится в своём поле.

s равно либо 0, либо 1. Это информация о знаке, соответствующее поле занимает всегда 1 бит.

M - это мантисса, дробное число, обычно меньше 1. Его представляет поле frac, занимает оно n бит и содержит последовательность`f(n-1), ..., f(1), f(0)`.

Ну, а E - это экспонента, которая может быть как положительной, так и отрицательной. Её представляет поле exp длиной k бит с последовательностью e(k-1), ..., e(1), e(0).

Итак, эти числа состоят аж из трёх полей сразу, и обычно имеют либо одинарную (single, 32 бита), либо двойную (double, 64 бита) точность. К примеру, для одинарной точности s занимает один бит номер 31, exp - с 23 по 30 биты, остальное (с 0 по 22) отводится под мантиссу.

Здесь, правда, возможно три разных случая.

Первый случай самый типичный, он описывает нормированные значения. Это случай, когда экспонента не состоит целиком из нулей или целиком из единиц. Говорят, что экспонента хранится в смещённой (biased) форме, а само её значение считается как:

E = e - B


e - число без знака с последовательностью e(k-1), ..., e(1), e(0). B - это значение bias, которое равно 2 ** (k - 1) - 1, то есть для одинарной точности оно равно 127, потому что в этом случае длина поля exp составляет 8 бит.

Следовательно, финальное значение E будет лежать в пределах от -126 (тк e - число без знака, и оно точно больше нуля в данном случае) до 127 для одинарной точности.

Поле frac в этом случае описывает дробную часть, то есть его значение f в десятичном виде лежит от 0 (включительно) до 1 (не включительно), это довольно важно, процесс формирования f увидим в примере ниже. Финальное значение мантиссы M = 1 + f.

Следующий случай - денормированные значения, это когда в поле exp содержатся все нули. В этом случае E = 1 - B, M = f.

Такие денормированные значения, в частности, используются, чтобы представить значение 0. А чего бы нам для нуля не использовать первый случай? Ну потому, что там M = 1 + f, то есть в любом случае M >= 1.

Кстати, тут получается интересный момент: у нас может быть как +0, так и -0. Почему? Потому что хотя биты в exp и frac занулены, s всё равно может иметь значение как 0, так и 1.

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

Последний третий случай - это специальные значения, когда в поле exp записаны все единицы. Правда, этот случай содержит два других возможных сценария.

Если в frac записаны одни нули, то таким образом мы представляем бесконечность (плюс или минус бесконечность, зависит от знака s) - примеру, если мы поделили на ноль.
👍4
Если в frac указано что-то иное (не все нули), то это значение называется "not a number" (NaN). Оно может вылезти, если результат невозможно представить реальными числами (настоящие джедаи помнят про мнимые числа, это не тот случай), либо если происходит что-то странное в духе "бесконечность минус бесконечность".

В качестве примера можно взять 8-битный формат, где на exp отводится k=4 бит, а на frac даётся n=3 бит (понятно, что на знак в любом случае 1 бит). В этом случае значение bias B = 2 ** (4-1) - 1 = 7.

Как мы представим ноль? Ну, очевидно вот так (биты разграничены по соответствующим полям):

0 0000 000


e=0, E = 1 - 7 = -6.

f можно записать как 0 / 8 (тк в поле frac у нас все нули), M = f = 0 / 8. Выходит формула:

((-1) ** 0) * (0/8) * (2 ** -6) = 0


Классно. Теперь число 7/8, то есть 0.875. Его представление:

0 0110 110


e = 0110 = 6, тогда E = 6 - 7 = -1.

Теперь f. У нас три бита, 2 ** 3 = 8, а само значение frac = 110, то есть 6. Выходит, что f = 6/8, M = 14 / 8.

Подставляем:

((-1) ** 0) * (14 / 8) * (2 ** -1) = 0.875


Попробуем ещё взять вот такое число, это в нашем случае самое большое из денормированных:

0 0000 111


Выходит, что e = 0, E = -6. При этом f = M = 7/8. Подставим:

((-1) ** 0) * (7/8) * (2 ** -6) ~ 0.013671875


А если самое маленькое из нормированных?

0 0001 000


Тут e = 1, E = -6, f = 0 / 8, M = 8 / 8. Подставляем:

((-1) ** 0) * (8/8) * (2 ** -6) ~ 0.015625


Аналогично, самое маленькое позитивное число, которое мы можем представить (грубо говоря, самое близкое к нулю):

0 0000 001


Тут e = 0, E = -6, f = M = 1/8. В формуле:

((-1) ** 0) * (1/8) * (2 ** -6) = 0.001953125


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

Кстати, тут один интересный момент. Смотрите, что у нас вышло:

0 0000 000 = 0

0 0000 001 = 0.001953125

0 0000 111 = 0.013671875

0 0001 000 = 0.015625

0 0110 110 = 0.875


Я расположил эти числа по возрастанию от самого маленького десятичного к самому большому. Но при этом можно видеть, что их двоичные аналоги тоже стоят по возрастанию! Это вовсе не случайно: стандарт создавался с учётом того, что программистам наверняка потребуется сортировать такие числа по тем же принципам, что и для целых чисел (хотя тут есть небольшая проблема, если в первом бите появляется 1, то есть число отрицательное).

Собственно говоря, из примера выше мы видим, что представить "любое" число мы с помощью такого стандарта не можем. К примеру, у нас идёт "перескок" от 0.013671875 сразу к 0.015625, и сделать с этим особенно ничего не получится. Да, можно использовать не 8 бит, а 32 или даже 64 (двойная точность), но, как вы понимаете, всё равно покрыть все возможные случаи никак не выйдет. Поэтому в том же Rust есть понятие "эпсилон" (мы его с вами видели на стриме), то есть определённая погрешность, которую стоит учитывать.
👍4
В этом уроке мы попробуем ответить на важный вопрос: как именно хранятся числа в компьютере, если современные процессоры оперируют только нулями и единицами? Мы узнаем о принципах хранения целых чисел без знака, со знаком, а также о стандарте IEEE 754, описывающем хранение дробных чисел. https://www.youtube.com/watch?v=Pe3GCa3WKBU
❤‍🔥82
О, кажется у меня круглое число 😂
👍15🎉82🎄1
У меня тут новая статья, в этот раз про scraping на питоне с шутками да прибаутками - в частности, сбор результатов из поиска google для последующего анализа (может быть полезно, например, для отслеживания позиций интересующих доменов по разным ключевым словам) https://www.scrapingbee.com/blog/how-to-scrape-google-search-results-data-in-python-easily/
❤‍🔥10👍7👀21
В этом уроке по Ethereum мы посмотрим, что нового появилось в OpenZeppelin Defender v2, что изменилось, и как с ним работать. С помощью этого решения вы сможете легко администрировать контракты, настраивать автоматизированные действия, создавать сценарии выполнения, и многое другое. https://youtu.be/tlhsIZX7LI0
12🔥4
Записал первые три главы аудиокниги "Воспоминания" (Тэффи). Если не знаете, что почитать (послушать), то это отличный вариант. Это не нудные мемуары, а интересное повествование о быте и проблемах во времена Гражданской войны в 1918 году. Здесь нет больших исторических личностей и значительных монологов, только жизнь обычных людей. Как мне кажется, во многом эти события (иногда до степени неотличимости) перекликаются и с тем, что происходит сейчас https://www.youtube.com/watch?v=zzYHjCnOsNc
🙏8👍7🔥2👏1🥱1
А сегодня у нас интересный стрим по Solidiy!

В этом стриме по Solidity мы рассмотрим новое решение от OpenZeppelin под названием AccessManaged. Оно позволяет настраивать права доступа через отдельный контракт, который сообщает, может ли определённая роль вызвать ту или иную функцию. Кроме того, AccessManaged позволяет делать аналог Timelock, то есть определённые роли должны поставить вызов функции в очередь, только спустя некоторое время её выполнить.

https://youtube.com/live/pL6tpKNfmJM?feature=share
👍12🔥2👏1
Что ж, мне очень приятно, что первые три главы (совершенно неожиданно) так заинтересовали слушателей, так что буквально только что закончил запись ещё двух глав. В них рассказывается о том, что же происходило в странном городке, где ветчину едят только днём, и как избежать карантина у немцев. https://www.youtube.com/watch?v=NQvV_Kfbs-A
👍13👎1🔥1😱1
Производил тут небольшой анализ в плане SEO от нечего делать. Обнаружил некоторые забавные вещи - в частности, кто-то создал автоматизированный клон YT, куда льются видео по теме разработки и не только, прямо сплошняком, без стеснения. Ну, что сказать, это предсказуемо.

С большим удивлением узнал, что книга Modern CSS, одним из автором которой я был, теперь доступа в довольно крупном издательстве O'Reilly. Впрочем, думается, что CSS там уже не совсем modern, так как ей лет шесть.

Выяснил также, что существует футболист из Беларуси, который мне почти тёзка 😂 В связи с этим уточню, что все актуальные соцсети перечислены у меня на сайте, если в списке какой-то соцсети нет, то и меня там нет (а то мало ли, будет ещё чудить кто-нибудь) - к примеру, твиттер, вконтакте, инстаграм (хотя в последнем есть страница музыкальной группы).

Если же в поиске обнаружился другой тёзка, но с отчеством Михайлович, то это мой относительно близкий родственник, учёный 🤪

В общем, иногда любопытно погуглить, что находится по своему имени-фамилии, попробуйте

https://www.youtube.com/watch?v=55nPncn6rRk&list=OLAK5uy_l_2JrkrjWXP2riZrzs4pHk5E8X565K7Yg&index=10
👍5😁31🤯1
В этом уроке по Rust мы поговорим об одной из самых неочевидных и необычных тем - о lifetimes, аналога которым в большинстве языков не встречается. Мы попробуем разобраться, зачем это нужно, рассмотрим примеры и порешаем задачи rustlings. https://www.youtube.com/watch?v=usnj6UZTsc4
👍9❤‍🔥2👎1🔥1
Я вот буквально вчера получил странное сообщение в LinkedIn, в котором неизвестный мне джентльмен сообщал, что планирует податься на работу к нам в Lokalise и почему-то просил меня передать его резюме в отдел HR (?). Да, в моём имени была ошибка, но это уже частности.

Выяснил, что это, оказывается, теперь распространённая практика (по словам коллег). Вероятно, я чего-то не понимаю, но первая мысль - человек не сделал "домашнюю работу" и не нашёл кого-нибудь, кто хотя бы как-то связан с hr. Некоторые утверждают, что таким образом ты как бы выделяешься из десятка других кандидатов.

Но ведь я этого человека даже не знаю - как же я могу его рекомендовать?.. Больше того, он подаётся на должность, которая ко мне не имеет отношения. Странно это. Или это и правда типичная история теперь?

Мы вот говорили с нашими студентами какое-то время назад насчёт работы, такой трюк, кажется, никто не упоминал 😂 Впрочем, чего говорить, время сейчас не самое простое, увольнения продолжаются, ИИ шагает широкой поступью...
😁7👍21🤷‍♂1
В свете того, что в ряде стран пользователей сети Интернет вынуждают устанавливать на компьютеры и смартфоны какие-то "специальные", непонятные сертификаты безопасности, некоторые знакомые спрашивают, что всё это значит. Попробую пояснить совсем по-простому и расскажу вам сказку.

Интернет - вообще штука публичная, огромное количество данных передаётся по сети каждую секунду, и кто даст гарантию, что какой-нибудь хитрец не пытается эти данные перехватить, подслушать? Ну, как перехватывают почтовых голубей, гонцов... В простом случае никакой гарантии и нет, ситуация примерно такая же, как и с обычной почтой: ваше письмо в теории может распечатать любопытный сотрудник и посмотреть, что же там такого интересного написано. Может даже дописать что-нибудь от себя, ну, как в мультфильме "Простоквашино", где у Шарика "хвост отваливается". К сожалению, в интернете ситуация аналогичная: пакеты информации при желании можно отловить и даже подсунуть туда что-то ещё (в безобидном случае - рекламу, в плохом случае - нехороший скрипт, который будет красть пароли).

Но если это так, то как же от этого защититься?! К счастью, умные люди уже придумали для нас решение, и называется оно "ассиметричное шифрование". Конечно, обо всём этом мы здесь говорим упрощённо, если вам интересно, у меня есть видео о принципе работы такого шифрования: https://www.youtube.com/live/ttsRlTJJizI.

Так вот, давайте представим, что веб-сайт, на который вы заходите (хотя бы тот же Гугл), будет класть информацию для вас в супер-надёжный запертый сундучок, который невозможно взломать, и отправлять его по почте. Отпереть этот сундучок любопытный сотрудник уже не сможет, но есть маленькая сложность: а как его должны отпирать вы? Иными словами, кто доставит вам ключ, причём так, что никто другой ни в коем случае этот ключ не получит? Может быть, какой-нибудь сказочный гонец? Но если этот гонец может доставить ключ, так почему он не может просто передать письмо, если он настолько сказочный, что его никто не сумеет перехватить? Вот это загадка.

Поэтому был придуман улучшенный принцип. Представьте, что где-то живёт некий мастер, он делает весьма хитрые замки для сундучков и ключи к ним. Зовут этого мастера Удостоверяющий центр. Его замки имеют необычное свойство: для запирания требуется один ключ, а для отпирания - уже совсем другой, парный ему. Больше того, по тому, каким ключом был заперт этот замок, вы можете понять, кто же именно его запер - к примеру, тот же Гугл (хотя это предельное упрощение, скажу честно). Как это помогает в решении нашей проблемы?

А вот как. Гугл может купить у мастера ключик только для себя любимого, и хранить его в секрете, никому не показывать. Это называется "приватный ключ" - мастер изготовил его лишь в одном экземпляре, и больше никогда такой уже не сделает (помните, это как история с храмом Василия Блаженного). Именно этим ключом Гугл и запирает сундучок с данными, которые отправляет вам. А как же его отпирать? Легко!

Дело в том, что для всех желающих мастер может изготовить сколько угодно парных ключей к тому, что был сделан для Гугла в единственном экземпляре. Как мы уже знаем, сундучок запирается одним ключом (в данном случае секретным), а открывается парным ему. Вы можете заказать у мастера парный ключ, он называется "открытый", и отпереть сундучок. Вообще-то, ситуация здесь куда сложнее, потому что нам ещё нужно обезопаситься от ситуации, когда кто-нибудь в этот же момент тоже закажет такой ключик и откроет наш сундук, но поверьте на слово, что такая защита встроена в весь этот процесс (подробнее можно узнать в видео).

Верно и обратное: вы можете положить в сундучок послание для Гугла, запереть его парным ключом, и лишь Гугл сумеет открыть его. Ведь мы уже знаем, что открывается он только парным ключом, а парным выступает тот самый секретный ключ, его нет ни у кого, кроме Гугла, мастер другого такого ключа никогда не сделает! Следовательно, и прочитать переданные вами данные никто не сможет.
🔥17👍1
Кстати, а почему, собственно говоря, мастер не может сделать ещё один такой же секретный ключ и дать его какому-нибудь вредному писарю, который хочет засовывать нос в сундучок? А вдруг этот писарь вообще станет отправлять секретные послания от имени Гугла вам, называть вас в этих посланиях нехорошими словами, а вы будете думать, что это пишет Гугл? Это будет совсем нехорошо!

А вот тут мы упираемся в важнейший вопрос доверия. Мастеров-ключников в этом мире чрезвычайно мало, их буквально несколько десятков, у них кристально чистая репутация, и поэтому люди им доверяют. В конце концов, люди ведь доверяют банкам или государственным структурам (до определённых пределов). Здесь ситуация та же; эти мастера известны всему миру: это, к примеру, VeriSign или Symantec. Они ставят на свои ключи знак качества, а Гуглу и другим структурам выдают специальный сертификат, который удостоверяет, что это именно Гугл и никто иной, это именно он запер сундучок, поэтому мастера и зовутся Удостоверяющими центрами.

Кстати, известные мастера могут брать учеников, которые тоже становятся Удостоверяющими центрами, только уровнем пониже, и они тоже могут создавать свои ключи, но и они должны следовать кодексу чести, никогда не выпуская секретных ключей "мимо кассы" и следя за тем, чтобы ключи не попали к лихим людям. Если же кто-то пришлёт вам сундучок, который был заперт ключом от неизвестного мастера, то ваше устройство сообщит, что здесь явно что-то не так: этот мастер не является доверенным, и он также не является учеником одного из известных мастеров! Список всех известных мастеров хранится на вашем устройстве, это называется "доверенные корневые удостоверяющие центры", и этот список попадает на устройство в момент установки операционной системы.

А теперь представим, что в мире появился мастер-негодяй, который создаёт секретные ключи для веб-сайтов, но раздаёт их всем желающим, в том числе любопытным опричникам. Что это значит? Это как раз значит, что все, получившие такой якобы "секретный" ключ, могут заглядывать в сундучки, которые отправляете вы, и даже подменять письма внутри! Но, постойте, ведь такого мастера-негодяя нет в список "доверенных" на вашем устройстве? Мы ведь уже знаем, что если мастер неизвестен, то нас сразу предупредят. Именно так, но только до тех пор, пока вы собственноручно не добавите имя этого мастера в список доверенных, то есть сделаете ровно то, что требуют от пользователей в некоторых странах.

Как только вы это сделали, вы начинаете автоматически доверять всем ключам этого нового мастера, и всем его ученикам тоже. А если есть подозрения, что мастер нечист на руку, то, быть может, не стоит ему доверять? Кто знает, кому ещё он подарит секретный ключик, и кто ещё сможет просматривать все данные, которые вы отправляете... Именно поэтому стоит быть очень разборчивым в том, кому именно вы доверяете.
👍21🔥94🤯1