Author Topic: Перевод десятичного числа во float (32 битный формат IEEE 754)  (Read 3432 times)

0 Members and 1 Guest are viewing this topic.

ya12

  • Активный участник
  • ***
  • Posts: 165
    • View Profile
Здравствуйте.
Помогите с переводом десятичного числа во float (32 битный формат IEEE 754).

ps: Хочу научить бота запрыгивать на камни.
ps2: Dramster формула по переводу float в десятичное число отлично работает.

dramster

  • Герой форума
  • *****
  • Posts: 1134
    • View Profile
Как это тебе может помочь?  :o Но все равно, интересно было узнать как это работает  :). Статей в интернете достаточно, мне более понятной показалась вот эта http://alexanderkobelev.blogspot.com/2013/05/ieee-754.html

Code: (clickermann) [Select]
$num = 185.4375 // наше десятичное число для перевода


print(" ")
print("десятичное число - ", $num)

//бит знака
IF($num > 0)
   $sign = 0
ELSE
   $sign = 1
   $num = abs($num)
END_IF


$int = int($num)    //целая часть
$fraction = $num - $int  //дробная


//перевод целой части в двоичную строку
$str_int_b = ""
WHILE($int > 0)
   $int = $int/2
   IF($int > int($int))
      $str_int_b = STRCONCAT("1", $str_int_b)
   else
      $str_int_b = STRCONCAT("0", $str_int_b)
   END_IF
   $int = int($int)
END_CYC
IF($str_int_b = "")
   print("целая часть в двоичном - ", 0)
ELSE
   print("целая часть в двоичном - ", $str_int_b)
END_IF



//перевод дробной части в двоичную строку (только наоборот)
$str_fraction_b = ""
WHILE(($fraction > 0)&(strlen(STRCONCAT($str_int_b,$str_fraction_b))<50)) //рассчет до 50 знаков (бит), я даже и не в курсе сколько нужно, чтобы и точность была, и зря не нагружать проц.
   $str_fraction_b = strconcat($str_fraction_b,int($fraction*2))
   $fraction = $fraction*2 - int($fraction*2)
END_CYC
print("дробная часть в двоичном - ",$str_fraction_b)


//рассчет мантиссы
$mantissa = STRCONCAT($str_int_b,$str_fraction_b)
WHILE(STRCUT($mantissa, 1, 1)=0)  //если число меньше единицы
   $mantissa = STRCUT($mantissa, 2, strlen($mantissa)-1)
END_CYC
$mantissa = STRCUT($mantissa, 2, strlen($mantissa)-1) //убираем последнюю единицу
IF(strlen($mantissa)<23)
   WHILE(strlen($mantissa) < 23) //дописываем недостающие нули, mantissa = 23 бита
      $mantissa = STRCONCAT($mantissa, 0)
   END_CYC
ELSE
   $mantissa = STRCUT($mantissa, 1, 23) //если больше 23 бит, то убираем лишнее
END_IF
print("мантисса - ",$mantissa)


//рассчет экспоненты
IF($str_int_b = "")  //если число меньше единицы
   $exponent_dec = 1
   WHILE(STRCUT($str_fraction_b, $exponent_dec,1) = 0)
      $exponent_dec = $exponent_dec + 1
   END_CYC
   $exponent_dec = 127 - $exponent_dec
ELSE      //если больше
   $exponent_dec = 126 + strlen($str_int_b)
END_IF

print("экспонента в десятичном - ",$exponent_dec)

$exponent = ""   //перевод экспоненты в двоичную строку
WHILE($exponent_dec > 0)
   $exponent_dec = $exponent_dec/2
   IF($exponent_dec > int($exponent_dec))
      $exponent = STRCONCAT("1", $exponent)
   else
      $exponent = STRCONCAT("0", $exponent)
   END_IF
   $exponent_dec = int($exponent_dec)
END_CYC
WHILE(strlen($exponent) < 8) //дописываем недостающие нули, exponent = 8 бита
   $exponent = STRCONCAT(0, $exponent)
END_CYC

print("экспонента в двоичном - ",$exponent)

//соединяем все вместе
$IEEE_754_bin = STRCONCAT($sign, $exponent, $mantissa)

print("IEEE_754 в бинарном виде - ", $IEEE_754_bin)

//пересчет из бинарной строки в десятичное число
$pow = 1
FOR($b=32,$b>0, -1)
   $IEEE_754_dec = $IEEE_754_dec + STRCUT($IEEE_754_bin, $b, 1) * $pow
   $pow = $pow * 2
END_CYC
print("IEEE_754 в десятичном виде - ", $IEEE_754_dec)


//пересчет из бинарной строки в шестнадцатеричный вид
SUB(bin_to_hex, $bin)
   $hex = 0
   $pow = 1
   FOR($bn=4,$bn>0, -1)
      $hex = $hex + STRCUT($bin, $bn, 1) * $pow
      $pow = $pow * 2
   END_CYC
   
   IF($hex > 9)
      SWITCH($hex)
         CASE(10)
            $hex = "A"
         CASE(11)
            $hex = "B"
         CASE(12)
            $hex = "C"
         CASE(13)
            $hex = "D"
         CASE(14)
            $hex = "E"
         CASE(15)
            $hex = "F"
      END_SWITCH
   END_IF
END_SUB

$IEEE_754_hex = ""
FOR($b=1, $b<33, 4)
   bin_to_hex(STRCUT($IEEE_754_bin, $b, 4))
   $IEEE_754_hex = STRCONCAT($IEEE_754_hex, $hex)
END_CYC
print("IEEE_754 в шестнадцатеричном виде - 0x",$IEEE_754_hex)


halt


Лог:
Code: (text) [Select]
00:06:24 десятичное число - 185.4375
00:06:24 целая часть в двоичном - 10111001
00:06:24 дробная часть в двоичном - 0111
00:06:24 мантисса - 01110010111000000000000
00:06:24 экспонента в десятичном - 134
00:06:24 экспонента в двоичном - 10000110
00:06:24 IEEE_754 в бинарном виде - 01000011001110010111000000000000
00:06:24 IEEE_754 в десятичном виде - 1127837696
00:06:24 IEEE_754 в шестнадцатеричном виде - 0x43397000


« Last Edit: November 03, 2019, 12:29:40 AM by dramster »

ya12

  • Активный участник
  • ***
  • Posts: 165
    • View Profile
Нашел в клиенте координаты(float) модели перса. Можно двигать модель в клиенте. Серверные координаты разумеется неизменны и за пределами радиуса обзора мир статичен.
Фича в том, что если стоять рядом с камнем, изменить Z координаты на выше камня, то локальная модель на камень спуститься, а серверная запрыгнет. Таким образом можно собрать дроп упавший на не доступной местности.