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

JavaCard无int/long类型下short乘法函数异常排查求助

问题分析与修正方案

你的代码核心问题在于把JavaCard的有符号short直接当作无符号8位分量相乘,以及中间加法的进位处理缺失,导致当输入为0xFFFF(即无符号65535)时计算错误。

错误根源拆解

当a=0xFFFF、b=0xFFFF时:

  • aHigh和aLow都会被解析为0xFF,但JavaCard中0xFF作为short是有符号的-1;
  • 直接执行aHigh * bLow时,实际是(-1)*(-1)=1,但我们需要的是无符号8位乘法结果255*255=65025(对应short的0xFE01);
  • 后续中间和的进位处理未考虑16位加法溢出,进一步导致高位计算错误。

修正后的完整代码

首先实现无符号8位乘法函数,避免有符号short的乘法溢出问题:

private static short mul8(short x, short y) {
    // 将8位数值拆分为4位分量,避免直接相乘溢出
    short x0 = (short)(x & 0x0F);
    short x1 = (short)((x >> 4) & 0x0F);
    short y0 = (short)(y & 0x0F);
    short y1 = (short)((y >> 4) & 0x0F);
    
    short p0 = (short)(x0 * y0);
    short p1 = (short)(x1 * y0);
    short p2 = (short)(x0 * y1);
    short p3 = (short)(x1 * y1);
    
    // 合并各分量乘积,得到8位无符号数的16位乘积结果
    short p1p2Shifted = (short)((p1 + p2) << 4);
    short p3Shifted = (short)(p3 << 8);
    return (short)(p0 + p1p2Shifted + p3Shifted);
}

然后修正主乘法函数,正确处理进位和无符号运算:

public static short[] multiplyShorts(short a, short b) {
    short aHigh = (short)((a >> 8) & 0xFF);
    short aLow  = (short)(a & 0xFF);
    short bHigh = (short)((b >> 8) & 0xFF);
    short bLow  = (short)(b & 0xFF);
    
    // 使用无符号8位乘法计算各部分乘积
    short lowLow = mul8(aLow, bLow);
    short highLow = mul8(aHigh, bLow);
    short lowHigh = mul8(aLow, bHigh);
    short highHigh = mul8(aHigh, bHigh);
    
    short[] result = new short[2];
    
    // 计算低16位的低8位
    result[1] = (short)(lowLow & 0xFF);
    short carry = (short)((lowLow >> 8) & 0xFF);
    
    // 计算低16位的高8位及进位
    short sumLowMid = (short)((highLow & 0xFF) + (lowHigh & 0xFF) + carry);
    result[1] |= (short)((sumLowMid & 0xFF) << 8);
    short carry1 = (short)((sumLowMid >> 8) & 0xFF);
    
    // 计算高16位的基础值及进位
    short sumHighMid = (short)((highLow >> 8) + (lowHigh >> 8) + carry1);
    result[0] = (short)(sumHighMid & 0xFF);
    short carry2 = (short)((sumHighMid >> 8) & 0xFF);
    
    // 合并highHigh的低8位及进位
    short temp = (short)(result[0] + (highHigh & 0xFF));
    carry2 = (short)(carry2 + ((temp < result[0]) ? 1 : 0));
    result[0] = temp;
    
    // 合并highHigh的高8位及剩余进位
    temp = (short)(result[0] + ((highHigh >> 8) << 8) + (carry2 << 8));
    result[0] = temp;
    
    return result;
}

测试验证

当输入a=0xFFFF、b=0xFFFF时:

  • 最终结果result[0] = 0xFFFE,result[1] = 0x0001,与预期完全一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 06:47:03