免费高清特黄a大片,九一h片在线免费看,a免费国产一级特黄aa大,国产精品国产主播在线观看,成人精品一区久久久久,一级特黄aa大片,俄罗斯无遮挡一级毛片

分享

Linux內(nèi)核中64位除法函數(shù)do_div

 langhuayipian 2014-02-20

Linux內(nèi)核中64位除法函數(shù)do_div


使用asm/div64.h中宏do_div

 

#include <asm/div64.h>

unsigned long long x,y,result;

unsigned long mod;

mod = do_div(x,y);

result = x; 

 

    64 bit division 結(jié)果保存在x中;余數(shù)保存在返回結(jié)果中。



問題】

編譯Linux下面的代碼,經(jīng)常會遇到這種錯誤:

undefined reference to `__udivdi3'

【解決過程】

之前遇到過幾次了,都是類似的原因?qū)е麓藛栴}的。后來才了解,其根本原因:

嵌入式中,32位系統(tǒng)中(目前多數(shù)系統(tǒng)都是,比如ARM的片子),對于普通的a除以b(b為32位):

(1)當(dāng)a為32位,Linux 內(nèi)核中,常用uint32_t 類型,可以直接寫為 a/b

(2)但是,對于a是64位,uint64_t的時候,就要用到專門的除操作相關(guān)的函數(shù),linux內(nèi)核里面一般為

do_div(n, base),注意,此處do_div得到的結(jié)果是余數(shù),而真正的a/b的結(jié)果,是用a來保存的。

do_div(n,base)的具體定義,和當(dāng)前體系結(jié)構(gòu)有關(guān),對于arm平臺,在

arch/arm/include\asm\div64.h

其實現(xiàn)很復(fù)雜,感興趣的自己去代碼里看吧,這里不多說了。

因此,如果你當(dāng)前寫代碼,a/b,如果a是uint64_t類型,那么一定要利用do_div(a,b),而得到結(jié)果a,

而不能簡單的用a/b,否則編譯可以正常編譯,但是最后鏈接最后出錯,會提示上面的那個錯誤:

undefined reference to "__udivdi3"

【解決方法】

知道原因,就好辦了。辦法就是,去你代碼里面找到對應(yīng)的用到除法的地方,即類似于a/b的地方,其中被除數(shù)a為64位,Linux中一般用用 uint64_t,將a/b用do_div(a,b)得到的a去代替(注意,不是直接用do_div()得到真正a除b后的結(jié)果,因為 do_div(a,b)得到的是余數(shù),囧。。。),即可,而具體寫其他,就顯得很麻煩。此處,我們可以借鑒Linux中\(zhòng)fs\yaffs2 \yaffs_fs.c中的宏:

static uint32_t YCALCBLOCKS(uint64_t partition_size, uint32_t block_size)
{
uint64_t result = partition_size;
do_div(result, block_size);
return (uint32_t)result;
}

來自己也去封裝一個支持64位數(shù)的除法的函數(shù),不過,Linux內(nèi)核就是好,早已經(jīng)幫我們實現(xiàn)了對應(yīng)的64位的unsingned和signed兩個函數(shù):

static inline u64 div_u64(u64 dividend, u32 divisor);

static inline s64 div_s64(s64 dividend, s32 divisor);
我們可以直接拿過來用了,注意用此函數(shù)時,要包含對應(yīng)頭文件:

#include <linux/math64.h>

總結(jié)一下就是:

1.先包含頭文件:

2.然后用(a,b)得到a/b的結(jié)果即可。

【提示】

如果需要在進行64位除數(shù)的時候,同時得到余數(shù)remainder,可以直接用

static inline u64 div_u64_rem(u64 dividend, u32 divisor, u32 *remainder);
static inline s64 div_s64_rem(s64 dividend, s32 divisor, s32 *remainder);

【引用】

1. - 64 bit division in linux

If you've encountered an error message like this

Unknown symbol __udivdi3Unknown symbol __umoddi3Unresolved symbol __udivdi3Unresolved symbol __umoddi3

you most likely want to make a 64 bit division, which is not supported by default in linux kernel space.
To solve this problem, you need to use the do_div macro available in asm/div64.h:

#include <asm/div64.h>unsigned long long x, y, result;unsigned long mod;mod = do_div(x, y);result = x;

If you want to calculate x / y with do_div(x, y), the result of the division is in x, the remainder is returned from the do_div function.
Since do_div is just an asm (assembler) macro, it doesn't break real time determinism, so it's also suitable for use in RTAI classic, RTAI fusion and ADEOS/ADEOS-IPIPE applications.

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多