【发布时间】:2021-03-02 19:35:46
【问题描述】:
我对 C++ 中的舍入模式有疑问。我想更改舍入模式,看看我们是否可以得到给定变量的上限和下限。
通过使用以下代码运行一些玩具示例,我可以获得一些超级奇怪的观察结果。
#include <iostream>
#include <iomanip>
#include <string>
#include <cfenv>
#include <cmath>
void test_c(const bool rounding_up, const float x)
{
#pragma STDC FENV_ACCESS ON
float y = 1e-6;
if (rounding_up){
std::fesetround(FE_UPWARD);
std::cout << std::setprecision(10) << "x_up_python " << x << "\n";
std::cout << std::setprecision(10) << "y_up_c++ " << y << "\n";
}
else{
std::fesetround(FE_DOWNWARD);
std::cout << std::setprecision(10) << "x_down_python " << x << "\n";
std::cout << std::setprecision(10) << "y_down_c++ " << y << "\n";
}
}
extern "C" {
void test(const bool rounding_up, const float x){
test_c(rounding_up, x);
}
}
import os
import numpy as np
from numpy.ctypeslib import ndpointer
import ctypes
from ctypes import cdll
from ctypes import *
os.system('g++ -c -fPIC post_processing.cpp -o post_processing.o')
os.system('g++ -shared -Wl,-soname,lib_rounding.so -o lib_rounding.so post_processing.o')
lib = cdll.LoadLibrary('./lib_rounding.so')
def test(x, rounding_up=True):
lib.test.restype = None
lib.test.argtypes = [ctypes.c_bool, ctypes.c_float]
lib.test(rounding_up, x)
if __name__ == '__main__':
x = 1e-6
test(x, True)
test(x, False)
首先,我们来看看y。如果舍入模式设置为FE_UPWARD,则结果值为9.999999975e-07。相比之下,如果舍入模式设置为FE_DOWNWARD,则结果值为9.999999974e-07。
其次,如果我在python 脚本中定义x=1e-6,然后使用ctype 将x 传递给这个C 函数。结果反过来,即FE_UPWARD返回9.999999975e-07,FE_DOWNWARD返回1.000000111e-06。
所以,我总共有 2 个问题:
-
对于第一个观察,为什么它们都小于
1e-6? -
至于第二个观察,为什么这两个值的关系是相反的?
非常感谢!
【问题讨论】:
-
请同时显示用于调用该函数的 Python 代码。
-
嗨,我刚刚添加了 Python 代码和左侧的 C++ 代码。