Rumah  >  Soal Jawab  >  teks badan

java - 浮点数如何比较是否相等或者如何判断某个浮点数是否为0?

大家应该都知道浮点数存在精度问题,所以问题就来了,我如何才能判断两个数是否近似相等,或者某个浮点数是否为0。
其实这是一个问题,对于前者,我们需要二者作差,然后与0进行比较。这样前者与后者就是同一个问题了,即如何判断某个浮点数是否为0。我所知道的比较简单但是不是很好的方法就是使用1e-7或者更小的数,如下所示(以单精度为例):

#include <iostream>
#include <cfloat>

using namespace std;

int main()
{
    float num;

    cout << "输入一个数:";
    cin >> num;

    if (num < 1e-7 && num > -1e-7)
        cout << num << "近似为0" << endl;
    else
        cout << num << "不近似为0" << endl;

    return 0;
}

上述方式以C++代码为例。由于不同编程语言有不同的处理方式,大家可以不限制使用任何编程语言。当然,如果您有更通用的方式当然再好不过了。

天蓬老师天蓬老师2740 hari yang lalu1894

membalas semua(3)saya akan balas

  • PHP中文网

    PHP中文网2017-04-18 10:20:47

    Seberapa kecil "cukup kecil" harus ditentukan oleh masalah khusus yang ditangani. Contohnya, jika anda menggunakan double untuk menyatakan jumlah, 1e-4 boleh dianggap sifar. Dan jika kita melakukan pengiraan saintifik, saya takut 1e-7 masih terlalu besar.

    <cfloat> mentakrifkan DBL_EPSILON sebagai perbezaan yang paling hampir kepada 1.0. Lihat di sini.

    balas
    0
  • PHPz

    PHPz2017-04-18 10:20:47

    Perbandingan nombor titik terapung masih perlu berdasarkan peraturan storan sebenar, kerana nombor titik terapung disimpan dalam perduaan, dan menggunakan perduaan untuk mewakili perpuluhan tidak boleh diwakili dengan tepat Walaupun nombor titik terapung mempunyai perpuluhan yang lebih sedikit digit bererti, maka Ia mungkin tidak mungkin untuk mewakili dengan tepat dalam perduaan. kenapa?
    Pertama sekali, perwakilan binari tempat perpuluhan nombor titik terapung adalah seperti berikut:
    1 tempat perpuluhan: 0.5 (2^-1)
    2 tempat perpuluhan: 0.25 (2^-2)
    .. .
    N tempat perpuluhan: 2^-n
    Maksudnya, bahagian perpuluhan mana-mana nombor titik terapung terdiri daripada 2^-1...2^-n , supaya anda boleh memahami mengapa nombor titik terapung dengan beberapa digit bererti tidak boleh dinyatakan dengan tepat Contohnya, 0.3 tidak boleh dinyatakan dengan tepat menggunakan gabungan digit di atas Jika anda tidak percaya cout, cuba:

    #include <iostream>
    #include <iomanip>
    
    int main()
    {
        float a = 0.3f;
        std::cout << std::setprecision(32) << a << std::endl;
        return 0;
    }

    Output: 0.30000001192092896
    Dan jika anda menggantikan 0.3 dengan 0.5, itu tidak mengapa, kerana 0.5 boleh diwakili dengan tepat oleh 2^-1! Dengan cara yang sama, 0.625 juga OK.
    Lalu mengapa kita biasanya boleh mengeluarkan 0.3 secara langsung apabila cout << Ini kerana cout melakukan pembundaran secara lalai .

    Kembali kepada soalan poster asal: Jika anda menilai secara langsung 0.3 == 0.3, maka tiada masalah, kerana nombor yang sama mempunyai perwakilan yang sama, jadi anda boleh menggunakan '==' secara langsung. Ini benar terutamanya jika ia adalah nombor yang boleh diwakili dengan tepat, seperti 0.
    Tetapi jika anda menilai sama ada 0.1+0.2 dan 0.3 adalah sama, itu tidak akan berfungsi, kerana kedua-duanya mempunyai kehilangan ketepatan, dan nilai kerugian berbeza, jadi anda tidak boleh membandingkan secara langsung dan anda perlu menggunakan kaedah seperti abs((0.1+0.2) - 0.3)<EPSILON.

    balas
    0
  • 天蓬老师

    天蓬老师2017-04-18 10:20:47

    Perwakilan komputer bagi nombor titik terapung (jenis terapung atau berganda) mempunyai had ketepatan Untuk nombor titik terapung yang melebihi had ketepatan, komputer akan memotong bahagian perpuluhan melebihi ketepatannya. Oleh itu, dua nombor titik terapung yang asalnya tidak sama mungkin menjadi sama dalam komputer. Contohnya:

    float a=10.222222225,b=10.222222229
    数学上a和b是不相等的,但在32位计算机中它们是相等的。
    
    如果两个同符号浮点数之差的绝对值小于或等于某一个可接受的误差(即精度),就认为它们是相等的。
    不要直接用“==”或者“!=”对两个浮点数进行比较,但是可以直接用“<”和“>”比较谁大谁小。
    

    balas
    0
  • Batalbalas