Няшная / Говнокод #23862 Ссылка на оригинал

0

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14
  15. 15
  16. 16
  17. 17
  18. 18
  19. 19
  20. 20
  21. 21
  22. 22
  23. 23
  24. 24
  25. 25
  26. 26
  27. 27
  28. 28
  29. 29
  30. 30
  31. 31
  32. 32
  33. 33
  34. 34
  35. 35
  36. 36
  37. 37
// https://github.com/Samsung/ADBI/blob/3e424c45386b0a36c57211da819021cb1929775a/idk/include/division.h#L138

/* Long division by 10. */
static unsigned long long int div10l(unsigned long long int v) {

    /* It's a kind of magic.  We achieve 64-bit (long) division by dividing the two 32-bit halfs of the number 64-bit
     * number.  The first (most significant) half can produce a rest when dividing, which has to be carried over to the
     * second half.  The rest_add table contains values added to the second half after dividing depending on the rest
     * from the first division.  This allows evaluation of a result which is almost correct -- it can be either the
     * expected result, or the expected result plus one.  The error can be easily detected and corrected.
     */
    
    /* one dream */
    static unsigned long long int rest_add[] = {
        0x00000000, 0x1999999a, 0x33333334, 0x4ccccccd, 0x66666667,
        0x80000001, 0x9999999a, 0xb3333334, 0xcccccccd, 0xe6666667
    };
    
    /* one soul */
    unsigned long long int a = div10((unsigned int)(v >> 32));
    unsigned long long int b = div10((unsigned int)(v & 0xffffffff));
    
    /* one prize */
    int ri = (v >> 32) - a * 10;
    
    /* one goal */
    unsigned long long int ret = (a << 32) + b + rest_add[ri];
    
    /* one golden glance */
    if (ret * 10L > v) {
        //printf("OGG %llu %llu\n", ret * 10, v);
        --ret;
    }
    
    /* of what should be */
    return ret;
}

Деление на 10. Но зачем? Неужели компилятор настолько туп, что сам не может этого сделать?
И да, эти туповатые комментарии one dream, one soul это отсылка к песне Queen - A Kind of Magic https://youtu.be/0p_1QSUsbsM

Запостил: j123123 j123123, (Updated )

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

    • Это даже не битоёбство толком.
      Просто разбили 64-битное деление на 2 32-битных.
      >a = div10((unsigned int)(v >> 32));
      >b = div10((unsigned int)(v & 0xffffffff));

      Дистрибутивность для пятиклассников.
      (hi+lo)/10 = hi/10+lo/10;

      Вот интересенее div10 посмотреть. Там наверняка умножение на "магию".
      Ответить
  • Хуева туча кода, и это должно быть быстрее, чем деление на 10?
    Ответить
    • Походу это особое деление на 10 для uint64_t для процессоров, в которых 64-битных регистров тупо нет. Т.е. тупо нет инструкции "поделить какое-то 64-битное число на что-то" и приходится извращаться подобным образром. https://godbolt.org/g/4WCQse - вон компилятор GCC тоже какой-то __udivdi3 вызывает, если с флагом -m32 надо делить 64-битный unsigned int на 10. Это все в libgcc должно быть, и у clang тоже должна быть подобная хрень.

      И да этот __udivdi3 является более общим случаем(т.е. делить можно не только на 10, а на любую фигню), а в этом говнокоде особая заточенная реализация для деления именно на 10
      Ответить
      • Давай, давай, а ну, давай,
        Меня шмонай ты, вертухай,
        Да загляни под юбочку,
        Да посмотри на булочки.
        Понюхай попку носиком,
        Прикинься, киса, пёсиком,
        Вот в этом вся и разница,
        Кто хочет, а кто дразнится.

        ©Любимая группа мамки админа
        Ответить
      • >ARM processors don't have hardware support for division.

        Там деления вообще нет.
        Но тут дело в том что gcc/clang давным-давно научились вычислять "магические числа" при компиляции, и заменять деление на умножение + сдвиг.

        Даже жабовский hotspot лет 5 назад научился оптимизировать деление на константы. Потому непонятно зачем писать весь этот код.
        Ответить
      • Я пишу: int div10(int num) { return num /10; }

        https://godbolt.org/g/ddmtnj
        Получаю imul (безо всяких флагов O2,O3):
        div10(int):
          mov eax, edi
          mov edx, 1717986919 // 0x66666667
          sar edi, 31
          imul edx
          sar edx, 2
          mov eax, edx
          sub eax, edi
          ret

        "Умный" код с гитхаба.
        static __attribute__((naked)) unsigned int div10(unsigned int v) {
            /* Instead of dividing by 10, we multiply the dividend by (0.1 * 2 ^ (32 + 3)).  The result will be 64-bit wide.
             * The first 32-bits of the result will be the quotient multiplied by (2 ^ 3).  Shifting this value right by 3 bits
             * will give us the final quotient.
             */
            __asm("ldr   r1, =0xcccccccd    \n"
                  "umull r1, r0, r1, r0     \n"
                  "lsr   r0, #3             \n"
                  "bx lr                    \n");
        }


        0x66666667*2 = 0xccccccce
        Ответить
        • А ну понятно. Они не хотят тянуть libgcc и всю обвязку.
          Тогда нормально.

          > Normally, the GCC compiler handles this problem.
          > Whenever a division operation is required, GCC inserts a call to a function, which replaces the division operation. This and other helper functions are implemented in libgcc, a library (usually static) distributed together with GCC. The compiler and linker take care about linking with this file automatically.

          >This library should even be included in the library when linking with the -nostdlib and similar switches. (However, this depends on the configuration.)

          >The libgcc library has its own dependencies as well, which we can not supply. For this reason, we need our own division algorithms.
          Ответить
            • Просто на наличие определенных функций.

              Джава вон про целый СтроительСтрок знает когда плюсик конпелит...
              Ответить
              • Кстати, кмк запороли простоту языка глупым исключением из своего же правила: не делать перегрузку операторов.

                Использование "+" для конкатенации уже обсуждали. Уж лучше бы оставили конкатенацию м-м-максимально неудобной, а развивали либу, в тех местах где плюсики помогали быстро говнячить: sql, html, логгирование, формат-стринги.

                Глядишь и говна меньше было бы: меньше бы клеили sqlи, а больше юзали prepared statement.

                Меньше бы лепили тормозное логирование,
                if (log.debugEnabled()){
                    log.debug("Hui: "+a+" pizda:"+b+" dzhigurga:"+c).
                }

                А больше юзали форматтеры:
                log.debug("Hui: {} pizda:{} dzhigurga:{}",a,b,c).

                Итд.
                Ответить
                • В джаве вообще очень много идиотизмов. Я не знаю по какой бараньей причине они не могут в датаклассы, в гереацию аксесоров/мутаторов, и в вывод типов

                  Перегрузка туда же относится.
                  Всё потому что 25 лет назад кто-то сказал "кококок, перегрузка усложняет код"
                  Ответить
                  • > и в вывод типов
                    Есть, причём довольно приличный. Лучше чем в C#.

                    > в генерецию аксесоров/мутаторов
                    import lombok.Getter; 
                    
                    @Getter @Setter private int pituh;



                    >датаклассы
                    import lombok.Data; 
                    @Data public class DataClass {
                    //дохуя полей
                    }
                    Ответить
                    • Довольно очевидно что речь шла о стандартной либе, а не об очередной аоп магии


                      Вывода типов нет. Напиши мне дефиницию переменной типа стринг, и сам увидишь
                      Ответить
                      • >а не об очередной аоп магии

                        Это не очередная аоп-магия. К аоп вообще никакого отношения.
                        Это часть языка. Подключаешь обычный jar (пару строк в мавене) и готово!

                        @Getter @Setter превращаются генерециями в обычные методы.
                        Ответить
                        • Ну прокси магия, какая разница если она не в стандартной либе?

                          Зы
                          Генереции это такие вореции?
                          Ответить
                          • И не прокси тоже.
                            В стандартной либе сделаны кодогенереции javax.annotation.processing.Processor

                            Они позволяют расширять язык такими штуковинами. Без изменения формата байт-кода и самого языка.

                            >Напиши мне дефиницию переменной типа стринг, и сам увидишь

                            String s="haha";
                            Ответить
                            • В момент копеляции? Уже лучше, но все равно датаклассов нет в либе, а в котлине и сишарпе есть
                              Ответить
                              • >а в котлине

                                Фу, тот же jvm.
                                Уж лучше в чистую яву аннотации добавлять, чем весь проект переписывать.

                                Да и профита там особо нет. Уж лучше на скалу пересесть, если ява не нравится.
                                Ответить
                                • Так сахар же, ну сравни

                                  data class Foo(name:String)
                                  val foo = Foo("ddd")
                                  print(foo.name)
                                  Ответить
                                  • Ты так говоришь будто сахар это что-то хорошее.

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

                                    import lombok.*;
                                    PrintStream o=System.out;
                                    
                                    @Builder @Data
                                    class Foo{
                                        String name;
                                    }
                                    
                                    val foo=new Foo("ddd");
                                    o.print (foo.getName())
                                    Ответить
                                    • А что плохого в сахаре? Котлин интероперейтится с джавой, это же те же опкоды под jvm
                                      Ответить
                              • val? Это автовывод?

                                Кмк эта говнофича обычно только убивает читабельность кода.

                                Ну если сильно хочется, то можно.
                                >val k = arrayOf(12,222)
                                import lombok.val;
                                val x= Arrays.asList(1,3,4);


                                Тем более фича неконсистентна return type в методе не выводит. Толк?
                                Ответить
                                • Выводит

                                  fun foo()=123

                                  Не знаю, мне нравится
                                  Все лучше чем писать два раза тип
                                  Ответить
                                  • >Все лучше чем писать два раза тип

                                    В яве (если не используешь lombok.val) ты пишешь тип 1 (один) раз
                                    List<Integer> a=Arrays.asList(1,2,3);
                                    
                                    List<String> a=new ArrayList<>();
                                    
                                    В C# тип в генерике не выводится
                                    var strings = new List<string> {"first", "second"};
                                    //<string> мог бы и додуплить


                                    val полезен только в случае паровозов из генериков: AbstractMap<Sting,List<Integer>>

                                    >fun foo()=123
                                    Что за язык?
                                    Ответить
                                    • Ты же сам List написал два раза

                                      Язык котлин

                                      fun foo(bar:Integer)=bar +42

                                      val buz=listOf(foo(12), 100050)

                                      buz теперь лист интов
                                      Ответить
                                      • Ща Роман пояснит что это не вывод типов, а говно

                                        А не говно есть сами знаете в каких япах уже 50 лет как
                                        Ответить
  • >эти туповатые комментарии one dream, one soul это отсылка к песне Queen - A Kind of Magic

    /* one dream */
    /* one soul */
    /* one prize */
    /* one goal */

    По-моему эта песня отсылка к другой песне: Ein Volk, Ein Reich, Ein Führer
    Ответить

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

Семь раз отмерь — один отрежь, guest!

    А не использовать ли нам bbcode?


    8