You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

负整数统计值显示异常修复求助:Min/Max/Sum/Average计算错误

问题修复:负整数统计值显示为无符号大数的问题

问题根源

  1. 输出函数误用:你用WriteDec输出有符号整数(SDWORD类型的sum、max、min、average),但WriteDec是按无符号十进制数解析输出的,负数的补码会被当成超大无符号数(比如-40的32位补码0xFFFFFFD8会被显示为4294967256)。
  2. 最小值初始化错误:numMin初始值设为UPPER_BOUND1(-100),但第二个输入区间[-50, -1]的数(如-10)比-100大,不会触发最小值更新,导致最终最小值错误。

修复步骤

  1. 替换输出函数:所有需要显示有符号整数的位置,把WriteDec换成WriteInt(Irvine32库专门用于输出有符号十进制数的函数)。
  2. 修正最小值初始化:将numMin初始值改为UPPER_BOUND2(-1)——这是所有有效输入的最大值,确保第一个有效输入会触发最小值更新,后续更小的数也能正确更新最小值。
  3. 保留整数平均值逻辑:你的需求是整数平均值,当前用idiv处理有符号数除法的逻辑正确,不需要将numAverage改为float类型。

修复后的完整代码

INCLUDE Irvine32.inc

.data
titleMsg        BYTE    "Welcome to the Integer Accumulator by ", 0
myName          BYTE    "John", 0
progMsg         BYTE    "We will be accumulating user-input negative integers between the specified bounds, then displaying statistics of the ", 0
progMsg2        BYTE    "input values including minimum, maximum, and average values values, total sum, and total number of valid inputs.", 0
namePrompt      BYTE    "What is your name? ", 0
greetMsg        BYTE    "Hello there, ", 0
instruction     BYTE    "Please enter numbers in [-200, -100] or [-50, -1].", 0
instruction2    BYTE    "Enter a non-negative number when you are finished, and input stats will be shown.", 0
invalidMsg      BYTE    "This is not a number we're looking for (Invalid Input)!", 0
inputPrompt     BYTE    "Enter number: ", 0
statsMsg        BYTE    "You entered ", 0
validMsg        BYTE    " valid numbers.", 0
maxMsg          BYTE    "The maximum valid number is ", 0
minMsg          BYTE    "The minimum valid number is ", 0
sumMsg          BYTE    "The sum of your valid numbers is ", 0
avgMsg          BYTE    "The rounded average is ", 0
farewellMsg     BYTE    "We have to stop meeting like this. Farewell, ", 0
specialMsg      BYTE    "Congratulations, you found an Easter Egg!", 0
SUM_LIMIT       EQU     1000    ; Limit for the sum of numbers entered

; Constants for value limits
LOWER_BOUND1    EQU     -200
UPPER_BOUND1    EQU     -100
LOWER_BOUND2    EQU     -50
UPPER_BOUND2    EQU     -1

; Variables
userName        BYTE    50 DUP (?)
inputNumber     SDWORD  ?
validCount      DWORD   ?
numSum          SDWORD  ?
numMax          SDWORD  ?
numMin          SDWORD  ?
numAverage      SDWORD  ?
signFlag        BYTE    ?

.code
main PROC
    ; Display program title and programmer's name
    mov  edx, OFFSET titleMsg
    call WriteString
    mov edx, OFFSET myName
    call WriteString
    call Crlf

    ; Display program description
    mov  edx, OFFSET progMsg
    call WriteString
    call Crlf
    mov  edx, OFFSET progMsg2
    call WriteString
    call Crlf

    ; Get the user's name and greet the user
    mov  edx, OFFSET namePrompt
    call WriteString
    mov  edx, OFFSET userName
    mov  ecx, SIZEOF userName  ; 修正:避免限制用户名输入长度
    call ReadString
    mov edx, OFFSET greetMsg
    call WriteString
    mov edx, OFFSET userName
    call WriteString
    call Crlf
    call Crlf
    
    ; Display instructions
    mov  edx, OFFSET instruction
    call WriteString
    call CrLf
    mov  edx, OFFSET instruction2
    call WriteString
    call CrLf

    ; Initialize variables
    mov  numSum, 0
    mov  validCount, 0
    mov  numMax, LOWER_BOUND1       ; 初始化为最小允许值,确保首个有效输入更新最大值
    mov  numMin, UPPER_BOUND2       ; 修正:初始化为最大允许值,确保首个有效输入更新最小值

    ; User input loop

inputLoop:
    ; Prompt user to enter a number
    mov  edx, OFFSET inputPrompt
    call WriteString
    call ReadInt
    mov  inputNumber, eax

    ; Check if the number is non-negative
    test eax, eax
    jns  checkSpecialMessage

    ; Check if the number is within the specified ranges
    cmp  inputNumber, LOWER_BOUND1
    jl   invalidInput
    cmp  inputNumber, UPPER_BOUND1
    jg   checkSecondRange
    jmp  validInput

checkSecondRange:
    cmp  inputNumber, LOWER_BOUND2
    jl   invalidInput
    cmp  inputNumber, UPPER_BOUND2
    jg   invalidInput
    jmp  validInput

invalidInput:
    ; Notify user of invalid input
    mov  edx, OFFSET invalidMsg
    call WriteString
    call CrLf
    jmp  inputLoop

validInput:
    ; Update count and sum of valid numbers
    inc  validCount
    mov  eax, inputNumber ; Move inputNumber into eax register
    add  numSum, eax      ; Add eax (inputNumber) to numSum

    ; Update max and min valid numbers
    mov  eax, numMax      ; Move numMax into eax register
    cmp  inputNumber, eax ; Compare inputNumber with eax (numMax)
    jle  notMax
    mov  eax, inputNumber ; Move inputNumber into eax register
    mov  numMax, eax      ; Move eax (inputNumber) to numMax
notMax:
    mov  eax, numMin      ; Move numMin into eax register
    cmp  inputNumber, eax ; Compare inputNumber with eax (numMin)
    jge  notMin
    mov  eax, inputNumber ; Move inputNumber into eax register
    mov  numMin, eax      ; Move eax (inputNumber) to numMin
notMin:
    jmp  inputLoop

checkSpecialMessage:
    ; Check if any valid inputs were received
    cmp validCount, 0
    je displaySpecialMessage        ; If no valid inputs were received, display special message
    jmp displayStats                ; If valid inputs were received, display statistics

displaySpecialMessage:
    ; Display special message
    mov  edx, OFFSET specialMsg
    call WriteString
    call CrLf
    jmp exitProgram ; 新增:避免执行统计代码

displayStats:
    ; Calculate the rounded average
    mov  eax, numSum
    cdq
    idiv validCount
    mov  numAverage, eax

    ; Display statistics
    mov  edx, OFFSET statsMsg
    call WriteString
    mov  eax, validCount
    call WriteDec
    mov  edx, OFFSET validMsg
    call WriteString
    call CrLf
    mov  edx, OFFSET sumMsg
    call WriteString
    mov  eax, numSum
    call WriteInt ; 替换为有符号输出函数
    call CrLf
    mov  edx, OFFSET maxMsg
    call WriteString
    mov  eax, numMax
    call WriteInt ; 替换为有符号输出函数
    call CrLf
    mov  edx, OFFSET minMsg
    call WriteString
    mov  eax, numMin
    call WriteInt ; 替换为有符号输出函数
    call CrLf
    mov  edx, OFFSET avgMsg
    call WriteString
    mov  eax, numAverage
    call WriteInt ; 替换为有符号输出函数
    call CrLf

exitProgram:
    ; Display farewell message with the user's name
    mov  edx, OFFSET farewellMsg
    call WriteString
    mov  edx, OFFSET userName
    call WriteString
    exit

main ENDP

END main

额外修正说明

  • 新增exitProgram标签:修复逻辑分支错误,避免显示特殊消息后执行统计代码。
  • 修正用户名输入长度:将输入长度限制改为SIZEOF userName,允许用户输入正常长度的名字。

验证输出

输入-10、-30、0后,输出会符合预期:

You entered 2 valid numbers.
The sum of your valid numbers is -40
The maximum valid number is -10
The minimum valid number is -30
The rounded average is -20
We have to stop meeting like this. Farewell, John

内容的提问来源于stack exchange,提问作者user23372697

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 12:02:03