我在C中实现了一种新的浮点“new float”,它使用32位,没有符号位(只有正数)。
所以整个32位被指数或尾数所使用。
在我的示例中,指数(EXPBITS)为6位,尾数(MANBITS)为26位。
我们有一个用于表示负指数的偏移量,它是(2^(EXPBITS-1)-1)。
给定一个NewFloat nf1,实数的转换如下:
nf1=2^(指数-偏移)*(1+尾数/2^MANBITS)。
现在,假设有两个新的浮点(nf1,nf2),每个浮点都有(exp1,man1,exp2,man2和相同的偏移量),
假设nf1>nf2,我可以计算nf1和nf2之和的指数和尾数,这样做:link
为了打发你的时间,我发现:
和的指数为:exp1
和的尾数是:man1+2^(exp2-exp1+MANBITS)+2^(exp2-exp1)*man2
为了简化代码,我将尾数的每个部分分开计算:
x=2^(exp2-exp1+MANBITS)
y=2^(exp2-exp1)*人2
我有点确定我没有执行正确的尾数部分:
unsigned long long x = (1 << (exp2 - exp1 + MANBITS));
unsigned long long y = ((1 << exp2) >> exp1) * man2;
unsigned long long tempMan = man1;
tempMan += x + y;
unsigned int exp = exp1; // CAN USE DIRECTLY EXP1.
unsigned int man = (unsigned int)tempMan;
总和表示如下:
总和=2^(exp1-偏移量)*(1+(man1+x+y)/2^MANBITS)。
最后一件事我必须处理的是金额尾数溢出的情况。
在这种情况下,我应该在指数上加1,然后除以整个(1+(man+x+y)2^MANBITS)表达式。
在这种情况下,考虑到我只需要用位来表示nominator,如何在除法之后这样做?
我的执行有什么问题吗?我有种感觉。
如果你有更好的方法做这件事,我真的很高兴听到。
拜托,别问我为什么这么做。。这是一个练习,我已经试着解决了10个多小时了。
最佳答案
代码正在执行signed int
移位,当然需要unsigned long long
。
// unsigned long long x = (1 << (exp2 - exp1 + MANBITS));
unsigned long long x = (1LLU << (exp2 - exp1 + MANBITS));
笔记:
建议使用更有意义的变量名,如
x_mantissa
。未执行舍入。舍入可能导致指数增加。
未检测到/实现溢出。
未实现次法线。不应该使用它们,不是说
NewFloat
并不意味着a-b --> 0
。