V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
liunaijie
V2EX  ›  问与答

c 语言的一个函数如何转换成 Java 或 scala 代码

  •  
  •   liunaijie · 2020-11-29 14:46:12 +08:00 · 1453 次点击
    这是一个创建于 1447 天前的主题,其中的信息可能已经有所发展或是发生改变。

    如题,我需要将一段 c 实现的函数转换成 java 或者 scala 代码。这个函数就是下面这个,一个哈希算法,在转换的过程中主要遇到的问题是,x *= 0xff51afd7ed558ccdULL 这一句,x=x*一个数,看这个应该是 16 进制的一个数,然后 U 表示无符号,LL 应该是表示 long long 类型,但是这个代码如何能在 java 中实现出来呢,大体逻辑我能知道,但是就是转换出来的结果跟 c 语言运行得到的结果不一致,希望有大佬能帮忙看一下。

    inline DB::UInt64 intHash64(DB::UInt64 x)
    {
        x ^= x >> 33;
        x *= 0xff51afd7ed558ccdULL;
        x ^= x >> 33;
        x *= 0xc4ceb9fe1a85ec53ULL;
        x ^= x >> 33;
    
        return x;
    }
    
    第 1 条附言  ·  2020-12-01 22:26:18 +08:00
    首先非常感谢 3 楼给出的代码。
    是这样,在 c 中有 long long 类型,而在 java 中只有 long 类型。这样会有一个问题就是位运算的时候出现精度问题,计算出来的结果跟 c 中得到的结果不一致。
    比如我在 c 语言中输入 1 得到的结果是一个比 max long 还大的值
    3 条回复    2020-11-29 16:06:19 +08:00
    msg7086
        1
    msg7086  
       2020-11-29 15:02:52 +08:00
    乘法不一致吗?还是异或不一致?
    Jirajine
        2
    Jirajine  
       2020-11-29 15:13:29 +08:00 via Android
    Java 没有 unsigned 类型,只能用 signed 类型来表示。可能结果看起来不一致,实际上换算过来是一样的。
    Cbdy
        3
    Cbdy  
       2020-11-29 16:06:19 +08:00
    public static long intHash64(long x) {

    x ^= x >> 33;
    x *= Long.parseUnsignedLong("ff51afd7ed558ccd", 16);
    x ^= x >> 33;
    x *= Long.parseUnsignedLong("c4ceb9fe1a85ec53", 16);
    x ^= x >> 33;
    return x;

    }
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5465 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 09:05 · PVG 17:05 · LAX 01:05 · JFK 04:05
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.