2014-09-11 104 views
4

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

例如,如果第一个小数float不能代表0.13f答案将是浮点只有1个精度。

+3

你的第一句话表明你正在寻找独特的表现,而你第二个建议你正在寻找一个精确的表示。这是什么?我不能完全表示0.1,但我可以唯一地表示它。 – 2014-09-11 11:25:51

+0

阅读http://floating-point-gui.de/ – 2014-09-11 11:54:24

+0

@JosephMansfield 0.0到1.0之间有无限多的实数。可以将每个精度为2的数字转换为“int”并返回;这样原来的“浮动”被保留下来了?所以在示例问题中,我是否可以表示:“0.00F”,“0.01F”,“0.02F”,“0.03F”,“0.04F”,“0.05F”,“0.06F”,“0.07F” 0.08F“,”0.09F“,”0.10F“,”0.11F“,”0.12F“和”0.14F“,我不能唯一地表示”0.13F“。这意味着如果我这样做了:'float foo = 0.13F;''foo'将具有与'0.12F'或'0.14F'相同的表示。 – 2015-08-24 11:13:07

回答

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。

+0

@我听不懂这句话,你能解释一下吗? “但是相对的舍入误差是不均匀的,一些具有7个十进制数字的浮点值在转换为32位浮点数和返回值后仍然存在。”我认为这是指先前的陈述:“任何具有这么多十进制数字的数字都可以被转换为T类型的值并返回十进制形式,而不会因四舍五入或溢出而改变。” – 2014-09-12 10:54:58

+1

往返'float orgF = 8.589973e9; int i = orgF; float f = i; assert(f == orgF);'可能出错 – Surt 2014-09-12 10:59:23

+0

您添加的示例不直接映射到OP的问题。 – 2014-09-13 12:48:11

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 
+0

+1这是一个非常实用的方式来回答这个问题。我希望我能接受这个答案,但看起来@Surt的答案更多一些,正如你所说的“写得好”。 – 2014-09-12 10:59:26

+0

@JonathanMee谢谢 – 2014-09-12 12:29:57