php работа с большими числами

Как работать с большими числами?

Пытаюсь записать и вывести большое число.

Результат
1.407606688E+12
А нужно
1406772865000

Помощь в написании контрольных, курсовых и дипломных работ здесь.

Как работать с большими XML
На стороннем сайте лежит XML, все товары магазина с описанием. 50 Мб. Мне нужны из этого файла.

Как работать с большими числами
Если нужно с числами длиной 128 бит или больше. Есть ли встроенный тип данных для таких размеров.

Как работать с очень большими числами?
Как можно складывать, вычитать, умножать друг на друга очень большие числа, которые не вмещаются.

Как работать с большими числами, не вмещающиеся в тип double
Доброго времени суток. Нужно найти x. 6^x mod 89548831 = 35152307 я решил сделать обычным.

Для работы с очень большими и очень маленькими числами
есть библиотеки, такие как BCMath и вроде GMP.

Ничего не знаю о GMP, а вот с BCMath работать очень
просто, почитайте о ней=)

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

Помощь в написании контрольных, курсовых и дипломных работ здесь.

Как работать с большими числами (больше чем int64)?
Дело такое: написал алгоритм, где генерируется код, по которому далее шифруется текст. Шифрование.

Как работать с большими текстами?
Что посоветуете чтоб программка начала работать с большими текстами. С небольшой строкой у нас.

Как работать с большими словарями
Здравствуйте! Подскажите пожайлуста как работать с большими словарями: в файле храниться.

Как реализовать работу с очень большими числами?
Добрый день всем! Очень необходимы светлые мозги, ибо не могу понять в чем проблема. Есть.

Источник

Как обрабатывать терабайты данных в 1000 потоков на PHP — Hadoop/MapReduce

Уже слышали про Bigdata? Ну да, веб растет, данных становится больше и их нужно держать под контролем и периодически анализировать. Базы данных — лопаются под нагрузкой, реляционная теория не совсем справляется с задачей, нужно решение. Маркетинг активно давит сверху, а железо острыми углами — снизу и попахивает суицидом.

В этом посте постараюсь дать конкретные работающие рецепты и куски кода с краткими теоретическими выводами, как же обрабатывать >=терабайты в >=1000 потоков на PHP. Чтобы можно было взять и решить задачу, не теряя времени и не забивая голову теорией.

Однако, если вдруг стало подташнивать и закружилась голова, можно дальше не читать — а полюбоваться на прекрасных птичек и забыть о вышенаписанном. Но будьте на чеку, Bigdata может завтра взять и постучаться в дверь 😉
php работа с большими числами. Смотреть фото php работа с большими числами. Смотреть картинку php работа с большими числами. Картинка про php работа с большими числами. Фото php работа с большими числами

Как обычно делается

Как обычно бывает в вебе. Складывают данные в БД, пока не лопнет. Если лопается, начинаются разговоры про MySQL sharding, partitioning, вспоминают про мульти-мастер кластер в оперативной памяти.

Если не помогает, начинаются поиски и внедрения NoSQL решения типа redis или облачного сервиса типа DynamoDB. Неплохо себя зарекомендовал в качестве эффективного поискового движка по объемным данным Sphinx.

Подсознательно идет расчет — сохраним в БД и потом проанализируем информацию. И это нередко работает. Но не всегда… и это «не всегда» становится чаще.

Данных еще больше, требуется он-лайн аналитика

Не всегда можно ответить бизнесу — подождем сутки, проанализируем логи/данные и дадим циферки. Бизнесу часто важно иметь циферки в онлайне, управлять ситуацией по приборам с живыми стрелочками.
php работа с большими числами. Смотреть фото php работа с большими числами. Смотреть картинку php работа с большими числами. Картинка про php работа с большими числами. Фото php работа с большими числами

Страшно представить управление самолетом путем анализа записанной в черные ящики информации один раз в сутки в гостинице для пилотов 🙂
php работа с большими числами. Смотреть фото php работа с большими числами. Смотреть картинку php работа с большими числами. Картинка про php работа с большими числами. Фото php работа с большими числами
php работа с большими числами. Смотреть фото php работа с большими числами. Смотреть картинку php работа с большими числами. Картинка про php работа с большими числами. Фото php работа с большими числами

Когда поток данных становится еще интенсивнее или бизнес-логика требует наличия текущей информации по еще не обработанным данным… Тогда нам помогают инструменты «потокового анализа» типа:
1) pinba
2) Amazon Kinesis
3) Потоковые парсеры на базе nginx/ragel

Полезно хотя бы один раз каждый из этих бесценных инструментов понять с листочком и карандашом, еще полезнее — «переспать» с мануалом и прототипом минимум ночь.
php работа с большими числами. Смотреть фото php работа с большими числами. Смотреть картинку php работа с большими числами. Картинка про php работа с большими числами. Фото php работа с большими числами

Особо хочется выделить здесь pinba за простоту настройки и легкость эксплуатации и минимум создаваемой нагрузки. Организовать сбор статистики по производительности веб-приложения в браузере его клиентов на основании js Navigation Timing API — делается в 2 файла на PHP на 30 строк.

Когда же нет возможности анализировать данные онлайн — начинаются поиски решения параллельного анализа накопленных данных и связанных с ним алгоритмов.

Параллельная обработка массивов данных

Есть список объектов, допустим это файлы в облаке s3, которых у вас — десятки миллионов. Как бы мы не доверяли облаку, нужно эти файлы периодически выгружать в другое облако/серверы. Каждый файл шифруется, сжимается, происходят другие операции и копируется.

Эти задачи подпадают под общий алгоритм «разделяй и властвуй»:
— распределяем задачки на части
— каждую часть обрабатываем отдельно и параллельно с другими частями
— объединяем результаты через агрегацию
php работа с большими числами. Смотреть фото php работа с большими числами. Смотреть картинку php работа с большими числами. Картинка про php работа с большими числами. Фото php работа с большими числами

Для PHP можно попытаться решить эту задачу используя очередь типа RabbitMQ и/или Gearman — но придется очень много повозиться для решения исключительных ситуаций, шардинга общей файловой системы, кластеризации на 20 серверов и т.п.

Поэтому если ваша задача может решиться в 30 потоков PHP на одном сервере — перечисленных инструментов, как правило, достаточно. Однако если вам «не повезло» и нужно за час обработать несколько терабайт и железа дают сколько унесешь — выход есть 🙂

Да, да, конечно это Hadoop, реализующий коррелирующую с фото девушек выше парадигму MapReduce 😉

Кому лень читать дальше и хочется узнать рецепт, вот пример исходной задачи и ее решения на Hadoop:

Нужно сжать, зашифровать и перенести 10 млн. файлов из бакета1 s3 в бакет2 s3.
Если делать средствами PHP на сервере, то можно форкануть максимум ну 20-30 потоков PHP, которые будут каждый выполняться в своем процессе. И это займет несколько недель. А объем данных растет и нужно системное решение.
Если то же самое делать средствами Hadoop, то задачу можно выполнить за час, но на большом количестве железок. Если выбрать разумное число железок с 15 потоками на каждой — то можно уложиться в 2 дня.
Т.е. если через полгода число файлов для обработки вырастет с 10 млн. до 50 млн., нужно будет поменять лишь одну циферку в конфиге запуска кластера Hadoop, увеличив число железок лишь.
Разве не красиво и системно? 🙂

Hadoop

Вообще это довольно большой продукт и недельки на 24/7 чтения мануалов наверно не хватит — но этого и не требуется. Мы научимся использовать эту технологию эффективно и быстро, экономя ваше и наше время.

Установка

Помимо установки java-софта потребуется еще настроить кластерную файловую систему. Зачем — а как будут ноды кластера обмениваться общими файлами? Но мы поступим хитрее — запустим кластер Hadoop в Амазоне. Там все уже настроено и установлено.

Подготовка map и reduce скриптов

Вот тут самое интересное в посте. Hadoop позволяет задействовать скрипты на любом языке — и провести сортировку файла на bash или обработку на PHP/Python/Perl.

Скриптики читают из стандартного ввода и пишут в стандартный вывод. Ну что может быть проще?

Скриптиков должно быть 2: mapper, reducer.

Если нужно просто распараллелить задачу на N серверов — достаточно написать один mapper.

Пример mapper

Если агрегированная статистика не нужна, второй скриптик — не нужен. Если нужна, пишем reducer:

Пример reducer
Инициализация серверов кластера

Т.к. скрипты наши на PHP, необходимо подготовить скрипт инициализации, выполняемый на каждом сервере кластера:

Выгружаем скрипты на PHP и bash в облако (s3)
Выгрузка данных для обработки в s3

Просто, например с помощью s3cmd, выгружаем исходные данные для обработки в папку в s3. Эти данные потом расплывутся по кластеру автоматически. Выгрузить можно сколько угодно данных и пусть кластер с ними мучается.

Запуск обработки данных в кластере

И напоследок такая вкусняшка — запускаем кластер для обработки наших данных.

php работа с большими числами. Смотреть фото php работа с большими числами. Смотреть картинку php работа с большими числами. Картинка про php работа с большими числами. Фото php работа с большими числами
Тут важно подобрать правильно число железок для размножения кластера — чем больше, тем конечно быстрее. В данном примере мы устанавливаем не больше 15 процессов на один сервер. Можно больше, это зависит от объема оперативной памяти, но осторожно — следим за ее расходом.

После отработки кластера в логах можно будет увидеть агрегированную статистику, логи также будут выгружены в s3.

Обычно скорость обработки, которая до этого делалась неделями — поражает, вдохновляет и выводит на новый уровень осознания IT-континиума не хуже последней части «300 спартанцев» 🙂
php работа с большими числами. Смотреть фото php работа с большими числами. Смотреть картинку php работа с большими числами. Картинка про php работа с большими числами. Фото php работа с большими числами

Итоги

В результате у вас появляется бизнес-инструмент, управляемый 2 скриптами на PHP. Число серверов (—num-instances 5) напрямую влияет на скорость обработки загруженного массива данных. В принципе никто не запрещает запустить 100 серверов с 10 потоками на каждом и обработать данные значительно быстрее, чем можно было сделать на одном сервере используя очередь заданий.

Используя данную технологию простым и понятным образом, мы на одном из наших проектов сократили время обработки десятков миллионов объектов в s3 с недель до 2 дней.

Коллеги, если есть вопросы, пожалуйста спрашивайте в комментах и посещайте наши конференции — мы с удовольствием поделимся опытом. И всем удачи в реализации веб-проектов и побед над Bigdata!

Источник

Двоичные и побитовые операции в PHP

php работа с большими числами. Смотреть фото php работа с большими числами. Смотреть картинку php работа с большими числами. Картинка про php работа с большими числами. Фото php работа с большими числами

Недавно я обратил внимание, что в разных проектах мне приходится активно писать побитовые операции на PHP. Это очень интересное и полезное умение, которое пригодится начиная с чтения двоичных файлов до эмуляции процессоров.

В PHP есть много инструментов, помогающих манипулировать двоичными данными, но хочу сразу предупредить: если вам нужно супернизкоуровневая эффективность, то этот язык не для вас.

Почему PHP может оказаться не лучшим кандидатом

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

Поясню: я не говорю о том, что приложение может потреблять на пять или десять мегабайт больше, а о выделении конкретного количества памяти для хранения данных определённого типа.

Согласно официальной документации о целых числах, PHP представляет десятичные, шестнадцатеричные, восьмеричные и двоичные значения с помощью целочисленного типа (integer). Так что не имеет значения, какие данные вы туда положите, они всегда будут целочисленными.

Суть вот в чём: не имеет значения, нужно ли вам хранить 0xff, 0xffff, 0xffffff или что-то другое. В PHP все эти значения будут храниться как long (lval) с длиной 32 или 64 бита.

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

Конечно, всё меняется, если мы говорим о С-расширениях или FFI, но это и не входит в мои цели. Я рассказываю о чистом PHP.

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

Быстрое введение в двоичное и шестнадцатеричное представление данных

Прежде чем разговаривать о том, как PHP обрабатывает двоичные данные, нужно сначала поговорить о том, что такое двоичность. Если вы думаете, что уже всё знаете об этом, то переходите к главе Двоичные числа и строки в PHP.

В математике есть понятие «основание». Оно определяет, как мы можем представлять количества в разных форматах. Люди обычно используют десятичное основание (основание 10), что позволяет нам представлять любое число с помощью цифр 0, 1, 2, 3, 4, 5, 6, 7, 8 и 9.

Чтобы пояснить следующий пример, я буду называть число 20 как «десятичное 20».

Двоичные числа (основание 2) могут представлять любое число, но только с помощью двух цифр: 0 и 1.

Десятичное 20 в двоичной форме выглядит так: 0b00010100. Вам не нужно преобразовывать его в привычный вид самостоятельно, пусть это делают компьютеры. 😉

Шестнадцатеричные числа (основание 16) могут представлять любые числа с помощью десяти цифр 0, 1, 2, 3, 4, 5, 6, 7, 8 и 9, а также дополнительных шести символов из латинского алфавита: a, b, c, d, e и f.

Десятичное 20 в шестнадцатеричной форме выглядит так: 0x14. Его преобразование тоже возложите на компьютеры, они в этом эксперты!

Важно понимать, что числа можно представлять по разным основаниям: двоичному (основание 2), восьмеричному (основание 8), десятичному (основание 10, наше обычное) и шестнадцатеричному (основание 16).

В PHP и многих других языках двоичные числа пишутся как и любые другие, но с префиксом 0b: десятичное 20 выглядит как 0b00010100. Шестнадцатеричные числа получают префикс 0x: десятичное 20 выглядит как 0x14.

Как вы уже можете знать, компьютеры не хранят литеральные данные. Они всё представляют в виде двоичных чисел, нулей и единиц. Символы, цифры, буквы, инструкции — всё представлено по основанию 2. Буквы являются лишь условностью числовых последовательностей. Например, буква «a» имеет номер 97 в ASCII-таблице.

Но хотя всё хранится в двоичном виде, программистам удобнее всего читать данные в шестнадцатеричном формате. Они так лучше выглядят. Вы только посмотрите:

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

Операции переноса

Вы уже знакомы с концепцией переноса (carry), но я должен уделить ей внимание, чтобы мы могли использовать её с разными основаниями.

В десятичном наборе у нас есть десять отдельных цифр для представления чисел, от 0 до 9. Но когда мы пытаемся представить числе больше девяти, нам не хватает цифр! И тут применяется операция переноса: мы делаем для числа префикс из цифры 1, а правую цифру сбрасываем в 0.

Двоичное основание ведёт себя так же, только оно ограничено цифрами 0 и 1.

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

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

Представление данных в памяти компьютера

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

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

Представление нашего десятичного 20 в такой таблице с помощью 8 бит выглядит так:

Позиция (адрес)01234567
Бит00010100

Беззнаковое 8-битное целое — это число, которое можно представить максимум с помощью 8 двоичных чисел. То есть 0b11111111 (десятичное 255) будет самым большим среди беззнаковых 8-битных чисел. Добавление к нему 1 потребует применения операции переноса, что уже нельзя представить с помощью того же количества цифр.

Зная это, мы можем легко разобраться, почему для чисел существует так много представлений в памяти и что они собой представляют: uint8 — это беззнаковые 8-битные целочисленные (десятичные 0—255), uint16 — беззнаковые 16-битные целочисленные (десятичные 0—65535). Есть также uint32, uint64 и, теоретически, более высокие.

Знаковые целые числа, которые могут представлять отрицательные значения, обычно используют последний бит для определения положительности (последний бит = 0) или отрицательности (последний бит = 1). Как вы понимаете, они позволяют хранить в том же объёме памяти более маленькие значения. Знаковое 8-битное целочисленное варьируется от —128 до десятичного 127.

Вот десятичное —20, представленное в виде знакового 8-битного целочисленного. Обратите внимание, что задан первый бит (адрес 0, значение 1), это означает отрицательное число.

Позиция (адрес)01234567
Бит10010100

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

Арифметические переполнения

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

Позиция (адрес)01234567
Бит11111110

Здесь мы очень близки к 8-битному пределу (десятичному 255). Если мы добавим единицу, то получим десятичное 255 в двоичном представлении:

Позиция (адрес)01234567
Бит11111111

Все биты назначены! Добавление 1 потребует операции переноса, которая будет невозможна, потому что у нас не хватает битов, все 8 уже назначены! Эта ситуация называется переполнением, мы выходим за какой-то предел. Двоичная операция 255 + 2 должна дать 8-битный результат 1.

Позиция (адрес)01234567
Бит00000001

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

Двоичные числа и строки в PHP

Вернёмся к PHP! Извините за этот большой экскурс, но я считаю его важным.

Надеюсь, у вас в голове уже начали собираться кусочки мозаики: двоичные числа, в каком виде они хранятся, что такое переполнение, как PHP представляет числа…

Десятичное 20, представленное в PHP в виде целочисленного значения, в зависимости от платформы может иметь два разных представления. На х86-платформе это будет 32-битное представление, на х64 — 64-битное, но в обоих случаях будет стоять знак (то есть значение может быть отрицательным). Мы знаем, что десятичное 20 может поместиться в 8-битное пространство, но PHP обращается с любым десятичным числом как с 32- или 64-битным.

Также в PHP есть двоичные строки, которые можно преобразовывать туда-обратно с помощью функций pack() и unpack().

В PHP главное отличие между двоичными строками и числами в том, что строки просто содержат данные, как буфер. Целочисленные значения (двоичные и не только) позволяют выполнять с собой арифметические операции, но и двоичные (побитовые), такие как AND, OR, XOR и NOT.

Двоичность: что использовать в PHP, числа или строки?

Для транспортировки данных мы обычно используем двоичные строки. Поэтому чтение двоичного файла или сетевое взаимодействие требует упаковки и распаковки двоичных строк.

Однако фактические операции, такие как OR и XOR, со строковыми не получится выполнять надёжно, поэтому нужно использовать числа.

Отладка двоичных значений в PHP

Теперь давайте развлечёмся и немного поиграем с PHP-кодом!

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

Отлаживать целые числа очень-очень просто, мы можем использовать функцию sprintf(). У неё очень мощное форматирование, и она поможет нам быстро понять, с какими значениями мы работаем.

Давайте представим десятичное 20 в 8-битном двоичном формате и в 1-байтном шестнадцатеричном:

Визуализация двоичных строк

Хотя в PHP целые числа всегда длиной 32 или 64 бита, длина строк равна длине их содержимого. Чтобы декодировать их двоичные значения и визуализировать их, нам нужно исследовать и преобразовать каждый байт.

К счастью, в PHP строки не являются именоваными, как массивы, и каждая позиция указывает на символ размером в 1 байт. Вот пример обращения к символам:

Если считать, что один символ занимает 1 байт, мы можем вызвать функцию ord() для приведения к 1-байтному целому числу:

Теперь можно выполнить двойную проверку с помощью приложения для командной строки hexdump:

Также при обработке двоичных строк мы можем использовать функции pack() и unpack(), и у меня есть для вас отличный пример! Допустим, вам нужно прочитать JPEG-файл, чтобы извлечь какие-нибудь данные (например, EXIF). С помощью режима чтения двоичных данных можно открыть обработчик файла и сразу же прочитать первые два байта:

Чтобы извлечь значения в целочисленный массив, можно просто распаковать их:

Побитовые операции

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

Я объясню работу каждого из них!

Как работает NOT (

Операции NOT требуется один параметр, она просто меняет значения всех переданных битов. Все 0 она превращает в 1, а все 1 — в 0.:

То же самое со смещением вправо:

Что такое битовая маска

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

Такое часто бывает нужно при работе с флагами. Можно даже найти примеры использования в самом PHP, например, флаги сообщения об ошибках.

Можно выбрать, какого рода ошибки будут выдаваться:

Что здесь происходит? Просто посмотрите на своё значение:

Когда PHP видит уведомление, которое можно передать, он проверяет нечто подобное:

И вы увидите это везде! Двоичные файлы, процессоры, всякие низкоуровневые вещи!

Нормализация чисел

В PHP есть одна особенность, связанная с обработкой двоичных чисел: целые числа имеют размер 32 или 64 бита. Это означает, что зачастую нам нужно нормализовать их, чтобы доверять своим вычислениям.

Например, исполнение этой операции на 64-битной машине даст странный (но ожидаемый) результат:

Что тут произошло? Операция NOT в 8-битном целом числе ( 0x20 ) превратила все нулевые биты в единицы. Угадайте, что у нас было нулями? Правильно, все остальные 56 битов слева, которые до этого игнорировались!

Повторюсь, причина в том, что в PHP длина целых чисел составляет 32 или 64 бита, вне зависимости от их значений!

Однако код работает ожидаемо. Например, результатом операции

0x20 & 0b11011111 === 0b11011111 будет булево значение (true). Но не забывайте, что эти биты слева никуда не деваются, иначе вы получите странное поведение кода.

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

0x20 в 8-битное целое число нужно применить AND с 0xFF ( 0b11111111 ), чтобы все предыдущие 56 битов превратились в нули.

Внимание! Не забывайте о том, что содержится в ваших переменных, иначе получите неожиданное поведение. Например, давайте взглянем, что произойдёт, когда мы смещаем вышеописанное значение вправо без 8-битной маски:

Поясню: с точки зрения PHP это является ожидаемым, потому что вы явно обрабатываете 64-битное число. Вы должны понимать, что ожидает ВАША программа.

Совет: избегайте подобных глупых ошибок, программируя в парадигме TDD.

Заключение: двоичность и PHP классные

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

Очень рекомендую почитать спецификации PDF или EXIF. Возможно, вы даже захотите поэкспериментировать с собственной реализацией формата сериализации MessagePack, или Avro, Protobuf… Возможности безграничны!

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *