考虑以下C ++程序:
#include <cstdint>
#include <iostream>
int main() {
std::string s = "αa";
std::cout << std::hex << uint32_t(s[0]) << std::endl;
std::cout << std::hex << uint32_t(s[1]) << std::endl;
std::cout << std::hex << uint32_t(s[2]) << std::endl;
}
打印
ffffffce
ffffffb1
61
如何在Python中复制转换行为? IE浏览器。如何获得包含3个数字的类型uint32_t的numpy数组? 1
例如
import numpy as np
s = "αa"
s = s.encode('utf-8')
for c in bytearray(s):
h = print(hex(np.uint32(c)))
将导致
0xce
0xb1
0x61
这还不够。我还研究了ctypes模块提供的功能,但找不到可行的解决方案。
动机:我想应用一个Fowler–Noll–Vo hash function,它依赖于逐位操作,匹配现有的C ++实现,该实现通过将std::string
的元素转换为uint32_t
来运行。
1 虽然C ++版本的输出取决于体系结构/编译器,但我正在寻找一个与此问题中描述的行为相匹配的实现,或者C ++程序的行为当使用相同的编译器编译它时,python解释器是用on。
编译的答案 0 :(得分:2)
根据Python doc.:
bytearray类型是0 <= x <0的范围内的可变整数序列。 256。
恕我直言,因此C ++中的转换应该将字符处理为unsigned char
。这可以通过&#34;两步&#34;投:
#include <cstdint>
#include <iostream>
typedef unsigned char uchar;
int main() {
std::string s = "αa";
std::cout << std::hex << uint32_t((uchar)s[0]) << std::endl;
std::cout << std::hex << uint32_t((uchar)s[1]) << std::endl;
std::cout << std::hex << uint32_t((uchar)s[2]) << std::endl;
}
输出:
ce
b1
61
注意:
我认为初始化std::string s = "αa";
有点关键。所以,这取决于源代码编码。 (我在Windows上。使用Windows-1252编码,因为它通常用于很多Windows应用程序会破坏这个程序,因为字符串只有两个元素。我刚才意识到{{ 3}}甚至不编码α
,但这并不能使它更好。)
将字符强制为unsigned char
,应使应用程序独立于C ++编译器的特定char
类型的签名。
答案 1 :(得分:2)
这里的问题是你的C ++实现(不可避免地允许 - 但不是强制的 - 标准)将For example , if arr={6,3,1,3,4,3,6,5};
after sort arr={1,3,3,3,4,5,6,6};
And number of similar elements from end is 2.
作为签名类型,而Python正确地考虑char
个元素为非负值。
正确的解决方案IMO将像@Scheff在其答案中所示 - 修复C ++程序,该程序依赖于生成有争议输出的实现定义行为。 OTOH,如果你被迫匹配一个无法改变的现有C ++程序,你可以很容易地在Python中重现这种行为。
在C ++程序中,当字节值超过127(因而为负数)转换为bytearray
时,它会被包裹在2³²左右,因此所有uint32_t
值都会被包含。
要在Python中获得相同的结果,您可以先手动转换为ffffffxx
(即C ++实现中的int8
):
char
输出:
import numpy as np
s = "αa"
s = s.encode('utf-8')
for c in bytearray(s):
h = print(hex(np.uint32(np.int8(c))))
答案 2 :(得分:1)
第一个字符获得0xffffffce
的事实依赖于实现,有效的C ++实现也可以返回0xce
,因为差异取决于签名或未签名的默认char
类型(有些编译器提供了一个命令行开关来改变行为,所以它甚至不仅仅依赖于平台,而是依赖于编译选项。)
那就是说你可以通过简单地扩展第8位或者在进行转换之前转换为相应的有符号值来将转换为uint32的无符号字符修改为转换有符号字符的相同结果...例如
print(hex(np.uint32(c if c < 128 else c-256)))
答案 3 :(得分:0)
获取uint32数组的一种方法是先将它传递给int8数组:
con_id date_updated type
--------------------------------------------
123 19/06/2018 2
101 07/06/2018 1