不能增加浮点变量的值

本文关键字:浮点变量 增加 不能 | 更新日期: 2023-09-27 17:54:28

我是c#新手,我不明白,为什么我的变量不想增加到大于16777215的值

我有代码:

float fullPerc = 100;
float bytesRead = 1;
long fileSize = 1;
ProgressBar pb1;
int blockSizeBytes = 0;
float counter = 0;
using (FileStream inFs = new FileStream(inFile, FileMode.Open))
{
    fileSize = inFs.Length;
    do
    {
        counter = counter + 1;
        if (counter > 16777215) //&& counter < 16777230)
        {
            counter = counter + 10;
            //Console.WriteLine(((counter + 10) /100));
        }
        count = inFs.Read(data, 0, blockSizeBytes);
        offset += count;
        outStreamEncrypted.Write(data, 0, count);
        bytesRead += blockSizeBytes;
   }
   while (count > 0);
   inFs.Close();
}

https://bitbucket.org/ArtUrlWWW/myfileencoderdecoder/src/f7cce67b78336636ef83058cd369027b0d146b17/FileEncoder/Encrypter.cs?at=master& fileviewer = file-view-default # encrypter.cs - 166

当计数器的值等于16777216时,变量增量counter = counter + 1;的代码不起作用,但此代码

if (counter > 16777215) //&& counter < 16777230)
                                    {
                                        counter = counter + 10;
                                        //Console.WriteLine(((counter + 10) /100));
                                    }

是正常的

例如,如果我注释这个if代码,我的counter将增长到16777216值,并将停止在这个值。当该变量>=16777216时,该变量只会增加10。

为什么?

不能增加浮点变量的值

尾数溢出,结果导致精度损失float(或Single)类型具有24位尾数(不超过16777216):

https://en.wikipedia.org/wiki/Single-precision_floating-point_format

让我们看看发生了什么:

  private static String MakeReport(float value) {
    return String.Join(" ", BitConverter
     .GetBytes(value)
     .Select(b => Convert.ToString(b, 2).PadLeft(8, '0')));
  }
...
  float f = 16777215;
  // Mantissa (first 3 bytes) is full of 1's except the last one bit
  // 11111111 11111111 01111111 01001011
  Console.Write(MakeReport(f)); 
  // Overflow! Presision loss
  // 00000000 00000000 10000000 01001011  
  Console.Write(MakeReport(f + 1)); 
  // Overflow! Presision loss
  // 00000000 00000000 10000000 01001011  
  Console.Write(MakeReport(f + 2)); 
  // Overflow! Presision loss
  // 00000100 00000000 10000000 01001011  
  Console.Write(MakeReport(f + 10)); 

补救方法:不使用浮点数作为counter,而使用整数:

 int counter = 0;

为避免整数除法将value强制转换为double

  float x = (float) ((((double)counter * blockSizeBytes) / fileSize) * fullPerc);