2013-05-31 5 views
0

Edit:Строка BCD (Причал Дельфи)

У меня есть (тестовый файл в формате ASCII) следующие записи в формате ASCII: «000000000,00»
мне нужно выводить их ISO при разборе это счетчик часть в BCD (другой тестовый файл в bcd/ebcdic).
Я считаю, что он принимает 6 символов в BCD и 11 в ascii.
Так что моя потребность была чем-то, что могло бы преобразовать ее взад-вперед.
Сначала я подумал о том, чтобы взять каждый символ, передать его функции преобразования и преобразовать его обратно, следовательно, мой перепутанный вопрос.

Надеюсь, что я более ясен.

Yain

+0

Подождите ... Ваше имя функции 'bcdConvInt', но вы передаете ему' AnsiString'. Вы действительно ищете 'BCDStringToInt'? Пожалуйста, отредактируйте свой вопрос, чтобы исправить заголовок или объяснить, что именно вы хотите сделать, потому что эти два сочетания не имеют смысла. Почему вы берете значение BCD из файла и сохраняете его в строке? Это не строка. –

+0

Вы правы. Я устал от проблемы с ebcdic, которую я решил раньше. –

+1

Пожалуйста, отредактируйте еще раз, чтобы предоставить образец строки, которую вы пытаетесь преобразовать, и значение, которое вы ожидаете от конвертирования, так как «(это как-то испортило мой разбор») говорит, что ваш разбор неправильный. 'StrToBCD' и' BCDToStr' были в течение некоторого времени, поэтому я сомневаюсь, что проблема связана с этими функциями. –

ответ

3

Д-р Питер Ниже (из Team B) пожертвовал их в старых группах новостей Borland Delphi несколько лет назад:

// NO NEGATIVE NUMBERS either direction. 

// BCD to Integer 
function BCDToInteger(Value: Integer): Integer; 
begin 
    Result := (Value and $F); 
    Result := Result + (((Value shr 4) and $F) * 10); 
    Result := Result + (((Value shr 8) and $F) * 100); 
    Result := Result + (((Value shr 16) and $F) * 1000); 
end; 

// Integer to BCD 
function IntegerToBCD(Value: Integer): Integer; 
begin 
    Result :=     Value div 1000 mod 10; 
    Result := (Result shl 4) or Value div 100 mod 10; 
    Result := (Result shl 4) or Value div 10 mod 10; 
    Result := (Result shl 4) or Value   mod 10; 
end; 
+0

Довольно уверен, что это ответ, который ищет OP, а не мои размышления ... – Floris

+0

Зачем вам использовать это, а не встроенные функции? –

+0

Я этого не делал, и я не задавал вопрос. Вопрос специально задал вопрос об этом без встроенных функций, и я отправил его в ответ на этот вопрос (который был совсем немного отличается от того, что есть сейчас). Затем плакат пересмотрел вопрос, но не ответил ни на один из последующих вопросов.Теперь кажется, что это проблема с синтаксическим разбором, о котором даже не упоминалось в исходном вопросе. Я не знаю, какова настоящая проблема, и пока плакат не уточнит это, я просто оставил ответ. Я удалю его, если потребуется. –

0

Как вы знаете, ASCII коды цифр 0 через 9 - от 48 до 57. Таким образом, если вы конвертируете каждый символ по очереди в эквивалент ASCII и вычитаете 48, вы получите его численное значение. Затем вы умножаетесь на десять и добавляете следующий номер. В псевдокоде (извините, не Дельфы парень):

def bcdToInt(string): 
    val = 0 

    for each ch in string: 
    val = 10 * val + ascii(ch) - 48; 

    return val; 

Если «строка» на самом деле содержит «значения истинно BCD» (то есть, цифры от 0 до 9, а не их ASCII эквивалентной 48 до 57), то не вычитайте 48 в приведенном выше коде. Наконец, если два значения BCD заправлены в один байт, вы получите доступ к последовательным элементам с поразрядным И с помощью 0x0F (15). Но в этом случае решение Кена Уайта явно более полезно. Надеюсь, этого хватит, чтобы вы пошли.

0

функции ниже работают для 8-значных шестнадцатеричных и двоичных значений.

function BCDToInteger(Value: DWORD): Integer; 
const Multipliers:array[1..8] of Integer=(1, 10, 100, 1000, 10000, 100000, 1000000, 10000000); 
var j:Integer; 
begin 
Result:=0; 
for j:=1 to 8 do //8 digits 
Result:=Result+(((Value shr ((j-1)*4)) and $0F) * Multipliers[j]); 
end;//BCDToInteger 

function IntegerToBCD(Value: DWORD): Integer; 
const Dividers:array[1..8] of Integer=(1, 10, 100, 1000, 10000, 100000, 1000000, 10000000); 
var j:Integer; 
begin 
Result:=0; 
for j:=8 downto 1 do //8 digits 
Result:=(Result shl 4) or ((Value div Dividers[j]) mod 10); 
end;//IntegerToBCD 
Смежные вопросы