【问题标题】:custom floats addition, implementing math expression - C自定义浮点加法,实现数学表达式 - C
【发布时间】:2014-12-26 15:23:12
【问题描述】:

我在 C 中实现了一种新的浮点数“NewFloat”,它使用 32 位,它有 没有符号位(只有正数。 所以整个 32 位被指数或尾数使用。

在我的示例中,指数 (EXPBITS) 有 6 位,尾数 (MANBITS) 有 26 位。 并且我们有一个用于表示负指数的偏移量,即 (2^(EXPBITS-1)-1)。

给定一个 NewFloat nf1,转换为实数如下: nf1 = 2^(指数 - 偏移量) * (1 + 尾数/2^MANBITS)。

现在,给定两个 NewFloat(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) * man2

我有点确定我没有正确实施尾数部分:

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;

总和表示如下: sum = 2^(exp1 - offset) * (1 + (man1 + x + y)/2^MANBITS)。

我必须处理的最后一件事是总和尾数溢出的情况。 在这种情况下,我应该给指数加 1 并整除 (1 + (man + x + y)2^MANBITS) 表达式。

那么,既然我只需要用位来表示提名者,那么除法之后我该怎么做呢?

我的实现有什么问题吗?我有一种感觉。

如果你有更好的方法,我会很高兴听到的。

请不要问我为什么要这样做。这是一个我已经尝试解决了 10 多个小时的练习。

【问题讨论】:

  • 编写浮点套件并非易事。当库函数速度慢得令人无法接受或不存在时,我已经这样做了。如果您必须重新发明轮子,至少要使格式符合 IEEE。
  • 如果你确实得到了这个“工作”,你必须测试拐角条件令人作呕以及所谓的例行任务。编写一个测试程序,循环遍历有效和无效数据的权限,并在一夜之间运行它,将结果与一个有根据的实现进行比较。

标签: c floating-point add bit addition


【解决方案1】:

代码正在执行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 --&gt; 0 不代表a == b

【讨论】:

  • Xcode 不知道“LUU”而是“LLU”,我想这就是你的意思。嗯,这并没有解决我的问题,我也不明白为什么需要它......只要我做左移,我为什么要关心类型(有符号或无符号)?如果我想在右移时按 0,我应该使用无符号,不是吗?不过感谢您的 cmets。
  • @johni 假设 int 是 32 位的。执行1 &lt;&lt; 48 正在移动int 超过其宽度,这是未定义行为(UB)。一个典型的结果是只使用了 48 的最低有效 5 位,并出现1 &lt;&lt; 16 的结果。通过使用1LLU,代码正在移动unsigned long long(至少64位类型)。
  • @johni 关于有符号整数和无符号整数:代码正在将有偏尾数形成为无符号整数结果。如果代码使用无符号类型而不是有符号类型来表示无符号有偏尾数,那么肯定不会让其他人感到困惑。
  • 是的,我现在明白为什么我们需要 LLU。谢谢。但仍然无法解决问题。
  • @johni 发布更多信息、示例或失败详细信息会有所帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多