Рассчитать значение функции с использованием циклов while или do while

Модераторы: Hawk, Romeo, Absurd, DeeJayC, WinMain

Absurd
Сообщения: 1213
Зарегистрирован: 26 фев 2004, 13:24
Откуда: Pietari, Venäjä
Контактная информация:

04 ноя 2017, 23:01

Слива писал(а):Умею, просто мне лень. :D Мне опять лень разбирать этот код. Там что, операция "divsd xmm0, xmm2" - это и есть n%2?

Это деление с плавающей точкой pow(...) / n. Конструкцию с остатком от деления на 2 он реализовал через AND ..., MIN_INT_VALUE. Потом если получился 1, JGE перескакивает на вычисление pow(...) / n. Если получился ноль, он превращает ноль в минус 1 каким-то странным способом при помощи DEC+OR+INC.
2B OR NOT(2B) = FF
Слива
Сообщения: 133
Зарегистрирован: 19 мар 2016, 10:15

05 ноя 2017, 06:47

Да, только дизассемблер косячный. Команда AND X, 0x80000001 даст 0 или 1 для положительного числа, поэтому следующая команда JGE Метка будет всегда выполняться переходом на метку. Потому что, X всегда будет больше чем -2147483647(0x80000001).
В каком компиляторе компилировали, кстати? :D
Absurd
Сообщения: 1213
Зарегистрирован: 26 фев 2004, 13:24
Откуда: Pietari, Venäjä
Контактная информация:

05 ноя 2017, 07:38

Слива писал(а):Да, только дизассемблер косячный. Команда AND X, 0x80000001 даст 0 или 1 для положительного числа, поэтому следующая команда JGE Метка будет всегда выполняться переходом на метку. Потому что, X всегда будет больше чем -2147483647(0x80000001)
Да, там похоже косяк связанный со знаками. Если сделать n unsigned, то код получается попроще. Компилятор Visual С++ 2015

Код: Выделить всё

; 24   :         next = ((n % 2) * 2 - 1)*((pow((a - 1), n)) / n);
                                                                  
        divsd   xmm0, xmm6                                        
        mov     eax, ebx                                          
        and     eax, 1                                            
        lea     ecx, DWORD PTR [rax*2-1]                          
        xorps   xmm2, xmm2                                        
        cvtsi2sd xmm2, rcx                                        
        mulsd   xmm0, xmm2                                        
                                                                  
; 25   :         ln += next;                                      
                                                                  
        addsd   xmm8, xmm0
2B OR NOT(2B) = FF
Absurd
Сообщения: 1213
Зарегистрирован: 26 фев 2004, 13:24
Откуда: Pietari, Venäjä
Контактная информация:

05 ноя 2017, 08:06

Слива писал(а):Да, только дизассемблер косячный. Команда AND X, 0x80000001 даст 0 или 1 для положительного числа, поэтому следующая команда JGE Метка будет всегда выполняться переходом на метку. Потому что, X всегда будет больше чем -2147483647(0x80000001).
В каком компиляторе компилировали, кстати? :D

Я посмотрел более внимательно и обнаружил что EBX не соответствует точно переменной n и бывает отрицательным в половине случаев. AND X, MIN_INT_VAL при отрицательном X выставит флаги таким образом, что JGE Не сработает (OF <> SF). Компилятор VC++2015
2B OR NOT(2B) = FF
Absurd
Сообщения: 1213
Зарегистрирован: 26 фев 2004, 13:24
Откуда: Pietari, Venäjä
Контактная информация:

05 ноя 2017, 08:40

Кроме того, когда ОП уже сдал свою лабу, наверное надо имеет смысл написать что в самом первом варианте у меня было ((n & 1) << 1) - 1. Я это поменял на остаток и умножение потому что надо стремиться к тому чтобы код был самодокументрованным и наглядным для непосвященного человека.

Это не то место где тормозят современные процессоры. Если вы посмотрите на схему современного процессора, то вы увидите маленький узелок в центре который делает и целочисленные вычисления, и побитовые операции, и плавающую точку, и векторные операции SSE2. И этот узелок со всех сторон окружен бескрайними полями кэша нулевого и первого уровней. Прочитать байт из ОЗУ в разы дороже чем разделить пару чисел. И по тактам, и по энергии.
2B OR NOT(2B) = FF
Слива
Сообщения: 133
Зарегистрирован: 19 мар 2016, 10:15

05 ноя 2017, 11:52

Цитата Absurda из 1 сообщения: "MIN_INT_VAL" - там не чисто MIN_INT_VAL, а (MIN_INT_VAL+1).
Цитата Absurda из 2 сообщения: ((n & 1) << 1) - побитная операция И приведет к такому же результату. :D
Absurd
Сообщения: 1213
Зарегистрирован: 26 фев 2004, 13:24
Откуда: Pietari, Venäjä
Контактная информация:

05 ноя 2017, 13:04

Слива писал(а):Цитата Absurda из 1 сообщения: "MIN_INT_VAL" - там не чисто MIN_INT_VAL, а (MIN_INT_VAL+1).
Отрицательное AND MIN_INT_VAL даст MIN_INT_VAL, OF = 0, SF= 1. JGE срабатывает при условии OF == SF, что в данном случае не выполняется.
Слива писал(а): ((n & 1) << 1) - побитная операция И приведет к такому же результату. :D
И к какому результату он приведет?
2B OR NOT(2B) = FF
Слива
Сообщения: 133
Зарегистрирован: 19 мар 2016, 10:15

05 ноя 2017, 16:13

Я имею ввиду, что n%2 и n&1 - выдадут только 0 или 1 в зависимости от младшего бита - собственно его и выдадут. :D
Absurd
Сообщения: 1213
Зарегистрирован: 26 фев 2004, 13:24
Откуда: Pietari, Venäjä
Контактная информация:

05 ноя 2017, 16:38

Слива писал(а):Я имею ввиду, что n%2 и n&1 - выдадут только 0 или 1 в зависимости от младшего бита - собственно его и выдадут. :D

% 2 сохраняет знак левого операнда, & 1 - нет.
2B OR NOT(2B) = FF
Vantelin
Сообщения: 0
Зарегистрирован: 22 дек 2017, 02:55

22 дек 2017, 03:09

//////////////////
Ответить