为什么一个浮点型变量停止在C#中的16777216递增? [英] Why does a float variable stop incrementing at 16777216 in C#?

查看:1319
本文介绍了为什么一个浮点型变量停止在C#中的16777216递增?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

 浮法A = 0; 
,而(真)
{
A ++;
如果(A> 16777216)
中断; //不会破坏......一个停在16777216
}



任何人都可以解释这一点我为什么浮点值停止递增,在16777216在此代码



编辑:



甚至更简单:

 浮动= 16777217; //一个变成16777216 


解决方案

短综述IEEE-754浮点数(32位),把我的头顶部:




  • 1位标志(0表示正数,1表示负数)

  • 8位指数(-127带偏见,这里并不重要)

  • 23位尾数

  • 随着指数的异常值0和255,可以计算出值:(?符号-1:+1)* 2 ^指数*(1.0 +尾数)

    • 尾数位代表的二进制的位数的之后的小数点分隔符,如: 1001 0000 0000 0000 0000 000 = 2 ^ -1 + 2 ^ -4 = 0.5 + 0.0625 = 0.5625 ,而不是存储在小数点前值但隐含地假定为1(如果指数为255,则假定0但在这里,这不是重要的),因此对于30指数,例如,该尾数例表示的值 1.5625




现在给你的例子:



16777216恰好是2 24 ,以及将表示为32位浮点像这样:




  • 登入= 0(​​正数)

  • 指数= 24(存储为24 + 127 = 151 = 10010111

  • 尾数= 0.0

  • 为32位浮点表示: 0 10010111 00000000000000000000000

  • 因此:值= (+ 1)* 2 ^ 24 *(1.0 + .0)= 2 ^ 24 = 16777216



现在让我们来看看在号码16777217,或正好2 24 +1:




  • 登入和指数是相同

  • 尾数必须是正好2 -24 ,使(+ 1)* 2 ^ 24 *(1.0 + 2 ^ -24)= 2 ^ 24 + 1 = 16777217

  • 这就是问题所在。尾数不能有值2 -24 ,因为它只有23位,所以数16777217就不能与32位浮点精度表示数字!


float a = 0;
while (true)
{
    a++;
    if (a > 16777216)
        break; // Will never break... a stops at 16777216
}

Can anyone explain this to me why a float value stops incrementing at 16777216 in this code?

Edit:

Or even more simple:

float a = 16777217; // a becomes 16777216

解决方案

Short roundup of IEEE-754 floating point numbers (32-bit) off the top of my head:

  • 1 bit sign (0 means positive number, 1 means negative number)
  • 8 bit exponent (with -127 bias, not important here)
  • 23 bits "mantissa"
  • With exceptions for the exponent values 0 and 255, you can calculate the value as: (sign ? -1 : +1) * 2^exponent * (1.0 + mantissa)
    • The mantissa bits represent binary digits after the decimal separator, e.g. 1001 0000 0000 0000 0000 000 = 2^-1 + 2^-4 = .5 + .0625 = .5625 and the value in front of the decimal separator is not stored but implicitly assumed as 1 (if exponent is 255, 0 is assumed but that's not important here), so for an exponent of 30, for instance, this mantissa example represents the value 1.5625

Now to your example:

16777216 is exactly 224, and would be represented as 32-bit float like so:

  • sign = 0 (positive number)
  • exponent = 24 (stored as 24+127=151=10010111)
  • mantissa = .0
  • As 32 bits floating-point representation: 0 10010111 00000000000000000000000
  • Therefore: Value = (+1) * 2^24 * (1.0 + .0) = 2^24 = 16777216

Now let's look at the number 16777217, or exactly 224+1:

  • sign and exponent are the same
  • mantissa would have to be exactly 2-24 so that (+1) * 2^24 * (1.0 + 2^-24) = 2^24 + 1 = 16777217
  • And here's the problem. The mantissa cannot have the value 2-24 because it only has 23 bits, so the number 16777217 just cannot be represented with the accuracy of 32-bit floating points numbers!

这篇关于为什么一个浮点型变量停止在C#中的16777216递增?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆