草庐IT

c++ - NAN -> 区分除以零和具有非常大的负值的指数

coder 2024-02-22 原文

我包括了一个 check for nan's在我的测试套件中。

现在在下一行抛出一个 SIGFPE

const double retVal =exp(exponent); 

指数的值大约为 -4000。这当然非常接近于零,如果没有 nan 检查,计算将继续为零。

信号 SIGFPE 现在被抛出。我假设这是一个 denormal number (表示为 NAN)。

如何区分被零除和具有非常大负值的指数?

在第二种情况下,在我的情况下使用零进行进一步计算,因为我不需要区分 +0 和 -0。

编辑: 我尝试了@user2079303 的建议。我的代码看起来像这样

#include <signal.h>
void fpe_handler(int signo, siginfo_t *info, void *context) {
    switch(info->si_code) {
        case FPE_INTDIV: // division by zero
            break;
        case FPE_FLTUND: // underflow
            break;
        // other cases ...
    }
}

int main() {
    struct sigaction action = {};
    action.sa_flags     = SA_SIGINFO;
    action.sa_sigaction = fpe_handler;
    sigaction(SIGFPE, &action, NULL);
    const double a = 0.0/0.0;
    if (a>0) 
        return 0;
    else
        return 1;
}

这会编译,但不会抛出信号或错误消息。

最佳答案

从技术上讲,从 C++ 的角度来看,被零除具有未定义的行为,因此没有标准的方法来处理它。


在无处不在的 IEEE 754 标准中,除以零定义明确,不会发出信号。可以使用 <cfenv> 测试先前执行的计算是否除以零 header :

std::feclearexcept(FE_ALL_EXCEPT);
// do calculation here
if(std::fetestexcept(FE_DIVBYZERO)) {
    // I was just divided by zero. The sky is falling.
    std::abort();
} else if(std::fetestexcept(FE_UNDERFLOW)) {
    // I just underflowed. This is my life now.
}

现在,将一个普通 float 除以零不会产生信号,除非您要求它使用 feenableexcept (这是一个 GNU 扩展;非标准)。

在标准 C++ 中无法区分 SIGFPE 的不同原因。但是有 a way in POSIX标准:

void fpe_handler(int signo, siginfo_t *info, void *context)
{
    switch(info->si_code) {
        case FPE_FLTDIV: // division by zero
            break;
        case FPE_FLTUND: // underflow
            break;
        // other cases ...
    }
}

// registering
struct sigaction action = {};
action.sa_flags     = SA_SIGINFO;
action.sa_sigaction = fpe_handler;
sigaction(SIGFPE, &action, NULL);

关于c++ - NAN -> 区分除以零和具有非常大的负值的指数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46193656/

有关c++ - NAN -> 区分除以零和具有非常大的负值的指数的更多相关文章

  1. ruby - 具有身份验证的私有(private) Ruby Gem 服务器 - 2

    我想安装一个带有一些身份验证的私有(private)Rubygem服务器。我希望能够使用公共(public)Ubuntu服务器托管内部gem。我读到了http://docs.rubygems.org/read/chapter/18.但是那个没有身份验证-如我所见。然后我读到了https://github.com/cwninja/geminabox.但是当我使用基本身份验证(他们在他们的Wiki中有)时,它会提示从我的服务器获取源。所以。如何制作带有身份验证的私有(private)Rubygem服务器?这是不可能的吗?谢谢。编辑:Geminabox问题。我尝试“捆绑”以安装新的gem..

  2. ruby-on-rails - 如何从 format.xml 中删除 <hash></hash> - 2

    我有一个对象has_many应呈现为xml的子对象。这不是问题。我的问题是我创建了一个Hash包含此数据,就像解析器需要它一样。但是rails自动将整个文件包含在.........我需要摆脱type="array"和我该如何处理?我没有在文档中找到任何内容。 最佳答案 我遇到了同样的问题;这是我的XML:我在用这个:entries.to_xml将散列数据转换为XML,但这会将条目的数据包装到中所以我修改了:entries.to_xml(root:"Contacts")但这仍然将转换后的XML包装在“联系人”中,将我的XML代码修改为

  3. ruby-on-rails - 如何优雅地重启 thin + nginx? - 2

    我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server

  4. ruby - Infinity 和 NaN 的类型是什么? - 2

    我可以得到Infinity和NaNn=9.0/0#=>Infinityn.class#=>Floatm=0/0.0#=>NaNm.class#=>Float但是当我想直接访问Infinity或NaN时:Infinity#=>uninitializedconstantInfinity(NameError)NaN#=>uninitializedconstantNaN(NameError)什么是Infinity和NaN?它们是对象、关键字还是其他东西? 最佳答案 您看到打印为Infinity和NaN的只是Float类的两个特殊实例的字符串

  5. ruby-on-rails - rspec should have_select ('cars' , :options => ['volvo' , 'saab' ] 不工作 - 2

    关闭。这个问题需要detailsorclarity.它目前不接受答案。想改进这个问题吗?通过editingthispost添加细节并澄清问题.关闭8年前。Improvethisquestion在首页我有:汽车:VolvoSaabMercedesAudistatic_pages_spec.rb中的测试代码:it"shouldhavetherightselect"dovisithome_pathit{shouldhave_select('cars',:options=>['volvo','saab','mercedes','audi'])}end响应是rspec./spec/request

  6. ruby-on-rails - Nokogiri:使用 XPath 搜索 <div> - 2

    我使用Nokogiri(Rubygem)css搜索寻找某些在我的html里面。看起来Nokogiri的css搜索不喜欢正则表达式。我想切换到Nokogiri的xpath搜索,因为这似乎支持搜索字符串中的正则表达式。如何在xpath搜索中实现下面提到的(伪)css搜索?require'rubygems'require'nokogiri'value=Nokogiri::HTML.parse(ABBlaCD3"HTML_END#my_blockisgivenmy_bl="1"#my_eqcorrespondstothisregexmy_eq="\/[0-9]+\/"#FIXMEThefoll

  7. ruby-on-rails - Rails 3.1 中具有相同形式的多个模型? - 2

    我正在使用Rails3.1并在一个论坛上工作。我有一个名为Topic的模型,每个模型都有许多Post。当用户创建新主题时,他们也应该创建第一个Post。但是,我不确定如何以相同的形式执行此操作。这是我的代码:classTopic:destroyaccepts_nested_attributes_for:postsvalidates_presence_of:titleendclassPost...但这似乎不起作用。有什么想法吗?谢谢! 最佳答案 @Pablo的回答似乎有你需要的一切。但更具体地说...首先改变你View中的这一行对此#

  8. ruby - 使用 `+=` 和 `send` 方法 - 2

    如何将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.你能做的最好的事情是:

  9. ruby - 如何计算 Liquid 中的变量 +1 - 2

    我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我

  10. ruby - 具有两个参数的 block - 2

    我从用户Hirolau那里找到了这段代码:defsum_to_n?(a,n)a.combination(2).find{|x,y|x+y==n}enda=[1,2,3,4,5]sum_to_n?(a,9)#=>[4,5]sum_to_n?(a,11)#=>nil我如何知道何时可以将两个参数发送到预定义方法(如find)?我不清楚,因为有时它不起作用。这是重新定义的东西吗? 最佳答案 如果您查看Enumerable#find的文档,您会发现它只接受一个block参数。您可以将它发送两次的原因是因为Ruby可以方便地让您根据它的“并行赋

随机推荐