为什么这个函数会产生错误的值? [复制]

2024-04-06

我有一个简单的函数模板来计算容器的平均值:

template<typename T>
T array_average( std::vector<T>& values ) {
    if( std::is_arithmetic<T>::value ) {
        if( !values.empty() ) {
            if( values.size() == 1 ) {
                return values[0];
            } else { 
                return (static_cast<T>( std::accumulate( values.begin(), values.end(), 0 )  ) / static_cast<T>( values.size() ) );
            }
        } else {
            throw std::runtime_error( "Can not take average of an empty container" ); 
        }
    } else {
        throw std::runtime_error( "T is not of an arithmetic type" );
    }
}

我添加在static_cast<>尝试将计算强制为所需类型<T>.

当我在 main 中使用uint64_t

std::vector<uint64_t> values{ 1,2,3,4,5,6,7,8,9,10,11,12 };
std::cout << array_average( values ) << '\n';

此代码确实会产生 MSVC 的编译器警告C4244由于转换可能会丢失数据,但它运行正常,这给了我预期的结果并打印出来6到控制台。这是正确的,因为实际值是6.5但由于整数除法的截断6是正确的。

现在如果我使用上面的函数来代替:

std::vector<double> values { 2.0, 3.5, 4.5, 6.7, 8.9 };
std::cout << array_average( values2 ) << '\n';

这应该给我一个结果5.12然而它正在显示4.6反而。这也给了我与上面相同的编译器警告,但它运行时没有运行时错误(执行中断),但给了我不正确的结果。

我不确定我的函数中的错误在哪里。我不知道这是否是由于编译器警告所致,或者是否是我设计函数本身的方式。


-Edit-

用户建议这可能与此重复Q/A https://stackoverflow.com/questions/20735841/why-is-the-stdaccumulate-function-showing-the-wrong-sum-of-a-vectordouble我无法反驳它是否回答了我的问题这一事实。在问这个问题时;我不知道该错误是由于使用不当造成的std::accumulate本身。我不确定它是否来自编译器警告,该警告与由于转换可能导致的数据丢失有关,或者我是否将其转换错误,或者是否是我一般实现此函数的方式。在提供链接之前,我已经接受了在此页面上找到的答案。我将保留此问答以供将来参考和读者!除此之外,我确实很欣赏提供的链接,因为它确实有助于了解错误在我的代码中的位置、错误是什么以及导致错误的原因,以及除了本页上接受的答案之外如何正确修复它。


Your static_cast是在错误的地方。您正在投射result的累积,但让累积以初始项的类型运行(这里0,即int)。因此,请这样做:

return std::accumulate( values.begin(), values.end(), static_cast<T>(0) ) / static_cast<T>( values.size() );

(请注意,4.6 确实是static_cast<double>(2 + 3 + 4 + 6 + 8) / 5.0).


与问题核心无关的评论:

  • 该功能应该采取const std::vector<T>&,因为它不会修改values.
  • 如果你用一个调用该函数T这不适用于std::accumulate(例如不是算术),您将收到编译时错误。最上面的if必须是if constexpr以您想要的方式工作。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么这个函数会产生错误的值? [复制] 的相关文章

随机推荐

  • 如何从 viewcontainer 角度删除特定视图

    在下面的示例中 https stackblitz com edit angular 1acvol https stackblitz com edit angular 1acvol 我使用创建了多个视图TemplateRef并将它们附加到同一
  • 异步加载车把模板

    我正在尝试编写一个函数 该函数将为我提供一个已编译的车把模板 我将所有模板都放在单独的文件中 使用 ajax 调用来获取模板并编译它以供使用 但我需要使用承诺 以便我可以实际使用它 function getTemplate name get
  • Python,OpenCV:增加图像亮度而不溢出UINT8数组

    我正在尝试增加灰度图像的亮度 cv2 imread 返回一个 numpy 数组 我正在向数组的每个元素添加整数值 从理论上讲 这会增加它们中的每一个 之后我就可以将上限设置为 255 并获得具有更高亮度的图像 这是代码 grey cv2 i
  • 连接建立后如何从服务器(使用连接列表)向客户端发送命令?

    我有这两个类 它们是我的服务器应用程序 桌面 的一部分 需要在建立连接后将命令发送回客户端 当我尝试这样做时 clients i Send info the Send 例行公事 的监听器 cs 可以访问 但我有以下语法错误 怎么解决这个问题
  • CSS 关键帧动画与平移变换在 IE 10 和 Firefox 中捕捉到整个像素

    看起来 IE 10 和 Firefox 在使用 css 关键帧动画中的平移 2d 变换对元素的位置进行动画处理时 都会将元素捕捉到整个像素 Chrome 和 Safari 没有 看起来a lot制作微妙运动动画时效果更好 动画是通过以下方式
  • 2 个不同长度的排序数组的中值

    如何找到长度分别为 m 和 n 的 2 个已排序数组 A 和 B 的中位数 我已经搜索过 但大多数算法都假设两个数组的大小相同 我想知道如果 m n 我们怎样才能找到中位数 考虑例子 A 1 3 5 7 11 15 其中 m 6 B 2 4
  • 在 AngularJS 中处理来自代理的 HTTP 302 响应

    我有一个反向代理 可以检查多个应用程序的全局身份验证 当用户断开连接但仍尝试使用我的应用程序时 代理会发送 302 响应 HTTP 1 1 302 Found Date Wed 11 Sep 2013 09 05 34 GMT Cache
  • 生成递归目录搜索的 XML 映射

    我正在阅读一个列表 其中某些组件下有大量档案 例如 component1 filelocation1 a11 ear component1 filelocation1 a12 ear component2 filelocation2 a2
  • 如何在Rails 3.2 erb中使用eval在运行时执行存储在字符串中的视图代码?

    我们想要做的是存储一大块erb代码在一个string然后在运行时执行代码 这是我们所做的测试 从工作的 erb 文件中取出一段代码 使用 eval 重写 erb 文件 这是取出的 erb 代码块 tr th th th th th th t
  • [Laravel]:SQLSTATE[3F000]:模式名称无效

    构建 Laravel 项目 v 5 4 当我运行时php artisan migrate我收到以下错误消息 Illuminate Database QueryException SQLSTATE 3F000 Invalid schema n
  • Mockk-spyk 模拟方法仅一次

    I have spyk from mockk图书馆 my spyk My 后来我嘲笑其中一种方法返回类似的内容 every my method someString returns something 我正在创建这个spyk in a Be
  • 获取具有默认值的参数列表

    我使用 ALL ARGUMENTS 来获取 oracle 10g 中的参数列表 但我找不到参数是否有默认值 我怎样才能做到呢 您可能需要在 10g 中采用 plsql 编程 如下面的代码示例所示 从某种意义上说 这个解决方案肯定是蛮力的 因
  • 如何在 javascript Chart.js 中仅显示整数

    我想在java脚本库创建的图表中仅显示整数而不是浮点数Chartjs org http www chartjs org docs 这是示例的链接graph http qlu in 0o3CTx stats 我是新手 有人可以帮我配置这个吗
  • THREE.JS 加载 STL 网格数组

    因此 我有一个数据库 其中包含文件引用列以及对其所需的子 STL 文件的任何引用 我可以将一两个模型加载到 THREE js 查看器中 因此所有这些都可以正常工作 但是当我加载四个左右的数组时 事情开始变得毛茸茸的 分配的网格 ID 开始变
  • Android 设计模式,用于 UI 和非 UI 模式的后台操作

    我有一个后台操作 我希望能够以两种模式运行 UI mode 由用户启动 在整个生命周期内为用户提供操作状态的精确反馈 非用户界面模式 由AlarmManager并在其生命周期结束时向用户提供操作摘要 自然的设计选择只为实现UI mode将会
  • 如何使用 Inno Setup 连接到 MS SQL Server?

    我想在安装过程中连接到 MS SQL Server 2008 有一个类似的问题 https stackoverflow com q 2171199 960757 它提供了一个解决方案 使用isql exe工具 与 SQL Server 20
  • MS Dynamics CRM 2012:脚本编辑器增强功能

    我一直在尝试查找有关下一个 Microsoft Dynamics CRM 产品 2012 6 的更多信息 我主要对脚本编辑器的任何增强感兴趣 版本 4 和版本 5 2011 之间有很大的改进 最受我欢迎的是跨表单 字段事件共享脚本函数的能力
  • HBase单调递增键的行键设计

    我有一个 HBase 表 我在其中编写行键 例如
  • Tailwind 全局使用本地文件中的字体

    目前我正在我的风格标签中这样做 import url https fonts googleapis com css family Roboto display swap font family Roboto sans serif 但我下载了
  • 为什么这个函数会产生错误的值? [复制]

    这个问题在这里已经有答案了 我有一个简单的函数模板来计算容器的平均值 template