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

C#转HLSL:long类型getBits函数适配double类型实现问题

问题:将C# long类型位操作函数迁移至HLSL double类型

原C#代码(针对long类型)

原函数用于从64位long值中提取指定区间的位,返回int结果:

static public int getBits(int start, int end, long value)
{
    long mask = ((1L << (end - start + 1)) - 1) << start;
    int result = (int)((value & mask) >> start);
    return result;
}

尝试的HLSL代码(存在错误)

尝试转换为double类型的实现,但返回结果始终错误:

int getBits(int start, int end, double value)
{
    uint mask = ((1 << (end - start + 1)) - 1) << start;
    uint valueAsUintLow, valueAsUintHigh;
    asuint(value, valueAsUintLow, valueAsUintHigh); // Extract the low and high 32 bits of value

    uint maskedValueLow = valueAsUintLow & mask; // Get the masked bits from the low bits
    uint maskedValueHigh = valueAsUintHigh & (mask >> 32); // Get the masked bits from the high bits

    int result = (int)(maskedValueLow | (maskedValueHigh << start)); // Combine the low and high bits

    return result;
}

正确的HLSL实现方案

错误分析

  1. 掩码溢出问题:原代码使用uint(32位)处理64位掩码,当位区间跨32位时会溢出,导致掩码计算错误。
  2. 位拼接逻辑错误:拆分double的高低32位后,手动拼接的逻辑不符合原C#的64位位操作逻辑,容易出错。
  3. 未对齐64位操作:C#的long是64位类型,HLSL中应直接将double转换为64位无符号整数ulong,复用原C#的位操作逻辑。

修正后的代码

int getBits(int start, int end, double value)
{
    // 将double的二进制位模式转换为64位无符号整数,对应C# long的位结构
    ulong valueAsUlong = asulong(value);
    
    // 计算64位掩码,使用ulong避免32位溢出,逻辑与C#完全一致
    ulong mask = ((1UL << (end - start + 1)) - 1) << start;
    
    // 执行位与、移位操作,最后转换为int返回
    int result = (int)((valueAsUlong & mask) >> start);
    
    return result;
}

说明

  • asulong(double)会直接将double的64位二进制位转换为ulong类型,完全保留原位模式,和C#中long的位结构对应。
  • 使用1UL作为移位的基础值,确保掩码计算在64位范围内进行,避免溢出。
  • 整个位操作逻辑与原C#代码完全对齐,保证输出结果一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 13:35:25