Hi all,
I need to multiply a 32 bit integer by a 16 bit integer and divide that result by a 16 bit integer. For the intermediate result I need more than 32 bits. I am programming in C using CW. Any ideas on implementing an unsigned long long variable?
Thanks,
David
解決済! 解決策の投稿を見る。
You didn't say if you tolerate assembler. Here's my code:
#include <hidef.h> /* common defines and macros */
#include "derivative.h" /* derivative-specific definitions */
typedef struct
{
unsigned short hibits;
unsigned long lobits;
} u48;
// *product = m32 * m16
void mul32x16_48(u48 *product, unsigned long m32, unsigned short m16)
{
asm
{
LDX product
LDD m32:2
LDY m16
EMUL
STD 4,x
STY 2,x
LDD m32
LDY m16
EMUL
ADDD 2,x
STD 2,x
TFR Y,D
ADCB #0
ADCA #0
STD 0,x
}
}
// *q = *nom / denom
void div48x16(u48 *q, u48 *nom, unsigned short denom)
{
u48 qtmp;
asm
{
LDY nom
LDD 0,y
LDX denom
IDIV
STX qtmp:0
TFR D,X
LDD 2,y
LDY denom
EXG Y,X
EDIV
STY qtmp:2
LDY nom
LDY 4,y
EXG D,Y
EDIV
STY qtmp:4
}
*q = qtmp;
}
u48 product;
u48 quot;
void main(void) {
/* put your own code here */
mul32x16_48(&product, 0x9876543F, 0xF765);
div48x16(", &product, 0xEDAB);
EnableInterrupts;
for(; {
_FEED_COP(); /* feeds the dog */
} /* loop forever */
/* please make sure that you never leave main */
}
You didn't say if you tolerate assembler. Here's my code:
#include <hidef.h> /* common defines and macros */
#include "derivative.h" /* derivative-specific definitions */
typedef struct
{
unsigned short hibits;
unsigned long lobits;
} u48;
// *product = m32 * m16
void mul32x16_48(u48 *product, unsigned long m32, unsigned short m16)
{
asm
{
LDX product
LDD m32:2
LDY m16
EMUL
STD 4,x
STY 2,x
LDD m32
LDY m16
EMUL
ADDD 2,x
STD 2,x
TFR Y,D
ADCB #0
ADCA #0
STD 0,x
}
}
// *q = *nom / denom
void div48x16(u48 *q, u48 *nom, unsigned short denom)
{
u48 qtmp;
asm
{
LDY nom
LDD 0,y
LDX denom
IDIV
STX qtmp:0
TFR D,X
LDD 2,y
LDY denom
EXG Y,X
EDIV
STY qtmp:2
LDY nom
LDY 4,y
EXG D,Y
EDIV
STY qtmp:4
}
*q = qtmp;
}
u48 product;
u48 quot;
void main(void) {
/* put your own code here */
mul32x16_48(&product, 0x9876543F, 0xF765);
div48x16(", &product, 0xEDAB);
EnableInterrupts;
for(; {
_FEED_COP(); /* feeds the dog */
} /* loop forever */
/* please make sure that you never leave main */
}
Hey kef,
Works great!!!
Thanks so much!!
David
Hi kef,
Do you have a divide routine for 48 bits divided by 24 bits?
Thanks,
David
No, I don't. 24bits divider is well more complicated using S12 division instructions. Shift-subtract loop is the easy way to go. But shift-subtract is slow and new code requires some debugging. Then why not just using double precision floating point arithmetics? Since double mantissa is 52bits wide, double can contain up to 52bits wide integers without any rounding or loss of precision issues.
I am avoiding use the floating point math library to keep the code smaller.
Thanks,
David