VC和VS系列(2005)编译器对双精度浮点溢出的处理

作者:风影残烛

在还原代码的过程中。目前程序是采用VS2005(以上版本)写的。

我使用的是vc6.0,结果。在运算的时候。发现编译器对

// FpuTlxTest.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <string.h>
#include <math.h>
#include <stdlib.h>

void KeyFun(char* pComputerName)
{
  char szKey[16] = {0};
  int iNum_ebx = 0;
  int iNum_ecx = 0;
  int iNum_var30 = 0;
  int dwCptNameLen = strlen(pComputerName);
  if (dwCptNameLen != 0)
  {
    int i = 1;
    int iTempMod;
    if (dwCptNameLen >= i)
    {
      double dblNum = 0.0;
      char* pTial = &pComputerName[dwCptNameLen - 1];
      int iNum = 2;
      iNum = 2 - (int)pComputerName;
      for (; i <= dwCptNameLen; i++, pTial--)
      {
        int iCharacter = (int)pComputerName[i-1];
        double dblTemp = sqrt((double)iCharacter) * i + 1.0;
        iCharacter = iCharacter * i * i;
        iTempMod = (int)(dblTemp * (double)iCharacter + dblNum) % 100000;
        iCharacter = iTempMod;
        dblNum = (double)iCharacter;
        iCharacter = (int)*pTial;
        dblTemp = pow(sqrt((double)iCharacter), 2) * dblNum;
        iCharacter = iNum + (int)&pComputerName[i-1];
        int iTemp = (int)(dblTemp * (double)iCharacter) % 100000;
        iNum_ebx = iNum_ebx + iTemp + 1;
        iCharacter = iNum_ebx * iTempMod;
        iTemp = iCharacter;
        iCharacter = iNum_var30 - (iNum_var30 / 100000 * 100000);
        iNum_var30 = (int)(sqrt((double)iTemp) + (double)iCharacter);  // 这里会有浮点溢出的情况
      }
      iNum_ecx = iNum_var30;
    }
    int iSaveNum = iTempMod + 0x1f;
    iSaveNum &= 0x8000007F;
    if ( iSaveNum < 0)
    {
      iSaveNum--;
      iSaveNum |= 0xFFFFFF80;
      iSaveNum++;
    }
    szKey[0] = (char)iSaveNum;
    iSaveNum = iTempMod + 0x20;
    iSaveNum &= 0x8000007F;
    if (iSaveNum < 0)
    {
      iSaveNum--;
      iSaveNum |= 0xFFFFFF80;
      iSaveNum++;
    }
    szKey[1] = (char)iSaveNum;
    iSaveNum = iTempMod + 0x27;
    iSaveNum &= 0x8000007F;
    if (iSaveNum < 0)
    {
      iSaveNum--;
      iSaveNum |= 0xFFFFFF80;
      iSaveNum++;
    }
    szKey[2] = (char)iSaveNum;
    iSaveNum = iTempMod + 0x3a;
    iSaveNum &= 0x8000007F;
    if (iSaveNum < 0)
    {
      iSaveNum--;
      iSaveNum |= 0xFFFFFF80;
      iSaveNum++;
    }
    szKey[3] = (char)iSaveNum;
    iSaveNum = iTempMod + 0x5f;
    iSaveNum &= 0x8000007F;
    if (iSaveNum < 0)
    {
      iSaveNum--;
      iSaveNum |= 0xFFFFFF80;
      iSaveNum++;
    }
    szKey[4] = (char)iSaveNum;
    iSaveNum = iNum_ebx + 0x9c;
    iSaveNum &= 0x8000007F;
    if (iSaveNum < 0)
    {
      iSaveNum--;
      iSaveNum |= 0xFFFFFF80;
      iSaveNum++;
    }
    szKey[5] = (char)iSaveNum;
    iSaveNum = iNum_ebx + 0xf7;
    iSaveNum &= 0x8000007F;
    if (iSaveNum < 0)
    {
      iSaveNum--;
      iSaveNum |= 0xFFFFFF80;
      iSaveNum++;
    }
    szKey[6] = (char)iSaveNum;
    iSaveNum = iNum_ebx + 0x176;
    iSaveNum &= 0x8000007F;
    if (iSaveNum < 0)
    {
      iSaveNum--;
      iSaveNum |= 0xFFFFFF80;
      iSaveNum++;
    }
    szKey[7] = (char)iSaveNum;
    iSaveNum = iNum_ebx + 0x21f;
    iSaveNum &= 0x8000007F;
    if (iSaveNum < 0)
    {
      iSaveNum--;
      iSaveNum |= 0xFFFFFF80;
      iSaveNum++;
    }
    szKey[8] = (char)iSaveNum;
    iSaveNum = iNum_ebx + 0x2f8;
    iSaveNum &= 0x8000007F;
    if (iSaveNum < 0)
    {
      iSaveNum--;
      iSaveNum |= 0xFFFFFF80;
      iSaveNum++;
    }
    szKey[9] = (char)iSaveNum;
    iSaveNum = iNum_ecx + 0x407; 
    iSaveNum &= 0x8000007F;
    if (iSaveNum < 0)
    {
      iSaveNum--;
      iSaveNum |= 0xFFFFFF80;
      iSaveNum++;
    }
    szKey[10] = (char)iSaveNum;
    iSaveNum = iNum_ecx + 0x552;
    iSaveNum &= 0x8000007F;
    if (iSaveNum < 0)
    {
      iSaveNum--;
      iSaveNum |= 0xFFFFFF80;
      iSaveNum++;
    }
    szKey[11] = (char)iSaveNum;
    iSaveNum = iNum_ecx + 0x6df;
    iSaveNum &= 0x8000007F;
    if (iSaveNum < 0)
    {
      iSaveNum--;
      iSaveNum |= 0xFFFFFF80;
      iSaveNum++;
    }
    szKey[12] = (char)iSaveNum;
    iSaveNum = iNum_ecx + 0x8b4;
    iSaveNum &= 0x8000007F;
    if (iSaveNum < 0)
    {
      iSaveNum--;
      iSaveNum |= 0xFFFFFF80;
      iSaveNum++;
    }
    szKey[13] = (char)iSaveNum;
    iNum_ecx += 0xad7;
    iNum_ecx &= 0x8000007F;
    if (iNum_ecx < 0)
    {
      iNum_ecx--;
      iNum_ecx |= 0xFFFFFF80;
      iNum_ecx++;
    }
    szKey[14] = (char)iNum_ecx;
    szKey[15] = '\0';
    int j = 0;
    int k = 0;
    while (k < 0x69)
    {
      char ch = szKey[j];
      if (ch >= '0' && ch <= '9')
      {
        k = k + 7;
        j++;
      }
      else if (ch >= 'A' && ch <= 'Z')
      {
        k = k + 7;
        j++;
      }
      else if (ch >= 'a' && ch <= 'z')
      {
        k = k + 7;
        j++;
      }
      else
      {
        int iTemp = ch + k + 0x1f;
        iTemp = iTemp & 0x8000007F;
        if (iTemp < 0)
        {
          iTemp--;
          iTemp |=  0xFFFFFF80;
          iTemp++;
        }
        szKey[j] = (char)iTemp;
      }
    } 
  }
  printf("%s\r\n", szKey);
}


int _tmain(int argc, _TCHAR* argv[])
{
  KeyFun("TEN-OLOIZ");

  system("pause");
	return 0;
}

代码中标注的地方 。采用不同的对待方式。导致结果不一样。

vc6.0中测试:如果溢出。则放到edx、eax返回为__int64。然而代码中的为int,所以只取低32字节。

vs2005中测试:如果溢出。则正确返回。

区别在于取整库函数的是实现不一样。有兴趣的朋友可以自己跟进去看。

posted @ 2014-04-13 13:52  0x苦行僧  阅读(565)  评论(0编辑  收藏  举报