• Float浮点数转二进制串和十六进制串


    #include <String.au3>
    #include <Array.au3>
    #cs
     0.125  0000003e
     12.25  00004441
     -0.125 000000be
     1.3    6666a63f 1.299999952316284
     0.3125 0000a030
     0.2    c8cc4c3e 0.199999928474426
     0.3    9899993e 0.299999952316284
    #ce

    Local $aArray = StringSplit("0.125,12.25,-0.125,1.3,0.3125,0.2,0.3", ",")
    For $i = 1 To UBound($aArray)-1
    ConsoleWrite(@LF&'----------------------------------------'&@LF&@LF)
     Local $floatHex=FloatToHex($aArray[$i])
    ConsoleWrite('=>' &$floatHex& @LF)
    ConsoleWrite(@LF)
    BinaryToFloat($floatHex)

    Next

    ;1位符号位+8位指数+23位尾数
    Func FloatToHex($floatStr)
     ;符号位 正数为0 负数为1
     Local $pegativeStr = '0'
     If StringInStr($floatStr, "-") <> 0 Then $pegativeStr = '1'
     Local $pos = StringInStr($floatStr, ".")
     ;小数点左边的值
     Local $left = StringLeft($floatStr, $pos - 1)
     ;小数点右边的值
     Local $right = StringRight($floatStr, StringLen($floatStr) - StringLen($left) - 1)
     Local $binaryStr = DecimalToBinary(Number($left)) & FloatSmailDecimalToBinary(Number('0.' & $right, 3))
     ConsoleWrite($floatStr & '=>' & $binaryStr & @LF)
     ;二进制串中,从左边算起第一个数字1的位置 例 1100.01 值为1
     Local $leftOnePos = StringInStr($binaryStr, "1", 0, 1);
     ;二进制串中,小数点的位置 例 1100.01 值为5
     Local $decimalPos = StringInStr($binaryStr, ".");
     ;指数部分为二进制浮点数正规化后,小数点移动的位数+127
     ;0.0011 2-5=-3     1001.01 5-1=4移动次数需再减1
     Local $exponent = $decimalPos - $leftOnePos + 127
     If ($decimalPos - $leftOnePos) > 0 Then $exponent -= 1
     Local $exponentBinaryStr = DecimalToBinary($exponent)
     ConsoleWrite('Exponent=>' & $exponent)
     ;指数左边补足8位
     $exponentBinaryStr = _StringRepeat("0", 8 - StringLen($exponentBinaryStr)) & $exponentBinaryStr
     ConsoleWrite('=>' & $exponentBinaryStr & @LF)
     ;尾数部分
     Local $tailBinaryStr = StringReplace(StringMid($binaryStr, $leftOnePos + 1), '.', "")
     ;用0补足23位
     $tailBinaryStr &= _StringRepeat("0", 23 - StringLen($tailBinaryStr))
     ConsoleWrite('Tail=>' & $tailBinaryStr & @LF)
     Local $floatBinaryStr = $pegativeStr & $exponentBinaryStr & $tailBinaryStr;
     ConsoleWrite('=>' & $pegativeStr & ' ' & $exponentBinaryStr & ' ' & $tailBinaryStr & @LF)
     Local $result = ''
     For $i = 0 To StringLen($floatBinaryStr) / 4 - 1 Step 1
      $result &= DecimalToHex(BinaryToDecimal(StringMid($floatBinaryStr, $i * 4 + 1, 4)))
     Next
     Return StringLower(MemData($result))
    EndFunc   ;==>FloatToBinary

    Func BinaryToFloat($hexStr)
     Local $binaryStr = HexToBinary(MemData($hexStr))
     ConsoleWrite($hexStr & '=>' & $binaryStr & @LF)
     Local $pegativeStr = '';
     If StringLeft($binaryStr, 1) = '1' Then $pegativeStr = '-'
     Local $exponentBinaryStr = StringMid($binaryStr, 2, 8)
     ConsoleWrite('ExponentBinary=>' & $exponentBinaryStr & @LF)
     Local $tailBinaryStr = StringMid($binaryStr, 10, 23)
     ConsoleWrite('TailBinary=>' & $tailBinaryStr & @LF)
     Local $exponent = BinaryToDecimal($exponentBinaryStr) - 127
     ConsoleWrite('Exponent=>' & $exponent & @LF)
     Local $tail = "1." & $tailBinaryStr
     Local $newTail = ''
     If $exponent >= 0 Then
      $newTail = StringReplace(StringLeft($tail, $exponent + 2), ".", "") & '.' & StringMid($tail, $exponent + 3)
     Else
      $newTail = '0.' & _StringRepeat("0", -$exponent - 1) & StringReplace($tail, '.', '')
     EndIf
     ConsoleWrite('Tail=>' & $newTail & @LF)
     Local $decimalPos = StringInStr($newTail, ".");
     Local $result = BinaryToDecimal(StringLeft($newTail, $decimalPos - 1)) & BinaryToSmailDecimal(StringMid($newTail, $decimalPos + 1))
     ConsoleWrite('=>' & $result & @LF)
     Return $pegativeStr & $result
    EndFunc   ;==>BinaryToFloat

    Func MemData($hexStr)
     Local $result = ''
     Local $index = StringLen($hexStr) / 2 - 1
     For $i = $index To 0 Step -1
      $result &= StringMid($hexStr, $i * 2 + 1, 2)
     Next
     Return $result
    EndFunc   ;==>MemData

    #cs
     如0.638
     1、将其乘二:0.638*2=1.276 则二进制小数的二分位是1.276整数部分1
     2、取小数0.276,0.276*2=0.552 则二进制小数的二十分位是0.522整数部分0
     3、重复1
     得:(0.638)10=(约等于)(0.1010)2
    #ce
    ;小数部分转二进制
    Func FloatSmailDecimalToBinary($float)
     Local $floatStr = String($float)
     Local $leftChar = ''
     Local $result = ''
     For $i = 1 To 23 Step 1
      $float = $float * 2
      If ($float = 0) Then ExitLoop ;
      $floatStr = String($float)
      $leftChar = StringLeft($floatStr, 1)
      $result &= $leftChar
      $temp = StringFormat('%f', '0.' & StringMid($floatStr, 3, StringLen($floatStr) - 2))
      $float = $temp;
     Next
     Return '.' & $result
    EndFunc   ;==>FloatSmailDecimalToBinary

    ;十进制转二进制
    Func DecimalToBinary($dec)
     Local $temp = 0, $shit = 0
     For $a = 1 To BinaryLen($dec) * 8 Step 1
      $shit = $a
      If (2 ^ $a > $dec) Then ExitLoop
     Next
     Local $result = ""
     For $i = 0 To $shit - 1 Step 1
      $result &= Chr(BitAND(0x1, BitShift($dec, $i)) + Asc("0"))
     Next
     Return _StringReverse($result)
    EndFunc   ;==>DecimalToBinary

    ;二进制转十进制
    Func BinaryToDecimal($bin)
     Local $result = 0
     Local $binArray = StringSplit($bin, "", 2)
     For $a = UBound($binArray) To 1 Step -1
      Local $number = StringMid($bin, $a, 1)
      If $number = "1" Then
       $result += 2 ^ (UBound($binArray) - $a)
      EndIf
     Next
     Return $result
    EndFunc   ;==>BinaryToDecimal

    ;二进制小数转十进制
    Func BinaryToSmailDecimal($bin)
     Local $result = 0
     Local $binArray = StringSplit($bin, "", 2)
     For $a = 1 To UBound($binArray) Step 1
      Local $number = StringMid($bin, $a, 1)
      If $number = "1" Then
       $result += 2 ^ - $a
      EndIf
     Next
     Return StringMid($result, 2)
    EndFunc   ;==>BinaryToSmailDecimal

    ;十进制转十六进制
    Func DecimalToHex($dec)
     Local $temp = 0, $shit = 0
     Local $hexChar = '0123456789ABCDEF'
     Local $hexCharArray = StringSplit($hexChar, '', 2)
     For $a = 1 To BinaryLen($dec) * 8 Step 1
      $shit = $a
      If (16 ^ $a > $dec) Then ExitLoop
     Next
     Local $result = ""
     For $i = 0 To $shit - 1 Step 1
      $dddd = BitAND(0xf, BitShift($dec, $i * 4))
      $result &= $hexCharArray[$dddd]
     Next
     Return _StringReverse($result)
    EndFunc   ;==>DecimalToHex

    ;十六进制转二进制
    Func HexToBinary($hex)
     If StringUpper(StringLeft($hex, 2)) = "0x" Then $hex = StringUpper(StringRight($hex, StringLen($hex) - 2))
     Local $bits = "0000|0001|0010|0011|0100|0101|0110|0111|1000|1001|1010|1011|1100|1101|1110|1111"
     $bits = StringSplit($bits, '|', 2)
     Local $hexInputArray = StringSplit($hex, '', 2)
     Local $result = ""
     For $a In $hexInputArray
      $result &= $bits[Dec($a)]
     Next
     Return $result
    EndFunc   ;==>HexToBinary

     运行结果:

    --------------------------------------------------------------------------------

    0.125=>0.001
    Exponent=>124=>01111100
    Tail=>00000000000000000000000
    =>0 01111100 00000000000000000000000
    =>0000003e

    0000003e=>00111110000000000000000000000000
    ExponentBinary=>01111100
    TailBinary=>00000000000000000000000
    Exponent=>-3
    Tail=>0.00100000000000000000000000
    =>0.125

    --------------------------------------------------------------------------------

    12.25=>1100.01
    Exponent=>130=>10000010
    Tail=>10001000000000000000000
    =>0 10000010 10001000000000000000000
    =>00004441

    00004441=>01000001010001000000000000000000
    ExponentBinary=>10000010
    TailBinary=>10001000000000000000000
    Exponent=>3
    Tail=>1100.01000000000000000000
    =>12.25

    --------------------------------------------------------------------------------

    -0.125=>0.001
    Exponent=>124=>01111100
    Tail=>00000000000000000000000
    =>1 01111100 00000000000000000000000
    =>000000be

    000000be=>10111110000000000000000000000000
    ExponentBinary=>01111100
    TailBinary=>00000000000000000000000
    Exponent=>-3
    Tail=>0.00100000000000000000000000
    =>0.125

    --------------------------------------------------------------------------------

    1.3=>1.01001100110011001100110
    Exponent=>127=>01111111
    Tail=>01001100110011001100110
    =>0 01111111 01001100110011001100110
    =>6666a63f

    6666a63f=>00111111101001100110011001100110
    ExponentBinary=>01111111
    TailBinary=>01001100110011001100110
    Exponent=>0
    Tail=>1.01001100110011001100110
    =>1.299999952316284

    --------------------------------------------------------------------------------

    0.3125=>0.0101
    Exponent=>125=>01111101
    Tail=>01000000000000000000000
    =>0 01111101 01000000000000000000000
    =>0000a03e

    0000a03e=>00111110101000000000000000000000
    ExponentBinary=>01111101
    TailBinary=>01000000000000000000000
    Exponent=>-2
    Tail=>0.0101000000000000000000000
    =>0.3125

    --------------------------------------------------------------------------------

    0.2=>0.00110011001100110011001
    Exponent=>124=>01111100
    Tail=>10011001100110011001000
    =>0 01111100 10011001100110011001000
    =>c8cc4c3e

    c8cc4c3e=>00111110010011001100110011001000
    ExponentBinary=>01111100
    TailBinary=>10011001100110011001000
    Exponent=>-3
    Tail=>0.00110011001100110011001000
    =>0.199999928474426

    --------------------------------------------------------------------------------

    0.3=>0.01001100110011001100110
    Exponent=>125=>01111101
    Tail=>00110011001100110011000
    =>0 01111101 00110011001100110011000
    =>9899993e

    9899993e=>00111110100110011001100110011000
    ExponentBinary=>01111101
    TailBinary=>00110011001100110011000
    Exponent=>-2
    Tail=>0.0100110011001100110011000
    =>0.299999952316284

  • 相关阅读:
    【ThreadX】Azure RTOS ThreadX概述
    -- spi flash 擦除接口调用HAL库不同函数的区别
    STM32 芯片锁死解决方法
    【KEIL】User's Guide
    【KEIL】Software Packs
    【KEIL 】Options for File
    使用CubeMX创建TouchGFX工程时LCD死活不显示
    【转】获取本地图片的URL
    printf 函数格式控制
    【集成】touchgfx 之 《Using C code with TouchGFX》
  • 原文地址:https://www.cnblogs.com/godghdai/p/6952563.html
Copyright © 2020-2023  润新知