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

Flutter放置游戏自定义大数类sub函数崩溃问题求助

Flutter放置游戏数值减法函数冻结问题修复

问题根源分析

你的sub函数导致模拟器冻结的核心原因是无限循环,具体问题点:

  1. 借位逻辑错误:你的fixNum函数中,数值≥94868330时触发进位,说明每一位的基数是94868330,但原代码借位时给当前位加94868329,少加了1,导致借位后当前位仍可能小于减数位,触发无限循环。
  2. 高位借位未处理零值:当numbs[i+1]本身为0时,numbs[i+1]-=1会变成负数,后续循环中该高位无法提供有效借位,导致while循环持续执行。
  3. 未处理长度不匹配:如果当前numbs长度小于被减数的numbs长度,直接访问numbs[i]会存在越界风险,也可能引发逻辑错误。
  4. 频繁调用fixNum():在循环内部每次减法后调用fixNum(),频繁修改数组结构,不仅影响性能,还可能干扰后续减法的位运算逻辑。

修复后的sub函数代码

IdleNumb sub(IdleNumb? number) {
  if (number == null) return this;

  // 确保当前numbs长度不小于被减数,不足补0
  while (numbs.length < number.numbs.length) {
    numbs.add(0);
  }

  for (int i = 0; i < number.numbs.length; i++) {
    // 当前位不够减时触发借位逻辑
    while (numbs[i] < number.numbs[i]) {
      // 从高位寻找可借位的有效位置
      int borrowIndex = i + 1;
      while (borrowIndex < numbs.length && numbs[borrowIndex] == 0) {
        borrowIndex++;
      }

      // 处理被减数大于当前数的情况(放置游戏可根据需求调整,避免死循环)
      if (borrowIndex >= numbs.length) {
        numbs[i] = number.numbs[i] - numbs[i];
        for (int j = 0; j <= i; j++) {
          numbs[j] = -numbs[j];
        }
        break;
      }

      // 执行借位:高位减1,当前位补全基数
      numbs[borrowIndex] -= 1;
      numbs[i] += 94868330; // 基数与fixNum的进位阈值一致

      // 填充中间位为最大值(避免后续借位异常)
      for (int j = i + 1; j < borrowIndex; j++) {
        numbs[j] = 94868329;
      }
    }

    numbs[i] = numbs[i].toInt() - number.numbs[i].toInt();
  }

  // 所有减法完成后统一修正数值
  fixNum();
  return this;
}

更高效的数值方案建议

放置游戏的超大数值运算,不建议用数组分段存储,推荐尾数+指数的科学计数法模式,运算速度更快且无溢出风险:

class IdleNumber {
  double mantissa; // 范围可设为1.0~1000.0,根据需求调整
  int exponent;

  IdleNumber(this.mantissa, this.exponent);

  IdleNumber sub(IdleNumber other) {
    // 对齐指数
    if (exponent > other.exponent) {
      double adjustedOther = other.mantissa * pow(10, other.exponent - exponent);
      double newMantissa = mantissa - adjustedOther;
      return _normalize(newMantissa, exponent);
    } else if (exponent < other.exponent) {
      double adjustedSelf = mantissa * pow(10, exponent - other.exponent);
      double newMantissa = adjustedSelf - other.mantissa;
      return _normalize(newMantissa, other.exponent);
    } else {
      double newMantissa = mantissa - other.mantissa;
      return _normalize(newMantissa, exponent);
    }
  }

  // 标准化尾数和指数
  IdleNumber _normalize(double mantissa, int exponent) {
    while (mantissa < 1.0 && exponent > 0) {
      mantissa *= 10;
      exponent--;
    }
    while (mantissa >= 1000.0) {
      mantissa /= 10;
      exponent++;
    }
    return IdleNumber(mantissa, exponent);
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 09:14:56