Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/316.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
Python 不应该';";int i=*(短*)&;浮动;保留标志?(C+;+;)_Python_C++_C++20 - Fatal编程技术网

Python 不应该';";int i=*(短*)&;浮动;保留标志?(C+;+;)

Python 不应该';";int i=*(短*)&;浮动;保留标志?(C+;+;),python,c++,c++20,Python,C++,C++20,下面的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():

下面的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 i = *(short *)&f;
应该是:

int i = *(int *)&f;
从而得出以下图表:

代码的第一个问题是,将一种类型的数据作为另一种不相关的类型读取是一种未定义的行为,没有某些属性,例如公共前缀,或者使用一些类型,例如
std::byte
char

std::bit_cast
是正确执行此操作的一种方法

第二个问题是,精确位的含义会因计算机的端度和使用的浮点标准等因素而有所不同。现在这些都是相对标准的,但还不完全

第三个问题是,short、int和float的大小是特定于平台和编译器的。您可以使用固定大小的整数类型,如
std::int32_t
,您应该使用它而不是
int
short
。通常
short
是16位,
int
是32位,但这远不是通用的<代码>浮点为32位是非常常见的

因此:

std::int32\u t i=std::位转换(f);

std::cout
short
可能是2个字节,而不是4个。
inti=*(short*)&f--比尔·林奇给出了你问题的实际答案。另一方面,您正在调用未定义的行为,请参见例如。如果你想在没有定义行为的情况下实现同样的事情,请使用<代码> MycPy< /Cord>。这不是C++中如何将浮点转换为int值的方法。哪本C++教材教你这个?无论是哪一种,你都需要一本更好的C++教材。@ SAMVARSHIVCHIK我怀疑这是关于数值转换的,我想他真的想看看浮点的字节表示如何映射到整数。这是一个很好的注释,扩展了打印错误(请阅读编辑)并添加更多的信息。我会接受它,希望您能抽出时间补充一点,说明
int I=*(int*)&f
是如何保留登录的,据我所知,这可能是大多数vainilla实现。谢谢
int i = *(int *)&f;
std::int32_t i = std::bit_cast<std::int32_t>(f);

std::cout << f << " " << i <<std::endl;
std::uint32_t ui = std::bit_cast<std::uint32_t>(f);
std::cout << f << " 0b";
for (int i = 0; i < 32; ++i)
  std::cout << (ui&(1<<i));

std::int32_t i = std::bit_cast<std::int32_t>(f);
std::cout << " " << i <<std::endl;