Здравствуйте Dima2, Вы писали:
D>Здравствуйте Edmond, Вы писали:
E>>Пошли эту тему в Assembler, пусть тебе составять самый быстрый декодер
D>Да мне самый быстрый не надо, устроит и на С++. D>А как asm инструкция для десятичной коррекции, не помню то ли edc, то ли dac?
У Боба Стоута в snippets прекрасный пример на C, www.snippets.org, если не найдете могу выслать. Но snippets вроде у кождого есть... или должен быть...
Здравствуйте Dima2, Вы писали:
D>Помогите может у кого валяется готовый алгоритм преобразования в BCD и обратно. D>Блин помню когда-т описал, а щас не найду.
D>Пример:
D>BCD код == 0x4711 это равно 4711 десятичное
Если абстрагироваться от x86.
Это же довольно просто. Аналогично преобразованию число/строка (только там char, а здесь тетрады)
unsigned bcd_to_bin(unsigned x)
{
unsigned y = 0;
while(x != 0)
{
assert((x & 0xF) < 10); // иначе это не BCD
y *= 10;
y += (x & 0xF);
x >>= 4;
}
return y;
}
unsigned bin_to_bcd(unsigned x)
{
assert(x < 100000000); // для 32-разрядных платформunsigned y = 0;
while(x != 0)
{
y <<= 4;
y += (x % 10);
x /= 10;
}
return y;
}
Здравствуйте Dima2, Вы писали:
D>Помогите может у кого валяется готовый алгоритм преобразования в BCD и обратно. D>Блин помню когда-т описал, а щас не найду.
D>Пример:
D>BCD код == 0x4711 это равно 4711 десятичное
Во первых ты не уточнил: упакованное/ не упакованное...
То что ты привёл упакованное...
Ничего особово в алгоритме нет...
Как образец смотри команды x86 коррекции, которые и осуществляют коррекцию
AAD — Ascii Adjust for Division
Usage: AAD
Modifies flags: SF ZF PF (AF,CF,OF undefined)
Used before dividing unpacked decimal numbers. Multiplies AH by
10 and the adds result into AL. Sets AH to zero. This instruction
is also known to have an undocumented behavior.
AL := 10*AH+AL
AH := 0
AAM — Ascii Adjust for Multiplication
Usage: AAM
Modifies flags: PF SF ZF (AF,CF,OF undefined)
AH := AL / 10
AL := AL mod 10
Used after multiplication of two unpacked decimal numbers, this
instruction adjusts an unpacked decimal number. The high order
nibble of each byte must be zeroed before using this instruction.
This instruction is also known to have an undocumented behavior.
Clocks Size
Пошли эту тему в Assembler, пусть тебе составять самый быстрый декодер
Здравствуйте Eugenue, Вы писали:
E>У Боба Стоута в snippets прекрасный пример на C, www.snippets.org, если не найдете могу выслать. Но snippets вроде у кождого есть... или должен быть...
Здравствуйте Dima2, Вы писали:
D>Помогите может у кого валяется готовый алгоритм преобразования в BCD и обратно. D>Блин помню когда-т описал, а щас не найду.
D>Пример:
D>BCD код == 0x4711 это равно 4711 десятичное
Ну так в Intel x86 архитектуре для этого есть специальные команды
Посмотри любой справочник по ассемблеру
Здравствуйте Кодт, Вы писали:
К>Если абстрагироваться от x86. К>Это же довольно просто. Аналогично преобразованию число/строка (только там char, а здесь тетрады)
Просто, то просто, но вот писать все заново не хотелось, плюс ко всему надо было сложение(деление...) в BCD коде. Перекидывать из BCD в десятичное, складывать, а затем опять пихать в BCD, не очень красиво, да и не всегда возможно, т.к. разрядности даже __int64 может не хватить, т.к. BCD число может быть трехэтажное.
Здравствуйте Dima2, Вы писали:
D>Здравствуйте Кодт, Вы писали:
К>>Если абстрагироваться от x86. К>>Это же довольно просто. Аналогично преобразованию число/строка (только там char, а здесь тетрады)
D>Просто, то просто, но вот писать все заново не хотелось, плюс ко всему надо было сложение(деление...) в BCD коде. Перекидывать из BCD в десятичное, складывать, а затем опять пихать в BCD, не очень красиво, да и не всегда возможно, т.к. разрядности даже __int64 может не хватить, т.к. BCD число может быть трехэтажное.
А зачем проводить вычисления в BCD?
Может, проще внутреннее представление сделать бинарным, и конвертировать только в моменты экспорта-импорта?
И потом, если не хватит разрядности __int64, то ее и так и этак не хватит (если переполнение — штатная ситуация).
...
Если очень нужно, изобретем велосипед. Даже посодействую...
Здравствуйте Кодт, Вы писали:
К>А зачем проводить вычисления в BCD? К>Может, проще внутреннее представление сделать бинарным, и конвертировать только в моменты экспорта-импорта?
Ну например во что ты будеш конвертировать 20-ти разрядное BCD число? В __int64 оно может не влезть.
А мне необходимо делать какие-либо действия над этими числами, например сложить их.
Здравствуйте Dima2, Вы писали:
D>Здравствуйте Кодт, Вы писали:
К>>А зачем проводить вычисления в BCD? К>>Может, проще внутреннее представление сделать бинарным, и конвертировать только в моменты экспорта-импорта? D>Ну например во что ты будеш конвертировать 20-ти разрядное BCD число? В __int64 оно может не влезть. D>А мне необходимо делать какие-либо действия над этими числами, например сложить их.
Дааа. Тяжко...
Окэй
typedef unsigned char byte;
void bcd_add(byte& a, byte b, bool& c)
// [in out] a - accumulator
// [in] b - increment
// [in out] c - carry flag
{
assert((a & 0xF) <= 9);
assert((b & 0xF) <= 9);
assert((a & 0xF0) <= 0x90);
assert((b & 0xF0) <= 0x90);
byte t1 = (a & 0xF) + (b & 0xF) + c; // младшая тетрадаif(t1 > 10) t1 += 6; // коррекция: 0x0A..0x12 -> 0x10..0x18
byte t2 = (a >> 4) + (b >> 4) + (t1 >> 4); // старшая тетрадаif(t2 > 10) t2 += 6;
a = (t1 & 0xF) | (t2 << 4);
c = (t2 > 0x10);
}
void bcd_add_vector(byte* a, const byte* b, bool& c, size_t s)
// младшими разрядами вперед, длиной s
{
size_t i;
for(i = 0; i < s; i++)
bcd_add(a[i], b[i], c);
}
template<class inttype>
void bcd_add_int(inttype& a, inttype b, bool& c)
{
bcd_add_vector((byte*)(void*)(&a), (const byte*)(const void*)(&b), c);
}