LINUX.ORG.RU

Использование BC в Bash

 , , ,


0

1

Уважаемые программисты, подскажите пожалуйста, можно ли (и как) в интерпретаторе Bash, используя утилиту BC, перевести 4-х байтовое число из 16-тиричной формы в 10-ричную тип float? Или предложите другие варианты.


Ответ на: комментарий от turtle_bazon

А так перевод простой echo «ibase=16; hex-number»|bc

Всегда хочется спросить, а если заюзать встроенные средства bash, то что-то плохое случится? Ведь, насколько я понимаю, у ТС-а сам скрипт на bash.

printf "%d\n" $((16#$hex))
Вот с float уже да — нет поддержки.

vodz ★★★★★
()
Последнее исправление: vodz (всего исправлений: 1)
Ответ на: комментарий от turtle_bazon

Про float не понял

Это, наверное, чтобы вместо 5 выводилось 4.99999998.

anonymous
()
Ответ на: комментарий от vodz

Ведь, насколько я понимаю, у ТС-а сам скрипт на bash.

Может, на bc. :)

turtle_bazon ★★★★★
()
Ответ на: комментарий от turtle_bazon

А что непонятного? Есть общепринятый формат хранения float IEE 754. Человек хочет из какого-нибудь 0xdeadbeef получить -6.2598534e18.

Legioner ★★★★★
()
Ответ на: комментарий от Legioner

Кошмар какой. Зачем такое хотеть? Откуда такие данные могли прийти?

legolegs ★★★★★
()
Ответ на: комментарий от Legioner

Совершенно верно. Именно в таком формате с плавающей точкой должно быть число. Данные приходят по Modbus. 4 байта в 16-тиричном формате. Как предлагает turtle_bazon echo «ibase=16; hex-number»|bc - эта строка так же переводит в число без дроби.

boyko
() автор топика

напиши на С программку которая кладет 4 байта в переменную (в область памяти переменной типа float) и затем форматирует printf’ом в нужный вид. Программа на 2.5 строки.

futurama ★★★★★
()
Ответ на: комментарий от futurama

напиши на С программку которая кладет 4 байта в переменную (в область памяти переменной типа float) и затем форматирует printf’ом в нужный вид. Программа на 2.5 строки.

Сейчас придет Разорванный Флакон, и начнет тебе затирать, что это небезопасно, что нужно переписать эту программу на Расте с 4-этажным unsafe и ASCII артом прямо в коде. 🤠-/

anonymous
()
Ответ на: комментарий от anonymous

[code] echo 0xBEEF|awk ‘{print $1+0.0}’ 48879 echo 0xBEEF|awk ‘{printf «%f»,$1}’ 48879,000000 printf «%f» 0xBEEF 48879,000000 [/code]

anonymous
()
Ответ на: комментарий от anonymous
echo 0xBEEF|awk '{print $1+0.0}'
48879
echo 0xBEEF|awk '{printf "%f",$1}'
48879,000000
printf "%f" 0xBEEF
48879,000000

Надеюсь тому, кто установил маркдаун разметкой по умолчанию, икается хорошо.

anonymous
()
Ответ на: комментарий от anonymous

Спасибо за ответ. Но все эти команды переводят 16-тиричное число в 10-тичное в формат WORD или DWORD. Совсем не понятно зачем добавляются нули после точки. Может кто знает как правильно перевести число из 16 в 10 в формате с плавающей запятой? Какие байты отводятся под целую часть, а какие под дробную? Не смог я найти такой информации. Конкретный пример: Имеем число 0x3F45767F При переводе данными командами получим: 1061516927 А правильно должно быть: 0,7713393568992615 Вопрос стоял - можно ли такой перевод сделать при помощи утилиты BC в Bash? Похоже, что сам Bash, что BC и AWK работают только с целыми числами. Единственное, что мне удалось найти, это строка на Python: echo 0x3F45767F | python3 -c ‘import struct; print(struct.unpack(«!f», bytes.fromhex(input()))[0])’

boyko
() автор топика
Ответ на: комментарий от boyko

Но все эти команды переводят 16-тиричное число в 10-тичное

Правильно, ибо это обычная задача. У вас же перевод бинарных данных плавающих чисел в текстовое человеческое представление десятичных плавающих чисел. Формулировать надо внятнее. Такая задача редкая, не очень в принципе идеологически правильная, если возникает и обычно предназначена для выгрузки и загрузки одной и той же утилитой, мало ли чего она зашифровала в эти бинарные данные дополнительно.

vodz ★★★★★
()
Ответ на: комментарий от next_time

в этом примере: printf - утилита командной строки %f - опция 0xFFFF - шестнадцатиричное представление вашего числа

переведите свои бинарные данные в хекс - затем скормите printf

next_time ★★★★★
()
Ответ на: комментарий от next_time

А не, вру - оно не то делает. Баш как всегда тупой, как пробка.

next_time ★★★★★
()
Ответ на: комментарий от next_time

читабельность убежит

Это потому, что в примерах всегда простейшие действия для демонстрации проблемы (и правильно). Но как только надо заюзать в жизни, не просто напечатать, а работать со значением, да еще и со сложным выражением, так оказывается, что эти ваша «читабельность» вовсе не при делах. Ибо в том примере просто добавляем -v var и получаем значение в переменную, а для bc будем рисовать $() с кавычками в кавычках и где ваша читабельность. И, заметьте, я ни слова не сказал о скорости выполнения этого всего в глубоком цикле. :)

vodz ★★★★★
()
Последнее исправление: vodz (всего исправлений: 2)
Ответ на: комментарий от vodz

речь о читабельности и скорости не идёт. Надо что бы правильно перевелось значение. Как я выше писал строку на Питоне, наверное лучше не придумать.

boyko
() автор топика
Ответ на: комментарий от boyko

Как я выше писал строку на Питоне, наверное лучше не придумать.

Ну если наилучшее, то уж точно на C лучше не придумать.

vodz ★★★★★
()
Последнее исправление: vodz (всего исправлений: 1)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.