gpt4 book ai didi

c - 在c中添加正负浮点值

转载 作者:太空宇宙 更新时间:2023-11-04 02:54:34 25 4
gpt4 key购买 nike

我知道,另一个关于浮点运算的主题!

我一直在努力解决这个问题,但似乎无法想出为什么添加负浮点值对我不起作用。

如果它们都是正值,则一切都按预期工作(返回的数字并没有超出预期,因为这毕竟是 float )。

我使用的是 32 位版本,因为它不是很明显 ;)

我已经通读了:http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html并且在网上找到了各种很好的浮点运算解释——但是,我似乎仍然无法弄清楚如何添加混合的正值和负值(或下面代码中的情况 2、3 和 4)。

到目前为止,这是我的代码:

int flt32_get_sign (flt32 x) {

/** shift sign bit right; 0 = pos, 1 = neg */
return ((x & 0x80000000) >> 31);
}

int flt32_get_exp (flt32 x) {

/** get biaseed exponent value */
return ((x & 0x7F800000) >> 23);
}

int flt32_get_val (flt32 x) {

/** mask off mantissa
* make sure implicit one set
*/
return ((x & 0x7FFFFF) ^ 0x800000);
}

int flt32_left_most_1 (int bits) {

int position = -1;

/** make sure working with abs value */
if (flt32_get_sign(bits) != 0){
bits = flt32_negate(bits);
}

while(bits != 0){
position++, bits >>=1;
}

return position;
}

int flt32_right_most_1 (int bits) {

int position = -1;

/** make sure working with abs value */
if (flt32_get_sign(bits) != 0){
bits = flt32_negate(bits);
}

while (!(bits & 1)){
position++, bits >>=1;
}

return position;
}

flt32 flt32_abs (flt32 x) {

return (x & 0x7FFFFFFF);
}

flt32 flt32_negate (flt32 x) {

if (flt32_get_sign(x) == 0){
/** is possitive */
return (x ^ 0x80000000);
}
/** else is negative */
return (x & 0x7FFFFFFF);
}

flt32 flt32_add (flt32 x, flt32 y) {

/**
* Possible casses:
* 1: +x +y; 2: +x -y; 3: -x +y; 4: -x -y
*/

flt32 sum, x_val, y_val;
int shift;


/** Case 1 */
if (flt32_get_sign(x) == 0 && flt32_get_sign(y) == 0){
if (flt32_get_exp(x) == flt32_get_exp(y)){
/** no shifting neccesary
* add mantissa's then mask to make sure
* we don't get overflow into the exponent bits
* then add exponent back to new value
*/
sum = (x & 0x7F800000) + ((flt32_get_val(x) + flt32_get_val(y)) & 0x7FFFFF);

} else if (flt32_get_exp(x) > flt32_get_exp(y)){
/** exponent of x is larger than y
* need to right shift y and set its exponent = exponent of x
*/
shift = (flt32_get_exp(x) - flt32_get_exp(y));
y_val = flt32_get_exp(x) + (flt32_get_val(y) >> shift);

sum = x + y_val;

} else {
/** exponent x is smaller than y
* need to right shift x and set its exponent = exponent of y
*/
shift = (flt32_get_exp(y) - flt32_get_exp(x));
x_val = flt32_get_exp(y) + (flt32_get_val(x) >> shift);

sum = x_val + y;
}
}

/** Case 2 */
if (flt32_get_sign(x) == 0 && flt32_get_sign(y) == 1){
if (flt32_get_exp(x) == flt32_get_exp(y)){
/** no shifting neccesary
* add mantissa's then mask to make sure
* we don't get overflow into the exponent bits
* then add exponent back to new value
*/
x_val = ((x & 0xFF800000) + flt32_get_val(x));
y_val = ((y & 0xFF800000) + flt32_get_val(y));

sum = x_val + flt32_negate(y_val);

} else if (flt32_get_exp(x) > flt32_get_exp(y)){
/** exponent of x is larger than y
* need to right shift y and set its exponent = exponent of x
*/
shift = (flt32_get_exp(x) - flt32_get_exp(y));
y_val = flt32_get_exp(x) + (flt32_get_val(y) >> shift);

sum = x + flt32_negate(y_val);

} else {
/** exponent x is smaller than y
* need to right shift x and set its exponent = exponent of y
*/
shift = (flt32_get_exp(y) - flt32_get_exp(x));
x_val = flt32_get_exp(y) + (flt32_get_val(x) >> shift);

sum = x_val + flt32_negate(y);
}
}

return sum;
}

旁白:这只是我在思考所有这些时所做的观察;理解 float 似乎很棒,甚至是必要的——但我遇到的几乎每篇文章,甚至是教科书,都说要尽可能避免它! :)

最佳答案

案例 2 的注意事项

sum = x + flt32_negate(y_val) 之后, 应该 sum < 0x800000 ,你需要规范化答案:左移直到不是这样,你去递减指数。注意 sum == 0首先并返回特殊形式的 0。一旦修复 flt32_get_val(),您将不会在递减偏差指数时检查下溢。 .

进一步的区别问题:必须执行减法(+ 情况 2),以便作为 shift 的一部分移出任何位由于 sum < 0x800000 被带回问题。如果仍有任何位移出,则必须评估和处理舍入。

考虑处理 + 和 - 通过通用例程并转向加/减量级。 + 案例 1、2、3、4 就像案例 1、4、3、2。 + case 1,4 是一样的,只是符号不同。 + 案例 2,3 是彼此的否定,一旦您首先发现哪个幅度更大。

首先考虑将 +0、-0 作为特殊情况处理。

您没有对 INF 和 NAN 做任何事情。建议保存以备后用,暂时放入 stub 。


案例 1 注意事项

如果sum > 0xFFFFFF ,您需要右筛选和递增指数,测试指数溢出和返回的 INF。

如果您右移,OP 需要决定舍入模式并可能增加答案,再次测试增量指数,测试指数溢出和返回的 INF。


制作后sum ,答案重构必须小心处理隐藏的MSBit。

OP 混淆了 | 的使用与 ^.

OP 还有很长的路要走,我估计 OP 已完成 add 案例的 10%。

关于c - 在c中添加正负浮点值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19018523/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com