chai2010 / advanced-go-programming-book

:books: 《Go语言高级编程》开源图书,涵盖CGO、Go汇编语言、RPC实现、Protobuf插件实现、Web框架实现、分布式系统等高阶主题(完稿)
https://chai2010.cn/advanced-go-programming-book/
BSD 2-Clause "Simplified" License
19.32k stars 3.21k forks source link

3.5.3 for 循环 的算法有问题 #577

Open feiquan123 opened 2 years ago

feiquan123 commented 2 years ago
func LoopAdd(cnt, v0, step int) int {
    result := v0
    for i := 0; i < cnt; i++ {
        result += step
    }
    return result
}

比如 1+2+...+100 等差数列可以这样计算 LoopAdd(100, 1, 1),而 10+8+...+0 等差数列则可以这样计算 LoopAdd(5, 10, -2)。

问题描述

按这个算法 LoopAdd(100, 1, 1) = 101 期望:5050 LoopAdd(5, 10, -2) = 0 期望:30

feiquan123 commented 2 years ago

修改后:

func LoopAdd(cnt, v0, step int) int {
    result := v0
    next := v0
    for i := 1; i < cnt; i++ {
        next += step
        result += next
    }
    return result
}

汇编:

TEXT ·LoopAdd(SB),$0-32
    MOVQ cnt+8*0(FP), AX // cnt
    MOVQ v0+8*1(FP), BX // v0 /result
    MOVQ step+8*2(FP), CX // step

    MOVQ BX, R8 // next
    MOVQ $1, DX // i

LOOP_IF:
    CMPQ DX, AX // compare i, cnt
    JL LOOP_BODY // if i < cnt; goto LOOP_BODY
    JMP LOOP_END

LOOP_BODY:
    ADDQ CX, R8 // next += step
    ADDQ R8, BX // result += next
    ADDQ $1, DX // i++
    JMP LOOP_IF

LOOP_END:
    MOVQ BX, ret+8*3(FP) // return result
    RET
chai2010 commented 2 years ago

发现 BUG 直接上 PR