輝夜's profileKaguya Houraisan's glori...PhotosBlogListsMore Tools Help

Blog


    November, 2009

    又一次吃了浮点数的亏 = =

    C++:
    while(step > 0.02){
        for(;;){
            if(x+step <= 100.0 &&
                (ttlen = ttl(x+step, y)) < minlength){
                minlength = ttlen;
                x += step;
            } else if(x-step >=0.0 &&
                (ttlen = ttl(x-step, y)) < minlength){
                minlength = ttlen;
                x -= step;
            } else if(y+step <= 100.0 &&
                (ttlen = ttl(x, y+step)) < minlength){
                minlength = ttlen;
                y += step;
            } else if(y-step >= 0.0 &&
                (ttlen = ttl(x, y-step)) < minlength){
                minlength = ttlen;
                y -= step;
            } else break;
        }
        step /= 2.0;
    }
     
    在 x-y 平面上寻找一个对 ttl 函数的极值点。先用 step 为步长寻找,然后步长减半再找,直到满足一定精度为止。
    逻辑上过程上都很简单才对,可惜以上代码在 VC2008 运行正确,用 Gcc 却陷入死循环。
     
    调试下发现居然出现了这种情况:在 A 点时发现 B 比 A 小,然后在 B点 发现 C 比 B 小,而在 C点 又发现 A 更小……于是就在这几个点上跳不出来了。
    其实以前也看过不少强调处理浮点数比较时要特别注意的地方,但每个地方都特别写一下又很麻烦,而且觉得 double 的精度够高应该不用担心,没想到还是出了问题。VC 里大概对浮点数的比较运算做了特殊处理才没出错,感觉在这种很细节的地方 VC 非常强调安全性,但可能有时候也会觉得多此一举或是担心性能上的影响吧。
    总之发现问题所在就好解决了,(ttlen = ttl(x, y+step)) < minlength 改为 (ttlen = ttl(x, y+step)) < minlength - 1e-4 即可。
    今后再处理浮点数的问题时一定要相当小心咯

    Comments

    Please wait...
    Sorry, the comment you entered is too long. Please shorten it.
    You didn't enter anything. Please try again.
    Sorry, we can't add your comment right now. Please try again later.
    To add a comment, you need permission from your parent. Ask for permission
    Your parent has turned off comments.
    Sorry, we can't delete your comment right now. Please try again later.
    You've exceeded the maximum number of comments that can be left in one day. Please try again in 24 hours.
    Your account has had the ability to leave comments disabled because our systems indicate that you may be spamming other users. If you believe that your account has been disabled in error please contact Windows Live support.
    Complete the security check below to finish leaving your comment.
    The characters you type in the security check must match the characters in the picture or audio.

    To add a comment, sign in with your Windows Live ID (if you use Hotmail, Messenger, or Xbox LIVE, you have a Windows Live ID). Sign in


    Don't have a Windows Live ID? Sign up

    Trackbacks

    The trackback URL for this entry is:
    http://dantvt.spaces.live.com/blog/cns!D87988A6CAC0A480!1021.trak
    Weblogs that reference this entry
    • None