![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Перевести значение из BCD в integer
Oni © (2005-11-19 15:27:00)Вопрос такой - есть значение, длиной в 8 бит, в формате BCD. Необходимо перевести его в integer.Как это сделать применительно к Дельфи - непонятно
Oni (2005-11-20 12:29:00) [1]Господа, простите великодушно, в первый пост вкралась непростительная очепятка не 8 бита 8 байт
Anatoly Podgoretsky (2005-11-20 12:05:00) [2]8 бит преобразовываются легко
Int := (N shr 4) * 10 + (N and $0F)
Anatoly Podgoretsky (2005-11-20 12:03:00) [3]Еще много тайн скрыто от нас, при том они имеют тенденцию двигаться в разные стороны и неоднакратно.
Чем дальше в лес, тем толще партизаны.
begin...end (2005-11-20 11:41:00) [4]> Германн © (20.11.05 02:21) [11]
> Я бы лично, не советовал бы автору применять никакие функции,
> пока он не скажет откуда он берет "значение, длиной в 8
> бит, в формате BCD"!
И чем Вам поможет, скажем, название программы, из которой берётся это значение?
> Тем более, что в формате BCD могут быть записаны и не Integer
> значения.
В посте [0] чёрным по белому написано, что значение целое.
> Oni (19.11.05 19:15) [9]
А зачем тогда было говорить, что он неупакованный? Мы же хотим помочь, а Вы нас зачем-то в заблуждение вводите.
:-)
> Oni (19.11.05 22:39) [10]
Да, в Delphi 5 нет этого модуля. Значит, надо ручками делать. Только если бы изначально было сказано, какая версия Delphi используется, то вопрос был бы уже решён.
:-)
> Oni (20.11.05 03:00) [12]
> Мне бы принцип перевода узнать.
В упакованном BCD каждый полубайт содержит одну десятичную цифру. А каждый байт, таким образом, содержит 2 десятичные цифры. Например, пусть значение байта равно 149. Запишем это в двоичном виде (можно использовать калькулятор Windows): 1001 0101. Младший полубайт -- это 5, а старший -- это 9. Значит, было закодировано число 95.
Ещё легче переводить, если представить исходный байт сразу в шестнадцатеричном виде. Каждая шестнадцатеричная цифра, как известно, представляет один полубайт. А поскольку в каждом полубайте закодирована одна десятичная цифра (т.е. значение полубайта не превышает 9), то шестнадцатеричное представление совпадает с десятичным закодированным числом. Переводим 149 в HEX: $95, и сразу видим, что изначально было число 95.
Теперь разберём, например, первые 8 байт из [2]:
DEC: 16 149 132 89 3 0 0 0
HEX: 1 0 9 5 8 4 5 9 0 3 0 0 0 0 0 0
Двоично-десятичные числа обычно располагаются в памяти так же, как и двоичные: младший байт по младшему адресу. Учитывая это, можно сказать, что получилось число 359849510.
Вот код, который может сделать такое преобразование:
type
TBCD = array [1..8] of Byte;
const
BCD: TBCD = (16, 149, 132, 89, 3, 0, 0, 0);
var
Value, Base: Int64;
I: Integer;
begin
Value := 0;
Base := 1;
for I := Low(BCD) to High(BCD) do
begin
Value := Value + Base * (BCD[I] and $0F) + Base * 10 * (BCD[I] shr 4);
Base := Base * 100;
end;
ShowMessage(IntToStr(Value))
end
Впрочем, можно и так:
Value := StrToInt64(IntToHex(Int64(BCD), 8))
:-)
Что печально -- не обязательно, что BCD-числа будут располагаться по принципу "младший байт по младшему адресу". Программист зачастую может сам решать, как ему удобнее.
P.S. Только почему-то изначально говорилось о числах из 8 бит , а уже в [2] -- о числах из 8 байт .
:-)
Германн (2005-11-20 03:43:00) [5]Так. А что ты знаешь об этой программе? Что и как она передает?
Oni (2005-11-20 03:00:00) [6]Пардон, не Long64, а Int64
Oni (2005-11-20 03:00:00) [7]Значения берутся от программы, опрашивающей электрические счётчики.Значения числовые и не дробные.Т.е. тип может быть и Long64. Мне бы принцип перевода узнать. Или, хотя-бы, где копать.
Германн (2005-11-20 02:21:00) [8]2 begin...end © (19.11.05 18:58) [8]
Я бы лично, не советовал бы автору применять никакие функции, пока он не скажет откуда он берет "значение, длиной в 8 бит, в формате BCD"!
Тем более, что в формате BCD могут быть записаны и не Integer значения.
Oni (2005-11-19 22:39:00) [9]А модуль FmtBCD я у себя не нашел. Использую Delphi 5.
Oni (2005-11-19 19:15:00) [10]Чесно сказать, я сам сомневаюсь что он неупакованный :)
begin...end (2005-11-19 18:58:00) [11]> heh (19.11.05 18:52) [7]
Я просто не понял, почему [5] последовало в ответ на [4]. По [2] видно, что упакованный, но автор говорит об обратном.
Если всё же действительно упакованный, то могу посоветовать автору функцию BCDToInteger из модуля FmtBCD.
heh (2005-11-19 18:52:00) [12][6] begin...end © (19.11.05 18:39)
В чём ваша цель? В посте [2] видно, с чем имеет дело автор.
begin...end (2005-11-19 18:39:00) [13]> heh (19.11.05 18:27) [5]
К чему это? В [4] речь про неупакованный формат, а в Вашем примере -- упакованный.
heh (2005-11-19 18:27:00) [14]>превышающие 9
153, 9*16+9 = 153
begin...end (2005-11-19 17:48:00) [15]> Oni (19.11.05 16:21) [2]
Не понял я. Если бы формат был неупакованным, то среди значений байтов не встречались бы числа, превышающие 9.
heh (2005-11-19 16:35:00) [16]Oni (19.11.05 15:27)
Обычно BCD каждая десятичная цифра кодируется 4-мя битами, т.е. в одном байте можно закодировать две цифры или число 0..99. Проверить такое ли у тебя BCD просто - в Windows калькуляторе введи это число и преобразуй в режим "hex"
Oni (2005-11-19 16:21:00) [17]Не упакованное.
Вот к примеру 24 байта массива содержащего разные значения:
16_149_132_89_3_0_0_0 » 8 байт - от младшего к старшему = значение.
128_5_0_0_0_0_0_0 » следующие байты хранящие значение
16_20_102_65_0_0_0_0 » следующие байты...
begin...end (2005-11-19 15:29:00) [18]В каком оно формате? Есть упакованные и неупакованные BCD-числа.