纯代码实现浮点计算实际上对浮点算法的再实践。IEEE浮点表示法是Modbus RTU协议至今还在用的传送编码,更是WITS 1记录标准的基础。以往实现 MKI、CVI,MKL、CVL,MKS、CVS,MKD、CVD在高级语言里封装了现成的语句,现在PowerBasic和FreeBasic也可以将这些语句封闭到 DLL 中供其它语言调用。不过还是重编代码,对算法的演练更到位。
1. MKI/CVI
要点:对输入数据取整,判断正负,正数直接转换,负数加上65536后转换。输入数据分成高低各16位数据,范围在 &H0000 - &HFFFF之间。
Function MKI(ByVal iData As Integer) As String'MKI 16bits &HFFFF -32768 to 32767 8000-7fffDim inData As LongDim HiByte As Long, LoByte As LonginData = Fix(iData)If inData < 0 Then inData = inData + 65536LoByte = inData And &HFFHiByte = (inData \ 2 ^ 8) And &HFFMKI = Right$(("0" + Hex$(HiByte)), 2) + Right$(("0" + Hex$(LoByte)), 2)
End Function
2. MKL/CVl
MKL实现方法与MKI类似,它是32位的,因此输入的数据分成四个8位数据,在VB6中用Currency类型变量表示更便于计算。
Function MKL(ByVal lData As Long) As StringDim Phi4 As Currency, Phi3 As Currency, Phi2 As Currency, Phi1 As CurrencyDim inData As CurrencyinData = Fix(lData)Phi4 = inData And &HFFPhi3 = (inData \ 2 ^ 8) And &HFFPhi2 = (inData \ 2 ^ 16) And &HFFPhi1 = (inData \ 2 ^ 24) And &HFFMKL = Right$(("0" + Hex$(Phi1)), 2) + Right$(("0" + Hex$(Phi2)), 2) + Right$(("0" + Hex$(Phi3)), 2) + Right$(("0" + Hex$(Phi4)), 2)
End Function
3. MKS/CVS
右移位求得整数部分二进制串,小数部分乘2取整形成小数二进制串,合并二进制串左移或右移小数点位置并舍去高位的 1 ,移位值加上127形成 exp 指数, 正负符号用0或1表示,结果是 s+exp+余下的小数。
OffSetBits = 8AcuFactor = 32: OffSet = 127inData = sDatainDataSingn = 0If inData < 0 Then inDataSingn = 1inData = Abs(inData) 'ignore singnipart = Int(inData): fpart = (inData - ipart)If inData = 0 ThenCaseID = 0Else'Convert ipart, the integer part, into byte array TempData1 MSB to LSBtipart = ipart: TempString = ""For I = 1 To AcuFactorTempString = Right$(Str$(tipart And &H1), 1) + TempStringtipart = tipart \ 2 ^ 1Next IFor I = 1 To AcuFactorIf Mid$(TempString, I, 1) = "1" Then Exit ForMid$(TempString, I, 1) = " "Next IIntiStr = Trim(TempString)'Convert fpart, the fraction part, into byte array TempData2tfpart = fpart: TempString = ""For I = 1 To AcuFactorIf tfpart = 0 Then Exit Fortfpart = tfpart * 2tnpart = Int(tfpart): tfpart = tfpart - tnpartTempString = TempString + Right$(Str$(tnpart And &H1), 1)Next IFracStr = TempStringIf ipart > 0 Then CaseID = 1If ipart = 0 Then CaseID = 2End If
4. MKD/CVD
与MKS类同,只是exp由8位增加至11位,偏移值由127变为1023
OffSetBits = 11AcuFactor = 64: OffSet = 1023inData = sDatainDataSingn = 0If inData < 0 Then inDataSingn = 1inData = Abs(inData) 'ignore singnipart = Int(inData): fpart = (inData - ipart)If inData = 0 ThenCaseID = 0Else'Convert ipart, the integer part, into byte array TempData1 MSB to LSBtipart = ipart: TempString = ""For I = 1 To AcuFactorTempString = Right$(Str$(tipart And &H1), 1) + TempStringtipart = tipart \ 2 ^ 1Next IFor I = 1 To AcuFactorIf Mid$(TempString, I, 1) = "1" Then Exit ForMid$(TempString, I, 1) = " "Next IIntiStr = Trim(TempString)'Convert fpart, the fraction part, into byte array TempData2tfpart = fpart: TempString = ""For I = 1 To AcuFactorIf tfpart = 0 Then Exit Fortfpart = tfpart * 2tnpart = Int(tfpart): tfpart = tfpart - tnpartTempString = TempString + Right$(Str$(tnpart And &H1), 1)Next IFracStr = TempStringIf ipart > 0 Then CaseID = 1If ipart = 0 Then CaseID = 2End If
最后的结果都要变成十六进制字符,以便传送和文件存储。
源代码下载:
https://download.csdn.net/download/weixin_45707491/88232263?spm=1001.2014.3001.5503