- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
自从调整了一些代码以启用多精度后,我的一些单元测试开始失败。头文件:
#ifndef SCRATCH_UNITTESTBOOST_INCLUDED
#define SCRATCH_UNITTESTBOOST_INCLUDED
#include <boost/multiprecision/cpp_dec_float.hpp>
// typedef double FLOAT;
typedef boost::multiprecision::cpp_dec_float_50 FLOAT;
const FLOAT ONE(FLOAT(1));
struct Rect
{
Rect(const FLOAT &width, const FLOAT &height) : Width(width), Height(height){};
FLOAT getArea() const { return Width * Height; }
FLOAT Width, Height;
};
#endif
主要测试文件:
#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MODULE RectTest
#include <boost/test/unit_test.hpp>
#include "SCRATCH_UnitTestBoost.h"
namespace utf = boost::unit_test;
// Failing
BOOST_AUTO_TEST_CASE(AreaTest1)
{
Rect R(ONE / 2, ONE / 3);
FLOAT expected_area = (ONE / 2) * (ONE / 3);
std::cout << std::setprecision(std::numeric_limits<FLOAT>::digits10) << std::showpoint;
std::cout << "Expected: " << expected_area << std::endl;
std::cout << "Actual : " << R.getArea() << std::endl;
// BOOST_CHECK_EQUAL(expected_area, R.getArea());
BOOST_TEST(expected_area == R.getArea());
}
// Tolerance has no effect?
BOOST_AUTO_TEST_CASE(AreaTestTol, *utf::tolerance(1e-40))
{
Rect R(ONE / 2, ONE / 3);
FLOAT expected_area = (ONE / 2) * (ONE / 3);
BOOST_TEST(expected_area == R.getArea());
}
// Passing
BOOST_AUTO_TEST_CASE(AreaTest2)
{
Rect R(ONE / 7, ONE / 2);
FLOAT expected_area = (ONE / 7) * (ONE / 2);
BOOST_CHECK_EQUAL(expected_area, R.getArea());
}
请注意,在定义
FLOAT
时作为
double
类型,所有测试通过。让我感到困惑的是,当打印确切的预期值和实际值(参见 AreaTest1)时,我们会看到相同的结果。但是
BOOST_TEST
报错是:
error: in "AreaTest1": check expected_area == R.getArea() has failed
[0.16666666666666666666666666666666666666666666666666666666666666666666666666666666 !=
0.16666666666666666666666666666666666666666666666666666666666666666666666672236366]
使用
g++ SCRATCH_UnitTestBoost.cpp -o utb.o -lboost_unit_test_framework
编译.
tolerance
在 AreaTestTol
不按照文档提供输出 here ? 最佳答案
两个问题:
T x = 1/3;
T y = 1/7;
这实际上会不精确地近似这两个分数。
T z = 1/3 * 1/7;
将实际评估右侧
表达式模板 , 所以不要像
x
这样计算临时变量回答
y
之前,右手边有一个类型:
expression<detail::multiplies, detail::expression<?>, detail::expression<?>, [2 * ...]>
boost::multiprecision::detail::expression<
boost::multiprecision::detail::multiplies,
boost::multiprecision::detail::expression<
boost::multiprecision::detail::divide_immediates,
boost::multiprecision::number<boost::multiprecision::backends::cpp_dec_float<50u,
int, void>, (boost::multiprecision::expression_template_option)1>, int,
void, void>,
boost::multiprecision::detail::expression<
boost::multiprecision::detail::divide_immediates,
boost::multiprecision::number<boost::multiprecision::backends::cpp_dec_float<50u,
int, void>, (boost::multiprecision::expression_template_option)1>, int,
void, void>,
void, void>
长话短说,这就是您想要的,因为它可以节省您的工作并保持更好的准确性,因为表达式首先被标准化为
1/(3*7)
所以
1/21
.
using T = boost::multiprecision::number<
boost::multiprecision::cpp_dec_float<50>,
boost::multiprecision::et_off > >;
T expected_area = T(ONE / 7) * T(ONE / 2);
T expected_area = (ONE / 7).eval() * (ONE / 2).eval();
BOOST_CHECK_EQUAL(expected_area, R.getArea());
T const eps = std::numeric_limits<T>::epsilon();
BOOST_CHECK_CLOSE(expected_area, R.getArea(), eps);
BOOST_TEST(expected_area == R.getArea(), tt::tolerance(eps));
这失败了第一个,并通过了最后两个。确实,除此之外,以下两个也失败了:
BOOST_CHECK_EQUAL(expected_area, R.getArea());
BOOST_TEST(expected_area == R.getArea());
因此,在
utf::tolerance
之前似乎必须做一些事情。装饰器生效。使用 native double 测试告诉我只有
BOOST_TEST
隐式应用公差。所以潜入了预处理扩展:
::boost::unit_test::unit_test_log.set_checkpoint(
::boost::unit_test::const_string(
"/home/sehe/Projects/stackoverflow/test.cpp",
sizeof("/home/sehe/Projects/stackoverflow/test.cpp") - 1),
static_cast<std::size_t>(42));
::boost::test_tools::tt_detail::report_assertion(
(::boost::test_tools::assertion::seed()->*a == b).evaluate(),
(::boost::unit_test::lazy_ostream::instance()
<< ::boost::unit_test::const_string("a == b", sizeof("a == b") - 1)),
::boost::unit_test::const_string(
"/home/sehe/Projects/stackoverflow/test.cpp",
sizeof("/home/sehe/Projects/stackoverflow/test.cpp") - 1),
static_cast<std::size_t>(42), ::boost::test_tools::tt_detail::CHECK,
::boost::test_tools::tt_detail::CHECK_BUILT_ASSERTION, 0);
} while (::boost::test_tools::tt_detail::dummy_cond());
深入挖掘,我遇到了:
/*!@brief Indicates if a type can be compared using a tolerance scheme
*
* This is a metafunction that should evaluate to @c mpl::true_ if the type
* @c T can be compared using a tolerance based method, typically for floating point
* types.
*
* This metafunction can be specialized further to declare user types that are
* floating point (eg. boost.multiprecision).
*/
template <typename T>
struct tolerance_based : tolerance_based_delegate<T, !is_array<T>::value && !is_abstract_class_or_function<T>::value>::type {};
我们有它!但不是,
static_assert(boost::math::fpc::tolerance_based<double>::value);
static_assert(boost::math::fpc::tolerance_based<cpp_dec_float_50>::value);
两者都已经通过了。唔。
utf::tolerance(v)
中的静态类型匹配您的操作数test_tools::tolerance
而不是依靠“环境”容忍。毕竟,我们想要测试我们的代码,而不是测试框架 template <typename T> struct Rect {
Rect(const T &width, const T &height) : width(width), height(height){};
T getArea() const { return width * height; }
private:
T width, height;
};
#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MODULE RectTest
#include <boost/multiprecision/cpp_dec_float.hpp>
using DecFloat = boost::multiprecision::cpp_dec_float_50;
#include <boost/test/unit_test.hpp>
namespace utf = boost::unit_test;
namespace tt = boost::test_tools;
namespace {
template <typename T>
static inline const T Eps = std::numeric_limits<T>::epsilon();
template <typename T> struct Fixture {
T const epsilon = Eps<T>;
T const ONE = 1;
using Rect = ::Rect<T>;
void checkArea(int wdenom, int hdenom) const {
auto w = ONE/wdenom; // could be expression templates
auto h = ONE/hdenom;
Rect const R(w, h);
T expect = w*h;
BOOST_TEST(expect == R.getArea(), "1/" << wdenom << " x " << "1/" << hdenom);
// I'd prefer explicit toleranc
BOOST_TEST(expect == R.getArea(), tt::tolerance(epsilon));
}
};
}
BOOST_AUTO_TEST_SUITE(Rectangles)
BOOST_FIXTURE_TEST_SUITE(Double, Fixture<double>, *utf::tolerance(Eps<double>))
BOOST_AUTO_TEST_CASE(check2_3) { checkArea(2, 3); }
BOOST_AUTO_TEST_CASE(check7_2) { checkArea(7, 2); }
BOOST_AUTO_TEST_CASE(check57_31) { checkArea(57, 31); }
BOOST_AUTO_TEST_SUITE_END()
BOOST_FIXTURE_TEST_SUITE(MultiPrecision, Fixture<DecFloat>, *utf::tolerance(Eps<DecFloat>))
BOOST_AUTO_TEST_CASE(check2_3) { checkArea(2, 3); }
BOOST_AUTO_TEST_CASE(check7_2) { checkArea(7, 2); }
BOOST_AUTO_TEST_CASE(check57_31) { checkArea(57, 31); }
BOOST_AUTO_TEST_SUITE_END()
BOOST_AUTO_TEST_SUITE_END()
打印
关于c++ - 带有 boost::multiprecision 的单元测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62726097/
在 rng 中使用固定种子时,如果精度变化,结果将无法重现。即,如果更改模板参数 cpp_dec_float并运行以下代码,会看到不同的输出(对于精度的每次变化)。 #include #includ
我一直在关注 documentation from the boost library生成多精度随机整数,但在文档中没有提到如何设置种子。 我不知道如何在不出现编译错误的情况下设置种子。 #inclu
我需要将IPv6字符串地址转换为boost::multiprecision::uint128_t 对于IPv4,我使用以下算法: uint32_t byte1 = 0, byte2 = 0, byte
自从调整了一些代码以启用多精度后,我的一些单元测试开始失败。头文件: #ifndef SCRATCH_UNITTESTBOOST_INCLUDED #define SCRATCH_UNITTESTBO
我正在尝试使用 boost::multiprecision 库进行浮点(或者在那种情况下,固定)点运算。但是,我无法通过以下方式检测潜在的溢出: typedef boost::multiprecisi
如果我有: 字符缓冲区[16]; 如何将其原始字节转换为: boost::multiprecision::uint128_t ? 我尝试进行标准的 C 风格转换: uint128_t myInt =
我正在使用 boost::multiprecision 来获得固定但任意精度的整数。我打算使用 number> .第一个明显的问题是: 此数据类型是否具有给定精度的任何无符号整数的标准位模式?我听说有
我使用 boost::multiprecision::uint128_t 类型来对 128 位值执行按位运算。但是,我无法将 128 位值写入二进制文件。特别是需要用零填充值。 例如,如果 uint1
http://www.boost.org/doc/libs/1_53_0/libs/multiprecision/doc/html/index.html 我刚刚开始探索这个图书馆。似乎没有办法将 cp
我读过 boost::multiprecision documentation : Depending upon the number type, precision may be arbitrari
如何将字符串转换为“boost::multiprecision::cpp_int”? 此外,我有一个 .txt 文件,其中包含 100 个数字,每个数字 50 个数字,我使用 ifstream 将它们
我需要以任意精度获取一个值的散列值(来自 Boost.Multiprecision);我用 cpp_int后端。我想出了以下代码: boost::multiprecision::cpp_int x0
考虑以下使用 boost 创建多精度 float “a”的代码。 如何使用boost库调用三角函数?比如我希望计算sin(a)。 #include #include "boost/multiprec
我正在尝试转换 boost::multiprecision::cpp_dec_float_x到 boost::multiprecision::uintx_t .所以基本上是 boost bigreal
我尝试创建一个派生自 boost::multiprecision::mpz_int 的类并让它继承基类构造函数: #include using namespace boost::multipreci
我需要从 boost::multiprecision::int128_t 转换至 double . 对于较小的整数,我使用: template flt_t as_flt() const { ret
我正在尝试使用Ramanujan's公式为浮点后的任意位数计算我的大学项目之一的pi。对于这项工作,我使用的boost::multiprecision库只是我已经安装在计算机上的mpfr和mpir的包
关于 this answer ,有一个使用 boost::multiprecision 和 boost::random 的最小示例。 当我使用种子时,我正在努力解决这个例子: #include #i
我有一些模板代码,编译器可以尾调用优化大多数数据类型,但不能优化其他数据类型。代码实现pow() template void powRecurse(T& x, U& y, T& acc) { i
我需要两个函数: std::vector bigint_to_bytes(cpp_int a); cpp_int bytes_to_bigint(std::vector const& a); goog
我是一名优秀的程序员,十分优秀!