浮动分数精度

时间:2014-09-11 11:13:28

标签: c++ floating-point

float1.0f之间0.0f有多少精度位置,以便每个值都可以唯一表示?

例如,如果第一个小数float无法代表0.13f,那么答案就是浮点只有1个精度位置。

2 个答案:

答案 0 :(得分:7)

std::numeric_limits<float>::digits10

来自http://en.cppreference.com/w/cpp/types/numeric_limits/digits10

  

标准的32位IEEE 754浮点类型具有24位小数部分(写入23位,一个隐含),这可能表明它可以表示7位小数(24 * std :: log10(2)是7.22),但是相对舍入误差是不均匀的,一些带有7位十进制数字的浮点值不能保持转换为32位浮点数和返回值:最小的正例是8.589973e9,在往返之后变为8.589974e9。这些舍入误差在表示中不能超过一位,而数字10计算为(24-1)* std :: log10(2),即6.92。向下舍入得到值6.

EDIT2: 这表明该数字不是7,而是任何浮点数只有6位数,就像std::numeric_limits<float>::digits10调用所说的那样。

float orgF = 8.589973e9;
int i = orgF;
float f = i;
assert(f == orgF);

失败,因为往返更改了值。

因此,如果我们只查找介于1.0和0.0之间的数字,则肯定答案是7,因为有问题的最低正数是8.589973e9。

答案 1 :(得分:4)

如果我理解你的问题,the answer就是6。

#include <iostream>
#include <string>
#include <sstream>
#include <iomanip>
using namespace std;

int main() {
    int i = 10;  /* Number of distinct number after 1 place of decimal */
    int k = 1;   /* Number of decimal places */
    for(;/* ever */;)
    {
        float prev = 0.0f;
        for(int j = 1; j <= i; ++j)
        {
            stringstream ss;
            ss << "0.";  /* Prepare stream with 0. followed by k digit number with leading zeroes */
            ss << setfill('0') << setw(k) << j;
            float next; /* Read the number */
            ss >> next;
            if(prev == next) return 0;  /* If previous number and current number can not be distinguished */
            prev = next;
        }
        cout << "Works for " << k << " places" << endl;
        i *= 10; /* 10 times more tests to be conducted for 1 more decimal places */
        k++;     /* Try for more decimal places */
    }
    return 0;
}

代码做什么

1. Set precision to 1 place after decimal
2. Compare 0.0 with 0.1, 0.1 with 0.2 .... 0.8 with 0.9 and 0.9
   with 1.0, if any of these are equal (not distinguish), exit.
   Otherwise print Works for 1 place.
3. Set precision to 2 places after decimal
4. Compare 0.00 with 0.01, 0.01 with 0.02 .... 0.98 with 0.99 and 0.99
   with 1.00, if any of these are equal (not distinguish), exit. Otherwise
   print Works for 2 places.
5. Repeat similar steps for 3 and more digits unless you exit