我有一个仿函数,它接受一个值,将其转换为 double,获取日志并将值转换回原始类型。对于这个问题,原始和输出类型是 float 。这是原始的 C++ 代码:
return static_cast< TOutput >( std::log( static_cast< double >( A ) ) )
当我在 Debug模式下编译时,一切都按预期进行,GCC 调用底层 log 函数:
51:/myfile.h **** return static_cast< TOutput >( std::log( static_cast< double >( A ) ) );
219133 .loc 112 51 0
219134 0010 488B45F0 movq -16(%rbp), %rax # A, tmp64
219135 0014 F30F1000 movss (%rax), %xmm0 # *A_1(D), D.237346
219136 0018 0F14C0 unpcklps %xmm0, %xmm0 # D.237346, D.237346
219137 001b 0F5AC0 cvtps2pd %xmm0, %xmm0 # D.237346, D.237347
219138 001e E8000000 call log #
219138 00
219139 0023 660F14C0 unpcklpd %xmm0, %xmm0 # D.237347
219140 0027 660F5AC0 cvtpd2ps %xmm0, %xmm0 # D.237347, D.237346
219141 002b F30F1145 movss %xmm0, -20(%rbp) # D.237346, %sfp
219141 EC
219142 0030 8B45EC movl -20(%rbp), %eax # %sfp, <retval>
但是,当我打开优化 (-O2 -ggdb3 -DNDEBUG) 时,它会调用 logf (???) 函数:
51:/myfile.h **** return static_cast< TOutput >( std::log( static_cast< double >( A ) ) );
145171 .loc 64 51 0
145172 01a0 F30F1004 movss (%rdx,%rax,4), %xmm0 # MEM[(const float &)_84], MEM[(const float &)_84]
145172 82
145173 01a5 E8000000 call logf #
它给出了不同的输出。这是正常的吗?我做错什么了吗?在我看来,GCC 对我的代码采取了一种非常自由的解释,如果没有 -ffast-math 选项,我不会期望这种解释。
最佳答案
将 double log应用到float的转换转换为单精度应用的float是一种边界优化>log,但可以说是可以接受的。
假设 logf 被正确四舍五入,并且 double log 也被正确四舍五入或至少忠实地四舍五入,这两个计算几乎不会有差异。由于double-rounding,它们可能不同(对于一些罕见的输入) (其中“double”表示“两次”,不指类型)。与最终类型的有效数字相比,在中间类型的有效数字中有额外的数字,双舍入在统计上的重要性较低(从数学的角度来看,这个统计论点有点垃圾,但它“在实践中有效”的函数没有被设计成反例)。出于教学原因,人们(或维基百科)用一个或两个额外的精度来解释它,但是当你有 53 - 24 = 29 个额外的二进制数字时,它可能会发生在 229.
我对优化感到惊讶,如果我自己编写代码以详尽搜索 log 的双舍入问题,我会对此感到不安,但考虑到 C++ 标准没有从 std::log 要求任何级别的准确性,可以认为它“不是错误”。
如果我们讨论的不是 log,而是基本操作之一(例如 *),那么对于编译器来说,转换是不正确的声称在引入可见更改时提供 IEEE 754 语义。对于基本操作,精度由 IEEE 754 间接规定,规范没有变化的余地。
碰巧对于基本操作,当 floatOP(flx,fly) 替换 (float)doubleOP((double)flx, (double)fly )(这个 thesis 在第 6 章中演示了这一点),但是当类型是 double 和 long double 时可能会有明显的差异。这个确切的错误是recently fixed斯蒂芬·佳能在 Clang 中。
关于c++ - 这个 GCC 优化不正确吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26584903/
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
我正在查看instance_variable_set的文档并看到给出的示例代码是这样做的:obj.instance_variable_set(:@instnc_var,"valuefortheinstancevariable")然后允许您在类的任何实例方法中以@instnc_var的形式访问该变量。我想知道为什么在@instnc_var之前需要一个冒号:。冒号有什么作用? 最佳答案 我的第一直觉是告诉你不要使用instance_variable_set除非你真的知道你用它做什么。它本质上是一种元编程工具或绕过实例变量可见性的黑客攻击
我正在尝试在我的centos服务器上安装therubyracer,但遇到了麻烦。$geminstalltherubyracerBuildingnativeextensions.Thiscouldtakeawhile...ERROR:Errorinstallingtherubyracer:ERROR:Failedtobuildgemnativeextension./usr/local/rvm/rubies/ruby-1.9.3-p125/bin/rubyextconf.rbcheckingformain()in-lpthread...yescheckingforv8.h...no***e
question的一些答案关于redirect_to让我想到了其他一些问题。基本上,我正在使用Rails2.1编写博客应用程序。我一直在尝试自己完成大部分工作(因为我对Rails有所了解),但在需要时会引用Internet上的教程和引用资料。我设法让一个简单的博客正常运行,然后我尝试添加评论。靠我自己,我设法让它进入了可以从script/console添加评论的阶段,但我无法让表单正常工作。我遵循的其中一个教程建议在帖子Controller中创建一个“评论”操作,以添加评论。我的问题是:这是“标准”方式吗?我的另一个问题的答案之一似乎暗示应该有一个CommentsController参
我喜欢使用Textile或Markdown为我的项目编写自述文件,但是当我生成RDoc时,自述文件被解释为RDoc并且看起来非常糟糕。有没有办法让RDoc通过RedCloth或BlueCloth而不是它自己的格式化程序运行文件?它可以配置为自动检测文件后缀的格式吗?(例如README.textile通过RedCloth运行,但README.mdown通过BlueCloth运行) 最佳答案 使用YARD直接代替RDoc将允许您包含Textile或Markdown文件,只要它们的文件后缀是合理的。我经常使用类似于以下Rake任务的东西:
我一直致力于让我们的Rails2.3.8应用程序在JRuby下正确运行。一切正常,直到我启用config.threadsafe!以实现JRuby提供的并发性。这导致lib/中的模块和类不再自动加载。使用config.threadsafe!启用:$rubyscript/runner-eproduction'pSim::Sim200Provisioner'/Users/amchale/.rvm/gems/jruby-1.5.1@web-services/gems/activesupport-2.3.8/lib/active_support/dependencies.rb:105:in`co
我需要一些关于TDD概念的帮助。假设我有以下代码defexecute(command)casecommandwhen"c"create_new_characterwhen"i"display_inventoryendenddefcreate_new_character#dostufftocreatenewcharacterenddefdisplay_inventory#dostufftodisplayinventoryend现在我不确定要为什么编写单元测试。如果我为execute方法编写单元测试,那不是几乎涵盖了我对create_new_character和display_invent
如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:
我在OSX上(如果重要的话)。如果我使用RVM安装Ruby,它会默认将Bundler安装到@globalgemset假设我想要一个不同版本的bundler。我假设我需要做的就是执行geminstallbundler--version但是,这会将bundler安装到默认gemset并且RVM不会为其设置路径。因此,如果我键入bundler,它仍会启动一个与Ruby一起安装到@global中的bundler两个问题:如何将bundler安装到@globalgemset。将bundler安装到@globalgemset中的模式是否正确,或者我遗漏了什么 最佳答案
我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我