我正在嘗試使用 Turbo Assembler 在 8086 匯編程式中檢查給定數字是否為素數。但也許我的代碼有問題,因為某些素數(19、23、31、37)顯示它不是素數。其余的素數(2,3,5,7,11,17,29,41,...,71)運行良好。
這是整個代碼:
DATA SEGMENT
NUM DB 37H
PR DB 0H
NPR DB 0H
DATA ENDS
CODE SEGMENT
START: ASSUME CS:CODE, DS:DATA
MOV AX, DATA
MOV DS, AX
MOV AL, NUM
MOV BL, 02H
MOV BH,00H
MOV DX,0000H
MOV AH,00H
UP:DIV BL
CMP AH,00H
JNE NEXT
INC BH
NEXT: CMP BH, 02H
JE NPRIME
INC BL
MOV AX, 0000H
MOV DX, 0000H
MOV AL, NUM
CMP BL, NUM
JBE UP
PRIME:
INC PR
JMP EXIT
NPRIME:
INC NPR
EXIT:
MOV AH, 4CH
INT 21H
CODE ENDS
END START
也許問題一定出在這部分?
UP:DIV BL
CMP AH,00H
JNE NEXT
INC BH
NEXT: CMP BH, 02H
JE NPRIME
INC BL
MOV AX, 0000H
MOV DX, 0000H
MOV AL, NUM
CMP BL, NUM
JBE UP
請讓我知道我哪里出錯了,在此先感謝!
uj5u.com熱心網友回復:
我試過你的程式,它運行良好,只是你似乎考慮了 0 和 1 素數。這是不正確的。
素數是大于 1 的數,它只能被自身和 1 整除。
快速修復如下:
...
MOV AL, NUM
cmp al, 2 <<<< Add this line
jb NPRIME <<<< Add this line
MOV BL, 02H
MOV BH,00H
MOV DX,0000H
MOV AH,00H
UP:DIV BL
CMP AH,00H
JNE NEXT
INC BH
NEXT: CMP BH, 02H
JE NPRIME
INC BL
MOV AX, 0000H
MOV DX, 0000H
MOV AL, NUM
CMP BL, NUM
JBE UP
PRIME:
INC PR
JMP EXIT
NPRIME:
INC NPR
EXIT:
...
如果我將其留在那里,那就沒什么答案了!因此,請允許我進行以下觀察:
- 歸零
DX是重復兩次的冗余操作 - 您可以在一次操作中加載
BH和BL - 不要在兩個不同的地方加載號碼
- 變數PR和NPR是互斥的,所以一個變數就足夠了
- 您不需要分支來增加計數器
更好的解決方法如下:
...
cmp NUM, 2
jb NPRIME ; 0 and 1 are no prime numbers
mov bx, 0002h ; BH=0 (counter), BL=2 (divisor)
UP:
mov al, NUM
mov ah, 0
div bl
cmp ah, 1 ; Only sets carry flag is remainder is 0
adc bh, 0 ; Conditional increment of counter
cmp bh, 2
je NPRIME
inc bl
cmp bl, NUM
jbe UP
PRIME:
inc PR
NPRIME:
EXIT:
...
因為您的演算法會嘗試每個除數本身,所以即使上述建議的更改也不會使程式真正高效。
我可以添加一個至少快 10 倍的代碼版本。如果您有興趣,請給我留言,也許我可以在周末添加它...
[編輯]
快速檢查素數
嘗試減少迭代次數,尤其是除法次數(div這是一項昂貴的操作)是我們在這里追求的:
- 首先拆分小數字 [0,3] 是最有效的。這避免了回圈中的額外測驗。
- 接下來我們拆分偶數,因為除了數字 2(我們已經拆分)之外,沒有偶數是素數。
- 因此回圈只需要除奇數。我們可以一次省略所有偶數除數,因為奇數除以偶數永遠不會產生零余數。
- 我們只需要測驗除數直到該數字的整數平方根。幸運的是,我們不需要計算它。只要除法的商仍然大于除數,我們還沒有達到整數平方根。
; IN (dl) OUT (cx) MOD (ax,bl)
TestPrime:
xor cx, cx ; CX=0 means NotPrime
cmp dl, 4
jb .Less4
mov bl, 1
test dl, bl
jz .No ; Number is EVEN, so not prime
; Remaining candidates {5,7,9,11,13,15,...}
.Loop:
add bl, 2 ; Division by {3,5,7,9,11,....}
mov al, dl
mov ah, 0 ; Will divide AX by BL
div bl
test ah, ah ; Remainder == 0 ?
jz .No ; Yes, found an additional divisor, so not prime
cmp al, bl ; Quotient > divisor ?
ja .Loop ; Yes, continue up to isqrt(number)
.Yes:
inc cx ; CX=1 means Prime
ret
.Less4:
cmp dl, 2
jae .Yes ; 2 and 3 are prime, 0 and 1 are not prime
.No:
ret
小于 256 的素數
下表顯示DIV了已執行的指令數量以及以納秒為單位的時間。中間的列是問題的改進代碼,右邊的列是今天優化的代碼。隨著數量的增長,收益也在增長。
| 數字 | IsPrime | DIV 的 | 納秒 | DIV 的 | 納秒 |
|---|---|---|---|---|---|
| 251 | 1 | 250 | 4163 | 8 | 495 |
| 241 | 1 | 240 | 4140 | 8 | 428 |
| 239 | 1 | 238 | 3967 | 7 | 285 |
| 233 | 1 | 232 | 3869 | 7 | 263 |
| 229 | 1 | 228 | 3809 | 7 | 285 |
| 227 | 1 | 226 | 3779 | 7 | 255 |
| 223 | 1 | 222 | 3697 | 7 | 263 |
| 211 | 1 | 210 | 3494 | 7 | 255 |
| 199 | 1 | 198 | 3298 | 7 | 263 |
| 197 | 1 | 196 | 3276 | 7 | 263 |
| 193 | 1 | 192 | 3298 | 7 | 263 |
| 191 | 1 | 190 | 3186 | 7 | 263 |
| 181 | 1 | 180 | 3020 | 6 | 315 |
| 179 | 1 | 178 | 2990 | 6 | 308 |
| 173 | 1 | 172 | 2900 | 6 | 285 |
| 167 | 1 | 166 | 2802 | 6 | 232 |
| 163 | 1 | 162 | 2742 | 6 | 232 |
| 157 | 1 | 156 | 2667 | 6 | 240 |
| 151 | 1 | 150 | 2637 | 6 | 240 |
| 149 | 1 | 148 | 2524 | 6 | 240 |
| 139 | 1 | 138 | 2382 | 6 | 240 |
| 137 | 1 | 136 | 2352 | 6 | 240 |
| 131 | 1 | 130 | 2254 | 5 | 285 |
| 127 | 1 | 126 | 2171 | 5 | 293 |
| 113 | 1 | 112 | 1946年 | 5 | 255 |
| 109 | 1 | 108 | 1893年 | 5 | 225 |
| 107 | 1 | 106 | 1871 | 5 | 225 |
| 103 | 1 | 102 | 1848年 | 5 | 210 |
| 101 | 1 | 100 | 1750 | 5 | 225 |
| 97 | 1 | 96 | 1713 | 5 | 225 |
| 89 | 1 | 88 | 1555 | 4 | 270 |
| 83 | 1 | 82 | 1457 | 4 | 270 |
| 79 | 1 | 78 | 1465 | 4 | 240 |
| 73 | 1 | 72 | 1390 | 4 | 195 |
| 71 | 1 | 70 | 1284 | 4 | 202 |
| 67 | 1 | 66 | 1202 | 4 | 210 |
| 61 | 1 | 60 | 1209 | 4 | 195 |
| 59 | 1 | 58 | 1082 | 4 | 195 |
| 53 | 1 | 52 | 976 | 3 | 255 |
| 47 | 1 | 46 | 871 | 3 | 263 |
| 43 | 1 | 42 | 804 | 3 | 180 |
| 41 | 1 | 40 | 773 | 3 | 187 |
| 37 | 1 | 36 | 728 | 3 | 172 |
| 31 | 1 | 30 | 616 | 3 | 180 |
| 29 | 1 | 28 | 601 | 2 | 225 |
| 23 | 1 | 22 | 510 | 2 | 232 |
| 19 | 1 | 18 | 435 | 2 | 172 |
| 17 | 1 | 16 | 413 | 2 | 172 |
| 13 | 1 | 12 | 360 | 2 | 172 |
| 11 | 1 | 10 | 315 | 1 | 217 |
| 7 | 1 | 6 | 247 | 1 | 142 |
| 5 | 1 | 4 | 217 | 1 | 150 |
| 3 | 1 | 2 | 187 | 0 | 165 |
| 2 | 1 | 1 | 172 | 0 | 165 |
小于 256 的非素數
下表顯示了數量DIV了已執行的指令數量以及以納秒為單位的時間。中間的列是問題的改進代碼,右邊的列是今天優化的代碼。隨著數量的增長,收益也在增長。
| 數字 | IsPrime | DIV 的 | 納秒 | DIV 的 | 納秒 |
|---|---|---|---|---|---|
| 255 | 0 | 4 | 270 | 1 | 195 |
| 254 | 0 | 126 | 2261 | 0 | 202 |
| 253 | 0 | 22 | 518 | 5 | 345 |
| 252 | 0 | 2 | 202 | 0 | 180 |
| 250 | 0 | 4 | 285 | 0 | 142 |
| 249 | 0 | 82 | 1532 | 1 | 217 |
| 248 | 0 | 3 | 240 | 0 | 150 |
| 247 | 0 | 18 | 510 | 6 | 345 |
| 246 | 0 | 2 | 210 | 0 | 165 |
| 245 | 0 | 6 | 270 | 2 | 232 |
| 244 | 0 | 3 | 255 | 0 | 165 |
| 243 | 0 | 8 | 338 | 1 | 217 |
| 242 | 0 | 10 | 375 | 0 | 180 |
| 240 | 0 | 2 | 217 | 0 | 157 |
| 238 | 0 | 6 | 360 | 0 | 142 |
| 237 | 0 | 78 | 1442 | 1 | 187 |
| 236 | 0 | 3 | 240 | 0 | 142 |
| 235 | 0 | 46 | 916 | 2 | 232 |
| 234 | 0 | 2 | 210 | 0 | 157 |
| 232 | 0 | 3 | 180 | 0 | 157 |
| 231 | 0 | 6 | 270 | 1 | 187 |
| 230 | 0 | 4 | 247 | 0 | 142 |
| 228 | 0 | 2 | 210 | 0 | 150 |
| 226 | 0 | 112 | 2066 | 0 | 142 |
| 225 | 0 | 4 | 247 | 1 | 195 |
| 224 | 0 | 3 | 240 | 0 | 142 |
| 222 | 0 | 2 | 217 | 0 | 150 |
| 221 | 0 | 16 | 435 | 6 | 338 |
| 220 | 0 | 3 | 240 | 0 | 150 |
| 219 | 0 | 72 | 1352 | 1 | 225 |
| 218 | 0 | 108 | 1931年 | 0 | 142 |
| 217 | 0 | 30 | 646 | 3 | 278 |
| 216 | 0 | 2 | 210 | 0 | 157 |
| 215 | 0 | 42 | 924 | 2 | 232 |
| 214 | 0 | 106 | 1893年 | 0 | 165 |
| 213 | 0 | 70 | 1322 | 1 | 217 |
| 212 | 0 | 3 | 240 | 0 | 157 |
| 210 | 0 | 2 | 165 | 0 | 150 |
| 209 | 0 | 18 | 488 | 5 | 323 |
| 208 | 0 | 3 | 270 | 0 | 165 |
| 207 | 0 | 8 | 255 | 1 | 217 |
| 206 | 0 | 102 | 1893年 | 0 | 165 |
| 205 | 0 | 40 | 811 | 2 | 202 |
| 204 | 0 | 2 | 210 | 0 | 165 |
| 203 | 0 | 28 | 631 | 3 | 278 |
| 202 | 0 | 100 | 1795 | 0 | 165 |
| 201 | 0 | 66 | 1254 | 1 | 217 |
| 200 | 0 | 3 | 240 | 0 | 165 |
| 198 | 0 | 2 | 165 | 0 | 150 |
| 196 | 0 | 3 | 232 | 0 | 142 |
| 195 | 0 | 4 | 240 | 1 | 187 |
| 194 | 0 | 96 | 1750 | 0 | 142 |
| 192 | 0 | 2 | 165 | 0 | 150 |
| 190 | 0 | 4 | 315 | 0 | 142 |
| 189 | 0 | 6 | 270 | 1 | 195 |
| 188 | 0 | 3 | 255 | 0 | 142 |
| 187 | 0 | 16 | 428 | 5 | 308 |
| 186 | 0 | 2 | 202 | 0 | 142 |
| 185 | 0 | 36 | 804 | 2 | 232 |
| 184 | 0 | 3 | 240 | 0 | 165 |
| 183 | 0 | 60 | 1142 | 1 | 225 |
| 182 | 0 | 6 | 270 | 0 | 157 |
| 180 | 0 | 2 | 165 | 0 | 157 |
| 178 | 0 | 88 | 1720 | 0 | 142 |
| 177 | 0 | 58 | 1134 | 1 | 187 |
| 176 | 0 | 3 | 240 | 0 | 150 |
| 175 | 0 | 6 | 270 | 2 | 232 |
| 174 | 0 | 2 | 210 | 0 | 180 |
| 172 | 0 | 3 | 240 | 0 | 157 |
| 171 | 0 | 8 | 300 | 1 | 187 |
| 170 | 0 | 4 | 247 | 0 | 150 |
| 169 | 0 | 168 | 2938 | 6 | 345 |
| 168 | 0 | 2 | 210 | 0 | 165 |
| 166 | 0 | 82 | 1540 | 0 | 142 |
| 165 | 0 | 4 | 240 | 1 | 240 |
| 164 | 0 | 3 | 232 | 0 | 150 |
| 162 | 0 | 2 | 157 | 0 | 150 |
| 161 | 0 | 22 | 510 | 3 | 278 |
| 160 | 0 | 3 | 247 | 0 | 157 |
| 159 | 0 | 52 | 1014 | 1 | 187 |
| 158 | 0 | 78 | 1442 | 0 | 142 |
| 156 | 0 | 2 | 165 | 0 | 142 |
| 155 | 0 | 30 | 646 | 2 | 263 |
| 154 | 0 | 6 | 270 | 0 | 150 |
| 153 | 0 | 8 | 375 | 1 | 187 |
| 152 | 0 | 3 | 247 | 0 | 157 |
| 150 | 0 | 2 | 210 | 0 | 150 |
| 148 | 0 | 3 | 270 | 0 | 150 |
| 147 | 0 | 6 | 270 | 1 | 202 |
| 146 | 0 | 72 | 1352 | 0 | 150 |
| 145 | 0 | 28 | 631 | 2 | 232 |
| 144 | 0 | 2 | 202 | 0 | 157 |
| 143 | 0 | 12 | 390 | 5 | 308 |
| 142 | 0 | 70 | 1375 | 0 | 165 |
| 141 | 0 | 46 | 916 | 1 | 225 |
| 140 | 0 | 3 | 240 | 0 | 165 |
| 138 | 0 | 2 | 165 | 0 | 195 |
| 136 | 0 | 3 | 232 | 0 | 150 |
| 135 | 0 | 4 | 247 | 1 | 195 |
| 134 | 0 | 66 | 1247 | 0 | 142 |
| 133 | 0 | 18 | 488 | 3 | 308 |
| 132 | 0 | 2 | 165 | 0 | 172 |
| 130 | 0 | 4 | 247 | 0 | 187 |
| 129 | 0 | 42 | 879 | 1 | 195 |
| 128 | 0 | 3 | 240 | 0 | 165 |
| 126 | 0 | 2 | 165 | 0 | 142 |
| 125 | 0 | 24 | 556 | 2 | 263 |
| 124 | 0 | 3 | 240 | 0 | 165 |
| 123 | 0 | 40 | 811 | 1 | 150 |
| 122 | 0 | 60 | 1209 | 0 | 142 |
| 121 | 0 | 120 | 2134 | 5 | 308 |
| 120 | 0 | 2 | 210 | 0 | 142 |
| 119 | 0 | 16 | 473 | 3 | 278 |
| 118 | 0 | 58 | 1127 | 0 | 165 |
| 117 | 0 | 8 | 300 | 1 | 202 |
| 116 | 0 | 3 | 247 | 0 | 172 |
| 115 | 0 | 22 | 556 | 2 | 270 |
| 114 | 0 | 2 | 210 | 0 | 165 |
| 112 | 0 | 3 | 240 | 0 | 150 |
| 111 | 0 | 36 | 758 | 1 | 187 |
| 110 | 0 | 4 | 240 | 0 | 157 |
| 108 | 0 | 2 | 165 | 0 | 150 |
| 106 | 0 | 52 | 1097 | 0 | 150 |
| 105 | 0 | 4 | 240 | 1 | 202 |
| 104 | 0 | 3 | 240 | 0 | 150 |
| 102 | 0 | 2 | 165 | 0 | 142 |
| 100 | 0 | 3 | 232 | 0 | 157 |
| 99 | 0 | 8 | 300 | 1 | 165 |
| 98 | 0 | 6 | 270 | 0 | 165 |
| 96 | 0 | 2 | 165 | 0 | 142 |
| 95 | 0 | 18 | 488 | 2 | 217 |
| 94 | 0 | 46 | 1036 | 0 | 150 |
| 93 | 0 | 30 | 646 | 1 | 195 |
| 92 | 0 | 3 | 240 | 0 | 157 |
| 91 | 0 | 12 | 390 | 3 | 308 |
| 90 | 0 | 2 | 210 | 0 | 180 |
| 88 | 0 | 3 | 232 | 0 | 187 |
| 87 | 0 | 28 | 631 | 1 | 187 |
| 86 | 0 | 42 | 871 | 0 | 142 |
| 85 | 0 | 16 | 428 | 2 | 232 |
| 84 | 0 | 2 | 210 | 0 | 180 |
| 82 | 0 | 40 | 819 | 0 | 157 |
| 81 | 0 | 8 | 293 | 1 | 202 |
| 80 | 0 | 3 | 232 | 0 | 142 |
| 78 | 0 | 2 | 210 | 0 | 157 |
| 77 | 0 | 10 | 323 | 3 | 278 |
| 76 | 0 | 3 | 232 | 0 | 142 |
| 75 | 0 | 4 | 240 | 1 | 150 |
| 74 | 0 | 36 | 758 | 0 | 150 |
| 72 | 0 | 2 | 165 | 0 | 142 |
| 70 | 0 | 4 | 315 | 0 | 142 |
| 69 | 0 | 22 | 518 | 1 | 187 |
| 68 | 0 | 3 | 240 | 0 | 142 |
| 66 | 0 | 2 | 165 | 0 | 142 |
| 65 | 0 | 12 | 390 | 2 | 232 |
| 64 | 0 | 3 | 240 | 0 | 142 |
| 63 | 0 | 6 | 270 | 1 | 150 |
| 62 | 0 | 30 | 646 | 0 | 150 |
| 60 | 0 | 2 | 165 | 0 | 150 |
| 58 | 0 | 28 | 751 | 0 | 142 |
| 57 | 0 | 18 | 488 | 1 | 195 |
| 56 | 0 | 3 | 270 | 0 | 165 |
| 55 | 0 | 10 | 368 | 2 | 232 |
| 54 | 0 | 2 | 202 | 0 | 180 |
| 52 | 0 | 3 | 240 | 0 | 157 |
| 51 | 0 | 16 | 428 | 1 | 195 |
| 50 | 0 | 4 | 240 | 0 | 142 |
| 49 | 0 | 48 | 1044 | 3 | 270 |
| 48 | 0 | 2 | 210 | 0 | 165 |
| 46 | 0 | 22 | 593 | 0 | 157 |
| 45 | 0 | 4 | 240 | 1 | 187 |
| 44 | 0 | 3 | 240 | 0 | 165 |
| 42 | 0 | 2 | 202 | 0 | 142 |
| 40 | 0 | 3 | 270 | 0 | 142 |
| 39 | 0 | 12 | 398 | 1 | 187 |
| 38 | 0 | 18 | 488 | 0 | 142 |
| 36 | 0 | 2 | 210 | 0 | 150 |
| 35 | 0 | 6 | 270 | 2 | 247 |
| 34 | 0 | 16 | 420 | 0 | 150 |
| 33 | 0 | 10 | 323 | 1 | 187 |
| 32 | 0 | 3 | 232 | 0 | 142 |
| 30 | 0 | 2 | 202 | 0 | 150 |
| 28 | 0 | 3 | 263 | 0 | 165 |
| 27 | 0 | 8 | 293 | 1 | 195 |
| 26 | 0 | 12 | 465 | 0 | 142 |
| 25 | 0 | 24 | 563 | 2 | 232 |
| 24 | 0 | 2 | 210 | 0 | 142 |
| 22 | 0 | 10 | 323 | 0 | 150 |
| 21 | 0 | 6 | 270 | 1 | 202 |
| 20 | 0 | 3 | 232 | 0 | 150 |
| 18 | 0 | 2 | 225 | 0 | 150 |
| 16 | 0 | 3 | 232 | 0 | 157 |
| 15 | 0 | 4 | 232 | 1 | 187 |
| 14 | 0 | 6 | 263 | 0 | 142 |
| 12 | 0 | 2 | 217 | 0 | 157 |
| 10 | 0 | 4 | 315 | 0 | 157 |
| 9 | 0 | 8 | 308 | 1 | 217 |
| 8 | 0 | 3 | 247 | 0 | 150 |
| 6 | 0 | 2 | 217 | 0 | 142 |
| 4 | 0 | 3 | 240 | 0 | 165 |
| 1 | 0 | 0 | 165 | 0 | 187 |
| 0 | 0 | 0 | 157 | 0 | 187 |
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/459722.html
