суббота, 14 февраля 2009 г.

Short circuit (сокращенное вычисление булевых выражений)

Многие знают о сокращенном вычислении булевых выражений, которые существуют в C, С++, C#, Java и других языках программирования. Имеется ввиду такая ситуация: 1. if ( firstCondition || secondCondition) 2. If (firstCondition && secondCondition ) В первом случае, если вычисление первого выражения даст true, то второе выражение не будет вычислено вообще. Во втором случае ситация аналогична: если вычисление первого выражение дает false, то результатом всего выражения в любом случае будет false, поэтому второе выражение вычислять не обязательно. Таким образом данные операторы не являются коммутатитвными, поскольку результат выражения A && B может быть определен, в то время, как результат выражения B && A, может быть неопределенным. Простой пример отсутствия коммутативности следующий: 1. if ( i != 0 && k/i > 10 ) 2. if ( k/i > 10 && i != 0 ) Эти два выражения не являются эквивалентными, т.к. во втором случае возможно деление на 0. Данное поведение противоречит теории, с той точки зрения, что стандартные математические булевы операторы являются комутативными. Т.е. а and b всегда имеет тоже значение, что и b and a, в то время как a && b не всегда имеет тоже значение, что и b && a. Но, вероятно, не многие знают, что во всех этих языках можно несколько "обойти" поведение по умолчанию и добиться коммутативности выполнения булевых операций. Для этого необходимо воспользоваться битовыми операциями. 1. if ( firstCondition & secondCondition ) 2. if ( firstCondition | secondCondition ) В этом случае все условные выражения будут вычисляться всегда, тем самым получая коммутативность булевых операторов. "Белой вороной" (как и во многих других вопросах) выглядит язык программирования Eiffel. В этом языке программирования основные булевы операторы and и or являются "строгими" (коммутативными). Их поведение совпадает с поведением битовых операторов | и &. При этом есть дополнительные булевы операторы and then и or else, которые ведут себя аналогично булевым операторам языков семейства С.

2 комментария:

  1. Круто! Я действительно этого не знал. Пасиба, Серега!
    Единственная проблема использования битовых операций для этих целей состоит в том, что человек, который будет читать или поддерживать этот код скорее всего тоже не будет знать этого нюанса

    ОтветитьУдалить
  2. Это точно. Помнишь, у нас Женя работал?
    Так вот он использовал битовые операции вместо логически, абсолютно не понимая различий между ними:)

    ОтветитьУдалить