- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我知道,另一个关于浮点运算的主题!
我一直在努力解决这个问题,但似乎无法想出为什么添加负浮点值对我不起作用。
如果它们都是正值,则一切都按预期工作(返回的数字并没有超出预期,因为这毕竟是 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/
我不敢相信这实际上是在问我一个问题。但是我的数据库中有一些十进制值,即 0.9999999,使用: number_format($result['debit'], 2); number_format(
我正在尝试创建一个带有总和为 1 的随机变量的 numpy 数组,但我也想包含负值。 我正在尝试: size =(50,1) w = np.array(np.random.random(size))
我正在尝试构建一个接受可变数量参数的函数。 该函数接受 n 个输入并计算所有可能的加法和减法的和,例如如果参数是 1,2,3 1 + 2 + 3 1 - 2 - 3 1 + 2 - 3 1 - 2 +
我是一名优秀的程序员,十分优秀!