簡體   English   中英

不能增加浮點變量的值

[英]Can't increment value of a floating-point variable

我是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;代碼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;

避免整數除法將值轉換為double

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM