С полей сообщають: Сдвиг отрицательных чисел дает результат отличный от результата деления, например, сдвиг -1 вправо даст -1 независимо от количества разрядов на которые производится сдвиг. А как тогда? Вариант 1:
Для получения точного результата нужна или предварительная коррекция делимого числа (примерно так: if (x < 0) x += N - 1; x >>= M;) или коррекция результата исходя из выдвинутых за пределы числа бит.
Вариант 2:
// ============= Быстрое деление целого на 64
signed int res;
if (Y0<0)
{
signed long tmp = -Y0;
res = tmp >> 6;
res = -res;
}
else {res = Y0 >> 6;}
return res;
95 if (Y0<0)
\ 000002D8 8148 LD R20, Y
\ 000002DA 8159 LDD R21, Y+1
\ 000002DC 816A LDD R22, Y+2
\ 000002DE 817B LDD R23, Y+3
\ 000002E0 2377 TST R23
\ 000002E2 F4C2 BRPL ??filter_int_1
96 {
97 signed long tmp = -Y0;
\ 000002E4 8108 LD R16, Y
\ 000002E6 8119 LDD R17, Y+1
\ 000002E8 812A LDD R18, Y+2
\ 000002EA 813B LDD R19, Y+3
\ 000002EC 9510 COM R17
\ 000002EE 9520 COM R18
\ 000002F0 9530 COM R19
\ 000002F2 9501 NEG R16
\ 000002F4 4F1F SBCI R17, 255
\ 000002F6 4F2F SBCI R18, 255
\ 000002F8 4F3F SBCI R19, 255
\ 000002FA 0108 MOVW R1:R0, R17:R16
\ 000002FC 0119 MOVW R3:R2, R19:R18
98 res = tmp >> 6;
\ 000002FE E046 LDI R20, 6
\ 00000300 0180 MOVW R17:R16, R1:R0
\ 00000302 0191 MOVW R19:R18, R3:R2
\ 00000304 ........ CALL ?SL_SHR_L03
\ 00000308 0128 MOVW R5:R4, R17:R16
99 res =- res;
\ 0000030A 9451 NEG R5
\ 0000030C 9441 NEG R4
\ 0000030E E000 LDI R16, 0
\ 00000310 0A50 SBC R5, R16
\ 00000312 C008 RJMP ??filter_int_2
100 }
101 else {res = Y0 >> 6;}
\ ??filter_int_1:
\ 00000314 E046 LDI R20, 6
\ 00000316 8108 LD R16, Y
\ 00000318 8119 LDD R17, Y+1
\ 0000031A 812A LDD R18, Y+2
\ 0000031C 813B LDD R19, Y+3
\ 0000031E ........ CALL ?SL_SHR_L03
\ 00000322 0128 MOVW R5:R4, R17:R16
102
103 return res;