Предупреждающее сообщение «Подразделение на ноль» является одним из наиболее часто задаваемых вопросов среди новых разработчиков PHP. Эта ошибка не вызовет исключения, поэтому некоторые разработчики будут иногда подавлять предупреждение, добавляя оператор подавления ошибок @ перед выражением. Например:
$value = @(2 / 0);
Но, как и при любом предупреждении, наилучшим подходом было бы отслеживать причину предупреждения и разрешать его. Причина предупреждения будет происходить из любого экземпляра, где вы пытаетесь разделить на 0, переменную, равную 0, или переменную, которая не была назначена (поскольку NULL == 0), потому что результат будет «неопределенным».
Чтобы исправить это предупреждение, вы должны переписать свое выражение, чтобы проверить, что значение не равно 0, если оно есть, сделать что-то еще. Если значение равно нулю, вы не должны делиться или изменять значение на 1, а затем делить так, что деление приводит к эквиваленту того, что он разделен только дополнительной переменной.
if ( $var1 == 0 ) { // check if var1 equals zero
$var1 = 1; // var1 equaled zero so change var1 to equal one instead
$var3 = ($var2 / $var1); // divide var1/var2 ie. 1/1
} else {
$var3 = ($var2 / $var1); // if var1 does not equal zero, divide
}
Вопросы, относящиеся:
Как насчет
if ((bool1? 1:0) + (bool2? 1:0) + (bool3? 1:0) +
(bool4? 1:0) + (bool5? 1:0) > 1)
// do something
или обобщенный метод был бы...
public bool ExceedsThreshold(int threshold, IEnumerable<bool> bools)
{
int trueCnt = 0;
foreach(bool b in bools)
if (b && (++trueCnt > threshold))
return true;
return false;
}
или использующий LINQ, как предложено другими ответами:
public bool ExceedsThreshold(int threshold, IEnumerable<bool> bools)
{ return bools.Count(b => b) > threshold; }
РЕДАКТИРОВАНИЕ (для добавления предложения Joel Coehoorn: (в.Net 2.x и позже)
public void ExceedsThreshold<T>(int threshold,
Action<T> action, T parameter,
IEnumerable<bool> bools)
{ if (ExceedsThreshold(threshold, bools)) action(parameter); }
или в.Net 3.5 и позже:
public void ExceedsThreshold(int threshold,
Action action, IEnumerable<bool> bools)
{ if (ExceedsThreshold(threshold, bools)) action(); }
или как расширение IEnumerable<bool>
public static class IEnumerableExtensions
{
public static bool ExceedsThreshold<T>
(this IEnumerable<bool> bools, int threshold)
{ return bools.Count(b => b) > threshold; }
}
использование тогда было бы:
var bools = new [] {true, true, false, false, false, false, true};
if (bools.ExceedsThreshold(3))
// code to execute ...
Вы упомянули
, Одна интересная опция состоит в том, чтобы сохранить булевские переменные в байте, сделать сдвиг вправо и соответствовать исходному байту. Что-то как
if (myByte && (myByte >> 1))
я не думаю, что выражение даст Вам результат, который Вы хотите (по крайней мере, использующий C семантика, так как выражение не является допустимым C#):
, Если (myByte == 0x08)
, то выражение возвратит true даже при том, что существует только один набор битов.
, Если Вы имели в виду" if (myByte & (myByte >> 1))
" тогда, если (myByte == 0x0a)
выражение возвратит false даже при том, что существует набор на 2 бита.
, Но вот некоторые методы для подсчета числа битов, одним словом:
Взломы Битового жонглирования - подсчет битов
изменение А, которое Вы могли бы рассмотреть, должно использовать метод подсчета Kernighan, но прыгнуть с парашютом рано, так как только необходимо знать, существует ли больше чем один набор битов:
int moreThanOneBitSet( unsigned int v)
{
unsigned int c; // c accumulates the total bits set in v
for (c = 0; v && (c <= 1); c++)
{
v &= v - 1; // clear the least significant bit set
}
return (c > 1);
}
, Конечно, с помощью таблицы поиска не плохая опция также.
если ((b1. CompareTo (ложь) + b2. CompareTo (ложь) + b3. CompareTo (ложь) +...),> 1)
//больше чем один из них верен
...
еще
...
Если у Вас только есть пять различных значений, можно легко сделать тест путем упаковки битов в к короткому или интервалу и проверки, чтобы видеть, является ли это какой-либо из нулевых или ответов на один бит. Единственные неверные номера, которые Вы могли получить, будут..
0x 0000 0000 0x 0000 0001 0x 0000 0010 0x 0000 0100 0x 0000 1000 0x 0001 0000
Это дает Вам шесть значений, чтобы искать, поместить их в таблицу поиска и если это не там, у Вас есть свой ответ.
Это дает Вам простой ответ.
public static boolean moreThan1BitSet(int b) { final short multiBitLookup[] = { 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; if(multiBitLookup[b] == 1) return false; return true; }
Это не масштабирует хорошо прошлые 8 битов, но Вы только имеете пять.
На большинстве верных языков эквивалентно ненулевому значению, в то время как ложь является нулем. У меня нет точного синтаксиса для Вас, но в псевдо коде, что относительно:
if ((bool1 * 1) + (bool2 * 1) + (bool3 * 1) > 2)
{
//statements here
}
У меня есть намного намного лучший теперь и очень короткий!
bool[] bools = { b1, b2, b3, b4, b5 };
if (bools.Where(x => x).Count() > 1)
{
//do stuff
}
Не точно довольно..., но вот другой способ сделать это:
if (
(a && (b || c || d || e)) ||
(b && (c || d || e)) ||
(c && (d || e)) ||
(d && e)
)
if (NumberOfTrue(new List<bool> { bool1, bool2, bool3, bool4 }) >= 2)
{
// do stuff
}
int NumberOfTrue(IEnumerable<bool> bools)
{
return bools.Count(b => b);
}
Я сделал бы что-то вроде этого, с помощью аргумента параметрических усилителей.
public void YourFunction()
{
if(AtLeast2AreTrue(b1, b2, b3, b4, b5))
{
// do stuff
}
}
private bool AtLeast2AreTrue(params bool[] values)
{
int trueCount = 0;
for(int index = 0; index < values.Length || trueCount >= 2; index++)
{
if(values[index])
trueCount++;
}
return trueCount > 2;
}
Бросок к ints и подведение итогов должны работать, но это немного ужасно, и на некоторых языках может не быть возможным.
Как насчет чего-то как
int count = (bool1? 1:0) + (bool2? 1:0) + (bool3? 1:0) + (bool4? 1:0) + (bool5? 1:0);
Или если Вы не заботитесь о пространстве, Вы могли бы просто предварительно вычислить таблицу истинности и использовать bools в качестве индексов:
if (morethanone[bool1][bool2][bool3][bool4][bool5]) {
... do something ...
}
В то время как мне нравится LINQ, существуют некоторые дыры в нем, как эта проблема.
Проведение подсчета прекрасно в целом, но может стать проблемой, когда объекты Ваш подсчет требуют времени для вычисления/получения.
Любой () дополнительный метод прекрасен, если Вы просто хотите проверить на кого-либо, но если Вы хотите проверить на, по крайней мере, существует не создано в функции, которая сделает это и будет ленива.
В конце, я записал функцию для возвращения true, если существует, по крайней мере, определенное число объектов в списке.
public static bool AtLeast<T>(this IEnumerable<T> source, int number)
{
if (source == null)
throw new ArgumentNullException("source");
int count = 0;
using (IEnumerator<T> data = source.GetEnumerator())
while (count < number && data.MoveNext())
{
count++;
}
return count == number;
}
Для использования:
var query = bools.Where(b => b).AtLeast(2);
Это обладает преимуществом не необходимости оценить все объекты прежде, чем возвратить результат.
[Разъем] Мой проект, NExtension содержит AtLeast, AtMost и переопределения, которые позволяют, Вы для смешивания в предикате с По крайней мере/Больше всего проверяете. [/Разъем]
от вершины моей головы, быстрого подхода для этого определенного примера; Вы могли преобразовать bool в интервал (0 или 1). тогда цикл через терм и складывает их. если результат> = 2 тогда можно выполнить функцию.
если Вы имеете в виду больше чем или равный одной булевской переменной, равняется истинному, Вы могли бы сделать это как
if (bool1 || bool2 || bool3 || bool4 || bool5)
при необходимости в больше чем одном (2 и выше) булевские переменные, равные истинному можно попробовать
int counter = 0;
if (bool1) counter++;
if (bool2) counter++;
if (bool3) counter++;
if (bool4) counter++;
if (bool5) counter++;
if (counter >= 2) //More than 1 boolean is true
Короче и более ужасный, чем версия Vilx-s:
if (((a||b||c)&&(d||e))||((a||d)&&(b||c||e))||(b&&c)) {}
Я записал бы функцию для получения любого количества булевых значений. Это возвратило бы количество тех значений, которые верны. Проверьте результат на количество значений, необходимо быть положительны сделать что-то.
Работают усерднее для прояснения, не умный!
private int CountTrues( params bool[] booleans )
{
int result = 0;
foreach ( bool b in booleans )
{
if ( b ) result++;
}
return result;
}
Я просто бросил бы их к ints и сумме.
, Если Вы не находитесь в супер трудном внутреннем цикле, который обладает преимуществом того, чтобы быть легким понять.
Время для обязательного ответа LINQ, который в этом случае на самом деле довольно аккуратен.
var bools = new[] { true, true, false, false, false };
return bools.Count(b => b == true) > 1;
Я собирался записать версию Linq, но приблизительно пять человек побеждают меня к ней. Но мне действительно нравится, когда подход параметрических усилителей избегает необходимости вручную новый массив. Таким образом, я думаю, что лучший гибрид, на основе ответа армированного пластика с заменой тела очевидным Linqness:
public static int Truth(params bool[] booleans)
{
return booleans.Count(b => b);
}
Красиво ясный читать и использовать:
if (Truth(m, n, o, p, q) > 2)
Если были миллионов вместо 5, вы можете избежать Count () и сделать это вместо этого ...
public static bool MoreThanOne (IEnumerable<bool> booleans)
{
return booleans.SkipWhile(b => !b).Skip(1).Any(b => b);
}