下面的Python3+代码试图编译一个Cpp脚本,并使用它从float转换为int,同时保持内存不变;详情如下:
import sys, os
import numpy as np
import matplotlib.pyplot as plt
# Build a C++ Script that accepts a str,
# converts it to a float, and prints
# the result of the operation
def build():
script = """
#include<iostream>
int main(int argc, char *argv[]){
float f = std::stof(argv[1]);
int i = *(short *)&f;
std::cout << f << " " << i <<std::endl;
return 0;
}
"""
with open('script.cpp', 'w') as f:
f.write(script)
return 1
# Loads the results from the C++ script
def load_results():
x,y = [],[]
with open('results-ctest.txt', 'r') as f:
result = f.readlines()
for _ in result:
local = _.split(' ')
x.append(float(local[0]))
y.append(int(local[1][:-2]))
return x,y
# Plots the results from the C++ script
def show_results(x,y):
# Define a figure
f,ax = plt.subplots()
# Plot results
ax.scatter(x,y)
# Format the axis according to the shown figure
ax.set_xticks(np.linspace(min(x), max(x), 20))
ax.set_yticks(np.linspace(min(y), max(y), 20))
plt.show()
if __name__=='__main__':
# build the C++ script
build()
# Compile the C++ script
# and clean the previous results
# by removing "results-ctest.txt"
os.system(f'g++ script.cpp')
os.system('rm results-ctest.txt')
# Generate 500 floats between -1.000.000 and 1.000.000
# and pass them to the C++ script
numbers=np.linspace(-1e6, 1e6, 500)
for number in numbers:
os.system(f'./a.out {number}>> results-ctest.txt')
# Open the results of the C++ script and
# split the input from the output
x,y = load_results()
# Produce the figure and open
# a window for it
show_results(x,y)
明显的问题是,(输出)整数与(输入)浮点数如下:
然而,如果“int”和“float”都是根据下图用4个字节实现的,那么输入和输出应该具有相同的符号
总结如下:使用C++创建int,并且它的符号没有按照第一个图所示保存。
float f = std::stof(argv[1]);
int i = *(short *)&f;
多谢各位
编辑: 底线是有一个打字错误。 我编辑问题是为了显示“正确”的情节
如评论中所述,问题在于以下几行:
int i = *(short *)&f;
应该是:
int i = *(int *)&f;
代码的第一个问题是,将一种类型的数据作为另一种不相关的类型读取(没有某些属性,如公共前缀),或者使用一些类型(如
std::byte
或char
),这是一种未定义的行为std::bit_cast
是一种c++20正确执行的方法第二个问题是,精确位的含义会因计算机的端度和使用的浮点标准等因素而有所不同。现在这些都是相对标准的,但还不完全
第三个问题是,short、int和float的大小是特定于平台和编译器的。您可以使用固定大小的整数类型,如
std::int32_t
,您应该使用它而不是int
或short
。通常short
是16位int
是32位,但这远不是通用的float
32位确实很常见因此:
至少可以解决大部分疯狂的问题
我不知道从浮点转换为整数时,endianness转换会有什么问题。我想说的是:
也可以根据体系结构的端性来转储
f
的位。然后取一个浮点值,它的位表示形式是已知的(并且不是所有的0),看看这会产生什么相关问题 更多 >
编程相关推荐