Some code that rounds off a division to demonstrate (C syntax):
SINT64 divRound(SINT64 dividend, SINT64 divisor)
{
SINT32 quotient1 = dividend / divisor;
SINT32 modResult = dividend % divisor;
SINT32 multResult = modResult * 2;
SINT32 quotient2 = multResult / divisor;
SINT64 result = quotient1 + quotient2;
return ( result );
}
Now, if it were User-space, we probably would not even notice that our compiler generates code for these operators (for example, divdi3 () for division). Most likely, we contact "libgcc" without even knowing about it. The problem is that the kernel space is different (for example, there is no libgcc). What to do?
Crawl Google for a while, note that almost everyone accesses an unsigned option:
#define UINT64 long long int
#define UINT32 long int
UINT64 divRound(UINT64 dividend, UINT64 divisor)
{
UINT32 quotient1 = dividend / divisor;
UINT32 modResult = dividend % divisor;
UINT32 multResult = modResult * 2;
UINT32 quotient2 = multResult / divisor;
UINT64 result = quotient1 + quotient2;
return ( result );
}
I know how to fix this: override udivdi3 () and umoddi3 () with _do_div () _ from asm / div64.h. Correctly? Wrong. Signed does not match unsigned, sdivdi3 () _ does not just call udivdi3 (), they are separate functions for some reason.
? , ? , , .
,
Chad