Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/fortran/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift和Javascript不同的按位计算结果_Javascript_Swift_Hash_Bitwise Operators - Fatal编程技术网

Swift和Javascript不同的按位计算结果

Swift和Javascript不同的按位计算结果,javascript,swift,hash,bitwise-operators,Javascript,Swift,Hash,Bitwise Operators,我正在尝试将Javascript哈希函数移植到Swift: 在Javascript中: 68207947269^51=-511529418 其中与Swift 5中的计算相同 68207947269^51=68207947318 如何,为什么它们不同 编辑,添加了JS哈希函数 function hash(str) { var hash = 5381, i = str.length; while(i) { hash = (hash * 33) ^ str.char

我正在尝试将Javascript哈希函数移植到Swift:

在Javascript中: 68207947269^51=-511529418

其中与Swift 5中的计算相同

68207947269^51=68207947318

如何,为什么它们不同

编辑,添加了JS哈希函数

function hash(str) {
  var hash = 5381,
      i    = str.length;

  while(i) {
    hash = (hash * 33) ^ str.charCodeAt(--i);
  }

  /* JavaScript does bitwise operations (like XOR, above) on 32-bit signed
   * integers. Since we want the results to be always positive, convert the
   * signed int to an unsigned by doing an unsigned bitshift. */
  return hash >>> 0;
}
编辑2,添加当前断开的Swift:

extension String {
    subscript(i: Int) -> String {
        return String(self[index(startIndex, offsetBy: i)])
    }
}

extension Character {
    func unicodeScalarCodePoint() -> UInt32 {
        let characterString = String(self)
        let scalars = characterString.unicodeScalars
        return scalars[scalars.startIndex].value
    }
}

func hashString(_ string: String) -> UInt32 {
    var hash: Int32 = 5381
    var i = string.count - 1
    while(i >= 0) {
        let char = Int32(Character(string[i]).unicodeScalarCodePoint())
        // Crash here with error: `Swift runtime failure: arithmetic overflow`
        let hashMultiply = Int32(truncating: NSNumber(value: hash * 33))
        hash = hashMultiply ^ char
        i -= 1
    }
    return UInt32(bitPattern: hash)
}

hashString("0x8f1083db77b5F556E46Ac46A29DE86e01031Bb14")

请注意:

操作数转换为32位整数,并由一系列位0和1表示。超过32位的数字将丢弃其最高有效位

Swift中的整数文本默认为Int类型,这是您的体系结构的字宽。如果你在最近的苹果设备上试用,它将是64位的

因此,要模拟JavaScript行为,您需要强制转换为Int32:

Int32(truncatingIfNeeded: 68207947269) ^ Int32(51)
这将给出所需的结果-511529418

请注意,JavaScript代码丢弃整数68207947269的位,因为它不能表示为32位整数。

请注意:

操作数转换为32位整数,并由一系列位0和1表示。超过32位的数字将丢弃其最高有效位

Swift中的整数文本默认为Int类型,这是您的体系结构的字宽。如果你在最近的苹果设备上试用,它将是64位的

因此,要模拟JavaScript行为,您需要强制转换为Int32:

Int32(truncatingIfNeeded: 68207947269) ^ Int32(51)
这将给出所需的结果-511529418

请注意,JavaScript代码丢弃整数68207947269的位,因为它不能表示为32位整数。

根据,JavaScript中的按位运算符使用32位操作数。68207947269太大,无法用32位表示,因此它首先自动被截断,然后执行逐位操作

默认情况下,Swift整数文本的类型为Int,Int的大小取决于平台。它很可能是64位,这就是为什么会产生不同的结果

要生成与JavaScript代码相同的结果,请先截断它,将其转换为Int32:

Int32(truncatingIfNeeded: 68207947269) ^ 51
请注意,结果是得到一个Int32。以后可能需要进行更多类型转换

关于你的快速翻译,我发现两个主要问题

首先,散列*33将溢出并导致崩溃。JavaScript版本不需要担心这一点,因为结果将简单地用JavaScript包装。幸运的是,如果结果溢出,而不是在Swift中崩溃,也会有一个解决方案。因此,您可以:

hash &* 33
其次,处理字符串的方式与JavaScript版本不同。在JavaScript中,返回一个UTF-16代码单元,但Swift代码取而代之的是unicode标量

要获得相同的行为,您应该执行以下操作:

extension String.UTF16View {
    subscript(i: Int) -> Element {
        return self[index(startIndex, offsetBy: i)]
    }
}

...

Int32(string.utf16[i])
根据,JavaScript中的位运算符使用32位操作数。68207947269太大,无法用32位表示,因此它首先自动被截断,然后执行逐位操作

默认情况下,Swift整数文本的类型为Int,Int的大小取决于平台。它很可能是64位,这就是为什么会产生不同的结果

要生成与JavaScript代码相同的结果,请先截断它,将其转换为Int32:

Int32(truncatingIfNeeded: 68207947269) ^ 51
请注意,结果是得到一个Int32。以后可能需要进行更多类型转换

关于你的快速翻译,我发现两个主要问题

首先,散列*33将溢出并导致崩溃。JavaScript版本不需要担心这一点,因为结果将简单地用JavaScript包装。幸运的是,如果结果溢出,而不是在Swift中崩溃,也会有一个解决方案。因此,您可以:

hash &* 33
其次,处理字符串的方式与JavaScript版本不同。在JavaScript中,返回一个UTF-16代码单元,但Swift代码取而代之的是unicode标量

要获得相同的行为,您应该执行以下操作:

extension String.UTF16View {
    subscript(i: Int) -> Element {
        return self[index(startIndex, offsetBy: i)]
    }
}

...

Int32(string.utf16[i])

您在Swift中使用的是什么类型?或者你只是将其作为一个表达式输入?我知道Javascript在Int32s中用于it计算,我尝试过,但没有成功-老实说,我不介意输入什么类型use@idmean我加上了电流。它仍然与INT32TRUNCATINGIFREADED:updateOn保持平衡,该错误发生在哪一行?如果你把你的计算分成几行,这肯定会有助于调试。你为什么要做NSNumbervalue:hash*33?你在Swift中使用的是什么类型?或者你只是将其作为一个表达式输入?我知道Javascript在Int32s中用于it计算,我尝试过,但没有成功-老实说,我不介意输入什么类型use@idmean我加上了电流。它仍然与INT32TRUNCATINGIFREADED:updateOn保持平衡,该错误发生在哪一行?如果你把计算分成几行,这肯定会有助于调试。你为什么要做NSNumbervalue:hash*33?