Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/58.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 如何在Linux内核中划分两个64位数字?_C_Linux_64 Bit - Fatal编程技术网

C 如何在Linux内核中划分两个64位数字?

C 如何在Linux内核中划分两个64位数字?,c,linux,64-bit,C,Linux,64 Bit,一些将该部分四舍五入以演示的代码(C语法): 现在,如果这是用户空间,我们可能甚至不会注意到我们的编译器正在为这些操作符生成代码(例如,divdi3()for division)。很可能我们连自己都不知道就链接到了libgcc。问题是内核空间不同(例如,nolibgcc)。怎么办 在Google上爬行一段时间,注意几乎每个人都会处理未签名的变体: #define UINT64 long long int #define UINT32 long int UINT64 divRound(UINT6

一些将该部分四舍五入以演示的代码(C语法):

现在,如果这是用户空间,我们可能甚至不会注意到我们的编译器正在为这些操作符生成代码(例如,
divdi3()
for division)。很可能我们连自己都不知道就链接到了
libgcc
。问题是内核空间不同(例如,no
libgcc
)。怎么办

在Google上爬行一段时间,注意几乎每个人都会处理未签名的变体:

#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 );
}
我知道如何解决这个问题:使用asm/div64.h中的
do_div()
覆盖
udivdi3()
umoddi3()
。做对了吗?错。Signed与unsigned不同,
sdivdi3()
不只是调用
udivdi3()
,它们是独立的函数,这是有原因的

你解决这个问题了吗?你知道有哪个图书馆可以帮我做这件事吗?我真的被卡住了,所以无论你在这里看到什么,我现在不知道的,都会很有帮助

谢谢, 乍得

ldiv


编辑:重读标题,所以您可能希望忽略此内容。或者没有,这取决于它是否有合适的非库版本。

这是我真正天真的解决方案。您的里程可能会有所不同

保留一个符号位,即
符号(被除数)^sign(除数)
。(或
*
,或
/
,如果您将符号存储为1和-1,而不是false和true。基本上,如果其中一个为负,则为负;如果没有或两者都为负,则为正。)

然后,对两者的绝对值调用无符号除法函数。然后将标志钉回结果上

另外,这实际上是
\uuu divdi3
libgcc2.c
中实现的方式(来自GCC4.2.3,安装在我的Ubuntu系统上的版本)。我刚查过。:-)

我认为(至少找不到办法)在这种情况下不起作用,因为do_div()实际上改变了股息。获取绝对值意味着一个临时变量,其值将改变我需要的方式,但不能从我的\uu divdi3()覆盖中传递出去

在这一点上,除了模仿do\u div()所使用的技术外,我看不到任何方法可以绕过\u divdi3()的参数按值签名

这可能看起来像是我在向后弯腰,应该想出一个算法来进行我实际需要的64位/32位除法。然而,这里增加的复杂性是,我有一堆使用“/”运算符的数字代码,需要遍历这些代码,并用我的函数调用替换每个“/”

不过,我已经迫不及待要这么做了

谢谢你的跟进,
Chad

早在内核v2.6.22中就引入了此功能。

最近,我们为每一个要使用的代码都提供了一份libgcc实现的副本(在lib/libgcc IIRC下)。但内核中的旧方法实际上是do_div()或div64.c中的相应函数。
#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 );
}