Справка, улучшающая простую функцию блока

Я просто вручил эту функцию в присвоении. Это сделано (следовательно никакой тег домашней работы). Но я хотел бы видеть, как это может быть улучшено.

По существу функция суммирует квадраты всех целых чисел между 1 и данное число, с помощью следующей формулы:

n(n+1)(2n+1)/6

Где n максимальное количество.

Функция ниже сделана поймать любое переполнение и возвратиться 0, должен любой происходить.

UInt32 sumSquares(const UInt32 number)
{
    int result = 0;
    __asm
    {
        mov eax, number  //move number in eax
        mov edx, 2       //move 2 in edx
        mul edx          //multiply (2n)
        jo end           //jump to end if overflow
        add eax, 1       //addition (2n+1)
        jo end           //jump to end if overflow
        mov ecx, eax     //move (2n+1) in ecx

        mov ebx, number  //move number in ebx
        add ebx, 1       //addition (n+1)
        jo end           //jump to end if overflow

        mov eax, number //move number in eax for multiplication
        mul ebx         //multiply n(n+1)
        jo end          //jump to end if overflow
        mul ecx         //multiply n(n+1)(2n+1)
        jo end          //jump to end if overflow
        mov ebx, 6      //move 6 in ebx
        div ebx         //divide by 6, the result will be in eax

        mov result, eax //move eax in result

end:
    }

    return result;
}

В основном я хочу знать то, что я могу улучшить там. С точки зрения лучших практик главным образом. Одна вещь звучит очевидной: более умная водосливная проверка (с единственной проверкой на любой максимальный вход вызвал бы переполнение).

5
задан Paul R 16 April 2010 в 06:09
поделиться

3 ответа

    mov eax, number  //move number in eax
    mov ecx, eax     //dup in ecx
    mul ecx          //multiply (n*n)
    jo end           //jump to end if overflow
    add eax, ecx     //addition (n*n+n); can't overflow
    add ecx, ecx     //addition (2n); can't overflow
    add ecx, 1       //addition (2n+1); can't overflow
    mul ecx          //multiply (n*n+n)(2n+1)
    jo end           //jump to end if overflow
    mov ecx, 6       //move 6 in ebx
    div ecx          //divide by 6, the result will be in eax

    mov result, eax //move eax in result

Снижение силы: сложите вместо умножения.

По результатам анализа меньше проверок переполнения (вы можете сделать лучше, как вы описали).

Хранить значения в регистрах вместо возврата к аргументу в стеке.

Тщательно выбирайте регистры, чтобы значения, которые можно использовать повторно, не перезаписывались.

8
ответ дан 18 December 2019 в 13:12
поделиться
mov eax, number    ; = n
cmp eax, 0x928     ; cannot handle n >= 0x928
jnc end 
shl eax, 1         ; = n(2)
add eax, 3         ; = n(2)+3
mov ebx, number
mul ebx            ; = n(n(2)+3)
add eax, 1         ; = n(n(2)+3)+1
mov ebx, number
mul ebx            ; = n(n(n(2)+3)+1) = n(n+1)(2n+1)
mov ebx, 6
div ebx
mov result, eax

Вместо проверки переполнения это решение проверяет ввод на соответствие известному максимальному значению, которое функция может справиться. Обратите внимание, что последнему умножению разрешено переполнение, и оно будет переполнено для любого входного числа больше, чем 0x509 . Проверка по известному значению вместо того, чтобы полагаться на проверки переполнения, позволяет функции обрабатывать почти вдвое больше входных значений. Фактически, функция может обрабатывать каждый ввод, результат которого умещается в пределах 32 бит.

3
ответ дан 18 December 2019 в 13:12
поделиться
UInt32 sumSquares(const UInt32 number)
{
  __asm
  {
    mov eax, number     // n
    cmd eax, MAX_VALUE
    jg  bad_value

    lea ebx, [eax+1]    // n + 1
    lea ecx, [2*eax+1]  // 2n + 1

    mul ebx
    mul ecx

    shr eax, 1          // divide by 2
    mov ebx, 2863311531 // inverse of 3
    mul ebx             // divide by 3

    ret

    bad_value:
    xor eax, eax        // return 0
    ret
  }
}

http://blogs.msdn.com/dev/archive/2005/12/12/502980.aspx

Spara

3
ответ дан 18 December 2019 в 13:12
поделиться
Другие вопросы по тегам:

Похожие вопросы: