# V3157. Suspicious division. Absolute value of the left operand is less than the right operand.

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

Результаты таких операций:

- для деления результатом будет 0;
- для взятия остатка от деления результатом будет левый операнд.

Скорее всего, такое выражение содержит ошибку или является избыточным.

Рассмотрим синтетический пример:

    public void Method()
    {
      int a = 10;
      int b = 20;
      var c = a / b;
      ....
    }

В данном примере результатом выражения 'a / b' всегда будет 0, так как 'a < b'. В этом случае необходимо преобразовать тип переменной 'a' для выполнения вещественного деления:

    public void Method()
    {
      int a = 10;
      int b = 20;
      var c = (double)a / b;
      ....
    }

Теперь рассмотрим реальный пример:

    public override Shipper CreateInstance(int i)
    {
      ....
      return new Shipper
      {
        ....
        DateCreated = new DateTime(i + 1 % 3000, // <=
                                   (i % 11) + 1,
                                   (i % 27) + 1,
                                   0,
                                   0,
                                   0,
                                   DateTimeKind.Utc),
        ....
      };
    }

Здесь допущена ошибка в приоритете операций. В выражении 'i + 1 % 3000' первым делом вычисляется выражение '1 % 3000', результатом которого всегда будет 1. Следовательно, 'i' всегда складывается с 1. Исправленный вариант может выглядеть следующим образом:

    public override Shipper CreateInstance(int i)
    {
      ....
      return new Shipper
      {
        ....
        DateCreated = new DateTime((i + 1) % 3000, // <=
                                   (i % 11) + 1,
                                   (i % 27) + 1,
                                   0,
                                   0,
                                   0,
                                   DateTimeKind.Utc),
        ....
      };
    }

Рассмотрим еще один реальный пример:

    private void ValidateMultiRecords(StorageEnvironment env,
                                      IEnumerable<string> trees,
                                      int documentCount,
                                      int i)
    {
      for (var j = 0; j < 10; j++)
      {
        foreach (var treeName in trees)
        {
          var tree = tx.CreateTree(treeName);
          using (var iterator = tree.MultiRead((j % 10).ToString())) // <=
          {
            ....
          }
        }
      }
    }

В данном примере переменная 'j' изменяется в пределах [0..9]. Получается, что выражение 'j % 10' всегда будет равно 'j'. Упрощенный вариант может выглядеть следующим образом:

    private void ValidateMultiRecords(StorageEnvironment env,
                                      IEnumerable<string> trees,
                                      int documentCount,
                                      int i)
    {
      for (var j = 0; j < 10; j++)
      {
        foreach (var treeName in trees)
        {
          var tree = tx.CreateTree(treeName);
          using (var iterator = tree.MultiRead(j.ToString())) // <=
          {
            ....
          }
        }
      }
    }

Данная диагностика классифицируется как:

CWE-682

Взгляните на примеры ошибок, обнаруженных с помощью диагностики V3157.