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

RV32I架构RARS模拟器下定点数平方根计算程序异常求助

RV32I定点数平方根计算问题修复

问题描述

需求是读取32位有符号整数,将其解释为14位小数位的32位无符号定点数,计算平方根后,再以相同格式输出。但输入409600(对应实际值25)时,输出始终为8388607或-8388607(格式最大值或其负数),与预期的81920(对应实际值5)不符。

核心问题分析

  1. 二进制搜索逻辑错误:当候选猜测的平方大于输入时,错误地将当前猜测减去步长,导致猜测值变为负数(无符号下为极大值),后续所有比较完全偏离正确方向。
  2. 乘法溢出问题:仅用mul指令获取乘积低32位,当猜测值较大时,平方结果超过32位,导致右移后的比较值完全错误。

修复后的代码(RV32M版本)

.data
input_raw:
    .word 0  

.text
.globl main
main:
    # (A) 读取输入值
    li a7, 5             
    ecall                
    la t4, input_raw     
    sw a0, 0(t4)        

    # 加载输入值(无符号处理)
    lw t5, 0(t4)        

    # 初始化二进制搜索寄存器
    li t0, 0             # 当前猜测值,初始为0
    li t1, 4194304       # 初始步长:2^22(最大可能猜测值2^23的一半)

loop:
    # (B) 正确计算(t0 + t1)^2 >>14(64位乘法避免溢出)
    add t3, t0, t1       # 候选猜测值
    mul t6, t3, t3       # 乘积低32位
    mulh t7, t3, t3      # 乘积高32位
    # 组合高低位得到右移14位的结果
    srli t8, t7, 14      # 高32位右移14位
    slli t9, t6, 18      # 低32位左移18位(填补高32位空缺)
    or t6, t8, t9        # t6即为(t3*t3) >>14

    # (C) 无符号比较候选平方与输入值
    bltu t6, t5, increase_guess  
    # 若候选平方>=输入,保持猜测值不变,直接减半步长
    j halve_step        

increase_guess:
    # (D) 候选平方小于输入,将步长加到猜测值中
    add t0, t0, t1       

halve_step:
    # (E) 步长减半
    srli t1, t1, 1       

    # (F) 步长不为0则继续循环
    bnez t1, loop        

# (G) 输出最终猜测值
done:
    mv a0, t0            
    li a7, 1             
    ecall                

    # 退出程序
    li a7, 10            
    ecall

关键修改说明

  1. 修正搜索逻辑:移除错误的减法操作,当候选猜测的平方大于输入时,仅减半步长、保持猜测值不变;只有当候选平方小于输入时,才将步长加到猜测值中,符合二进制搜索逼近平方根的正确逻辑。
  2. 解决乘法溢出:使用mulh获取乘积高32位,结合mul的低32位,正确计算出平方右移14位的结果,避免大数值下的溢出错误。
  3. 消除负数输出:猜测值始终从0开始累加正数步长,最终结果必然是非负的,解决了负数输出问题。

严格RV32I版本(无乘法指令)

若需完全符合RV32I指令集(禁用mul/mulh),可将平方计算部分替换为移位加法实现的64位乘法:

# 替换原乘法部分,计算t3*t3 >>14存入t6
li t6, 0
li t7, 0
mv t8, t3
mv t9, t3
li t10, 0
mul_loop:
    andi t11, t9, 1
    bnez t11, add_t8
    j next_bit
add_t8:
    add t6, t6, t8
    sltu t11, t6, t8
    add t7, t7, t11
next_bit:
    slli t8, t8, 1
    sltu t11, t8, 1
    add t7, t7, t11
    srli t9, t9, 1
    addi t10, t10, 1
    bltu t10, 32, mul_loop
# 计算右移14位
srli t8, t7, 14
slli t9, t6, 18
or t6, t8, t9

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 15:33:11