1. Си / Говнокод #5997

    +105

    1. 1
    int c = ((i-(i%(int)pow(10,p)))/(int)pow(10,p))%10;

    Выделение из числа I цифры, стоящей на месте P с конца.
    =>
    i = 1234, p = 2, c => 2

    Запостил: danilissimus, 16 Марта 2011

    Комментарии (24) RSS

    • (i-i%j)/j вместо просто i/j
      Вычитать остаток перед делением...
      Автор не тот же, который обнуляет биты перед сдвигом?
      Ответить
      • а это какой?
        Ответить
      • он сомневался, что результат будет целым
        Ответить
        • показать все, что скрытоЭто всё из-за того, что Си опасный и непродуманный язык, позволяющий в одном выражении использовать как целые, так и вещественные числа.
          Ответить
          • >позволяющий
            а касты там просто так чтоли стоят?
            Ответить
          • он еще хуже - он позволяет приводить вещественные числа к целым, с потерей точности! :}
            Ответить
            • в данном конкретном случае потери нет: число вида double(1000.0) к числу вида int(1000).
              Ответить
              • к 999

                даже в паскале так можно :-P
                Ответить
                • Вруша!
                  #include <stdio.h>
                  
                  int main(int argc, char**argv) {
                      double d = 1000.0;
                      printf("%i\n", (int) d);
                      
                      return 0;
                  }

                  1000
                  Ответить
                • #include <cstdio>
                  #include <cmath>
                  
                  int main() {
                          for(int i = 0; i < 19; ++i) {
                                  double p = pow(10, i);
                                  printf("Float: %lld; ", (unsigned long long)(float)p);
                                  printf("Double: %lld\n", (unsigned long long)(double)p);
                          }
                  }


                  Float: 1; Double: 1
                  Float: 10; Double: 10
                  Float: 100; Double: 100
                  Float: 1000; Double: 1000
                  Float: 10000; Double: 10000
                  Float: 100000; Double: 100000
                  Float: 1000000; Double: 1000000
                  Float: 10000000; Double: 10000000
                  Float: 100000000; Double: 100000000
                  Float: 1000000000; Double: 1000000000
                  Float: 10000000000; Double: 10000000000
                  Float: 99999997952; Double: 100000000000
                  Float: 999999995904; Double: 1000000000000
                  Float: 9999999827968; Double: 10000000000000
                  Float: 100000000376832; Double: 100000000000000
                  Float: 999999986991104; Double: 1000000000000000
                  Float: 10000000272564224; Double: 10000000000000000
                  Float: 99999998430674944; Double: 100000000000000000
                  Float: 999999984306749440; Double: 1000000000000000000

                  Таким образом если мы используем double и кастуем 64битные числа вида pow(10, i) то всё будет ОК.
                  Но в общем случае (при использовании float, или при использовании бОльших чисел могут быть фэйлы).
                  Ответить
              • А что значит "число вида"? Что такое "вид" в данном случае?

                Напомню, что будет ли целое число представлено точно в формате типа `double` зависит от ширины мантиссы двоичного представления данного числа. Если это представление помещается в мантиссу `double`- то все в порядке, а если нет - то представление будет неточным. С `1000.0` все хорошо. А вот с бОльшими числами, пусть даже "круглыми" с десятичной точки зрения, могут возникнуть проблемы. Я не проверял, на каком значении вида `10...0.0` они возникнут, т.е. может быть тут в этом плане все порядке (для разумных значений индекса `p` в случае, скажем, 64-битного `int`). Но тем не менее...
                Ответить
          • в паскале нельзя умножить целое на вещественное ?
            Ответить
            • Разумеется! Ну какие вещества в паскале…
              Ответить
              • Сейчас приидет Тарас Б, и скажет "своё копирайтное" КАКОГО ХУЯ?
                Ответить
                • Длинного и гордо свисающего заместо галстука...
                  Ответить
            • В Паскале ещё можно.
              А в Аде уже запрещено.
              Ответить
              • А в Рае?
                Ответить
              • А как же :
                function "*" (Left : Float; Right : Integer ) return Float;
                ?
                Ответить
                • А, ну если определишь, то будет можно. А вообще принудительно приводить надо либо к целому, либо к вещественному. Удобно, что не делается неявного приведения, причём не факт, что к нужному в данной сситуации типу.
                  Ответить
    • Смущённый парень робко подошёл. Он столько сейчас наговорил всего, что уже опасался, как бы ему и правда не добавили. Задница и так болит!
      Ответить

    Добавить комментарий