Блог пользователя difask

Автор difask, 10 лет назад, перевод, По-русски

Всем привет! Несколько дней назад я узнал об одной очень крутой фишке в С++. Многие кфщики используют макрос "#define INF 100000007". Вместо этого можно просто писать INFINITY и это будет работать как максимальное число в текущем типе. Например:

  1. ll ans = INFINITY; //long_long_max

  2. if (smth < INFINITY) //int_max by default

  3. if (smth < (long long)INFINITY) //long_long_max

Я не видел это в кодах. Возможно кому-то это будет интересно и он начнет это использовать

  • Проголосовать: нравится
  • +35
  • Проголосовать: не нравится

»
10 лет назад, # |
  Проголосовать: нравится +34 Проголосовать: не нравится

Одна проблема: иногда мы хотим прибавить что-нибудь к бесконечности и потом сравнить эту сумму с чем-то. А если я прибавлю 1 к int_max, я явно получу что-то нехорошее. Поэтому в этом плане взять в роли бесконечности что-то типа 1e9 — выгодный вариант.

  • »
    »
    10 лет назад, # ^ |
      Проголосовать: нравится -15 Проголосовать: не нравится

    Согласен, для таких случаев это не подходит. Но мне почему то не приходит в голову ни одного варианта когда нужно к бесконечности что-то прибавлять. Можете привести пример?

    • »
      »
      »
      10 лет назад, # ^ |
        Проголосовать: нравится +47 Проголосовать: не нравится
      for (int k=0;k<n;k++)
       for (int i=0;i<n;i++)
        for (int j=0;j<n;j++)
         dist[i][j]=min(dist[i][j],dist[i][k]+dist[k][j]);
      
      • »
        »
        »
        »
        10 лет назад, # ^ |
        Rev. 2   Проголосовать: нравится -27 Проголосовать: не нравится

        Согласен. Для такой реализации Флойда это не подходит. Но все-таки можно писать так:

        for (int k=0; k<n; ++k)
         for (int i=0; i<n; ++i)
          for (int j=0; j<n; ++j)
           if (d[i][k] < INFINITY && d[k][j] < INFINITY)
            d[i][j] = min (d[i][j], d[i][k] + d[k][j]);
        

        Хотя я согласен это дольше и иногда проще написать свой INF.

        • »
          »
          »
          »
          »
          10 лет назад, # ^ |
            Проголосовать: нравится 0 Проголосовать: не нравится

          Не понимаю, за что меня минусуют)

          • »
            »
            »
            »
            »
            »
            10 лет назад, # ^ |
              Проголосовать: нравится 0 Проголосовать: не нравится

            Ваша поправка ничего не меняет int x = INFINITY;// x < INFINITY

            • »
              »
              »
              »
              »
              »
              »
              5 лет назад, # ^ |
                Проголосовать: нравится -19 Проголосовать: не нравится

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

»
10 лет назад, # |
Rev. 3   Проголосовать: нравится +14 Проголосовать: не нравится

It's not so useful. For example long long answer = INFINITY; if (answer == INFINITY) // answer != INFINITY

  • »
    »
    10 лет назад, # ^ |
      Проголосовать: нравится +2 Проголосовать: не нравится

    Yes, in this case it will not work. But it is possible to write

     if (answer == (ll)INFINITY)
    

    And it will work correctly.

»
10 лет назад, # |
Rev. 2   Проголосовать: нравится +22 Проголосовать: не нравится

That is not really useful because you usually want to have INFINITY/2 and not INFINITY itself, since any addition will overflow type. In other words you really don't want inequalities INF+5<INF to be correct.

»
10 лет назад, # |
  Проголосовать: нравится +6 Проголосовать: не нравится

I use (1 << 30) for int. And (1ll << 60) for long long type.

»
10 лет назад, # |
  Проголосовать: нравится +5 Проголосовать: не нравится

As Shtrix stated too , it's not really useful because you simply can not do any addition to the value correctly , but if you insist on using this , I'd choose the safer way :

    int minn = numeric_limits<int>::max()/4;
    long long maxx = numeric_limits<long long>::min()/4 ;