Недостаточно памяти для запуска вашего скрипта. PHP достиг предела памяти и перестает его выполнять. Эта ошибка является фатальной, сценарий останавливается. Значение предела памяти можно настроить либо в файле php.ini
, либо с помощью ini_set('memory_limit', '128 M');
в скрипте (который перезапишет значение, определенное в php.ini
). Цель ограничения памяти заключается в том, чтобы не допустить, чтобы один скрипт PHP собирал всю доступную память и приводил к остановке всего веб-сервера.
Первое, что нужно сделать, это свести к минимуму объем памяти, необходимый вашему сценарию , Например, если вы читаете большой файл в переменной или извлекаете много записей из базы данных и сохраняете их все в массиве, которые могут использовать много памяти. Измените свой код, чтобы вместо этого читать строки по строке или извлекать записи базы данных по одному, не сохраняя их все в памяти. Это требует немного концептуального понимания того, что происходит за кулисами, и когда данные хранятся в памяти и в других местах.
Если эта ошибка возникла, когда ваш сценарий не выполнял интенсивную работу с памятью, вы вам нужно проверить свой код, чтобы узнать, есть ли утечка памяти. Функция memory_get_usage
является вашим другом.
Вопросы, относящиеся:
В C, с побитовыми операторами:
#include<stdio.h>
int add(int x, int y) {
int a, b;
do {
a = x & y;
b = x ^ y;
x = a << 1;
y = b;
} while (a);
return b;
}
int main( void ){
printf( "2 + 3 = %d", add(2,3));
return 0;
}
XOR (x ^ y
) является дополнением без переноса. (x & y)
еда на вынос от каждого бита. (x & y) << 1
перенос - в к каждому биту.
цикл продолжает добавлять переносы, пока перенос не является нулем для всех битов.
Добавление двух целых чисел не является настолько трудным; существует много примеров сложения в двоичной системе онлайн.
А более сложной проблемой являются числа с плавающей точкой! Существует пример в http://pages.cs.wisc.edu/~smoler/x86text/lect.notes/arith.flpt.html
Причина ADD реализован в ассемблере как единственная инструкция, а не как некоторая комбинация битовых операций, состоит в том, что трудно сделать. Необходимо волноваться о переносах от данного бита низкоуровневого до следующего бита высшего порядка. Это - материал, который машины делают в аппаратных средствах быстро, но что даже с C, Вы не можете сделать в программном обеспечении быстро.
Почему не только увеличивают первое число так же часто, как второе число?
Отметьте, это было бы для сумматора, известного как сумматор со сквозным переносом , который работает, но не работает оптимально. Большинство двоичных сумматоров, встроенных в аппаратные средства, является формой быстрого сумматора такой как сумматор с ускоренным переносом .
Мой сумматор со сквозным переносом работает и на неподписанный и на 2's дополнительные целые числа при установке carry_in на 0, и 1's дополнительные целые числа, если carry_in установлен на 1. Я также добавил флаги для проявления потери значимости или переполнения на дополнении.
#define BIT_LEN 32
#define ADD_OK 0
#define ADD_UNDERFLOW 1
#define ADD_OVERFLOW 2
int ripple_add(int a, int b, char carry_in, char* flags) {
int result = 0;
int current_bit_position = 0;
char a_bit = 0, b_bit = 0, result_bit = 0;
while ((a || b) && current_bit_position < BIT_LEN) {
a_bit = a & 1;
b_bit = b & 1;
result_bit = (a_bit ^ b_bit ^ carry_in);
result |= result_bit << current_bit_position++;
carry_in = (a_bit & b_bit) | (a_bit & carry_in) | (b_bit & carry_in);
a >>= 1;
b >>= 1;
}
if (current_bit_position < BIT_LEN) {
*flags = ADD_OK;
}
else if (a_bit & b_bit & ~result_bit) {
*flags = ADD_UNDERFLOW;
}
else if (~a_bit & ~b_bit & result_bit) {
*flags = ADD_OVERFLOW;
}
else {
*flags = ADD_OK;
}
return result;
}
Обман. Вы могли инвертировать число и вычесть его сначала:)
Сбой, что, ищите, как работает двоичный сумматор.:)
РЕДАКТИРОВАНИЕ: А-ч, видел Ваш комментарий после того, как я отправил.
Детали сложения в двоичной системе здесь .
Определите "лучше всего". Вот версия Python:
len(range(x)+range(y))
Эти +
выполняет конкатенацию списка, не дополнение.
Нет + право?
int add(int a, int b)
{
return -(-a) - (-b);
}
int add(int a, int b) {
const char *c=0;
return &(&c[a])[b];
}
Пойдите базирующееся решение
func add(a int, b int) int {
for {
carry := (a & b) << 1
a = a ^ b
b = carry
if b == 0 {
break
}
}
return a
}
, то же решение может быть реализовано в Python следующим образом, но существует некоторая проблема о числе, представляют в Python, Python имеет больше чем 32 бита для целых чисел. таким образом, мы будем использовать маску для получения последних 32 битов.
, Например: если мы не будем использовать маску, то мы не получим результат для номеров (-1,1)
def add(a,b):
mask = 0xffffffff
while b & mask:
carry = a & b
a = a ^ b
b = carry << 1
return (a & mask) if b > mask else a
Функция add() в CMS прекрасна. Она не должна быть запятнана унарным отрицанием (небитовая операция, равносильная использованию сложения: -y==(~y)+1). Вот функция вычитания, использующая ту же битовую конструкцию:
int sub(int x, int y) {
unsigned a, b;
do {
a = ~x & y;
b = x ^ y;
x = b;
y = a << 1;
} while (a);
return b;
}