Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/56.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 如何添加两个符号相反的浮点数?_C_Algorithm_Floating Point - Fatal编程技术网

C 如何添加两个符号相反的浮点数?

C 如何添加两个符号相反的浮点数?,c,algorithm,floating-point,C,Algorithm,Floating Point,为了好玩,为了弄清楚更多关于浮点数是如何工作的,我正在尝试制作一个函数,它接受两个单精度浮点数,并将它们相加 到目前为止,我所做的工作对于相同的符号数字是完美的,但是当数字有相反的符号时,它就会崩溃。我看了很多问题和网站(,,,),但是那些提出减法的网站大多描述它有点像“基本相同,但减法相反”,我没有发现这非常有用。UAF说 负尾数首先转换为2的补码,然后执行加法。执行加法后,结果将转换回符号幅值形式 但我似乎不知道该怎么做。我发现并解释了什么是有符号震级,以及如何在它和2的补码之间转换,所以我

为了好玩,为了弄清楚更多关于浮点数是如何工作的,我正在尝试制作一个函数,它接受两个单精度浮点数,并将它们相加

到目前为止,我所做的工作对于相同的符号数字是完美的,但是当数字有相反的符号时,它就会崩溃。我看了很多问题和网站(,,,),但是那些提出减法的网站大多描述它有点像“基本相同,但减法相反”,我没有发现这非常有用。UAF说

负尾数首先转换为2的补码,然后执行加法。执行加法后,结果将转换回符号幅值形式

但我似乎不知道该怎么做。我发现并解释了什么是有符号震级,以及如何在它和2的补码之间转换,所以我试着这样转换:

manz=manx+((多个0x01000000)^0x007FFFFF)+1);
就像这样:

manz=manx+((多个0x01000000)^0x007FFFFF)+1);
manz=((manz-1)^0x007FFFFF)和0xFEFFFFFF);
但这两种方法都不奏效

尝试其他来源描述的减法,我尝试用各种方式否定负数的尾数,如下所示:

manz=manx-many;
manz=manx+(多个-(1
如何添加两个符号相反的浮点数

大多数情况下你不会

对于不能依赖“溢出时的两个补码换行”(例如浮点、大数字库等)的数字类型的所有操作,您总是会得到如下结果:

add_signed(v1, v2) {
    if( v1 < 0) {
        if( v2 < 0) {
            // Both negative
            return -add_unsigned(-v1, -v2);
        } else {
            // Different sign, v1 is negative
            return subtract_unsigned(v2, -v1);
        }
    } else {
        if( v2 < 0) {
            // Different sign, v2 is negative
            return subtract_unsigned(v1, -v2);
        } else {
            // Both positive
            return add_unsigned(v1, v2);
        }
    }
 }

subtract_signed(v1, v2) {
    return add_signed(v1, -v2);
}

add_unsigned(v1, v2) {
    // Here we know that v1 and v2 will never be negative, and
    //   we know that the result will never be negative
    ...
}

subtract_unsigned(v1, v2) {
    if(v1 < v2) {
        return -subtract_unsigned(v2, v1);
    }
    // Here we know that v1 and v2 will never be negative, and
    //   we know that the result will never be negative
    ...
}
添加签名(v1、v2){ 如果(v1<0){ 如果(v2<0){ //都是否定的 return-add_unsigned(-v1,-v2); }否则{ //不同的符号,v1为负 返回无符号的减法_(v2,-v1); } }否则{ 如果(v2<0){ //不同的符号,v2是负数 返回无符号的减法_(v1,-v2); }否则{ //都是正面的 返回未签名的add_(v1,v2); } } } 减去符号(v1,v2){ 返回添加签名(v1,-v2); } 添加未签名(v1、v2){ //这里我们知道v1和v2永远不会是负数 //我们知道结果永远不会是负面的 ... } 减去无符号(v1,v2){ 如果(v1
换句话说,所有的实际加法和实际减法都是用无符号(“从不负”)数字进行的

仅添加32位浮点模拟的更完整示例(在C中,未经测试且可能有缺陷,可能适用于非规范化,可能不适用于非规范化,不支持“NaN/s”或无穷大,不支持溢出或下溢,不支持“左移尾数以减少舍入前的精度损失”,并且不支持不同的舍入模式“向零转”):

#定义符号标志0x80000000U
#定义指数屏蔽0x7F800000U
#定义尾数掩码0x007FFFFFU
#定义隐含_位0x00800000U
#定义溢出位0x01000000U
#定义一个指数0x00800000U
uint32\u t添加签名(uint32\u t v1,uint32\u t v2){
如果((v1和签名标志)!=0){
如果((v2和标志)!=0){
//都是否定的
返回SIGN_FLAG | add_unsigned(v1&~SIGN_FLAG,v2&~SIGN_FLAG);
}否则{
//不同的符号,v1为负
返回无符号减法(v2、v1和符号);
}
}否则{
如果((v2和标志)!=0){
//不同的符号,v2是负数
返回无符号减法(v1、v2和符号标志);
}否则{
//都是正面的
返回未签名的add_(v1,v2);
}
}
}
uint32带符号减法(uint32带符号v1,uint32带符号v2){
返回添加签名(v1,v2^签名标志);
}
uint32\u t添加未签名(uint32\u t v1,uint32\u t v2){
//这里我们知道v1和v2永远不会是负数
//我们知道结果永远不会是负面的
if(v1>=1;
exp2+=指数μ1;
}
uint32_t mr=m1+m2;
如果((mr和溢出位)!=0){
mr>>1;
expr+=指数1;
}
返回表达式(mr&~u位);
}
uint32减去无符号(uint32 v1,uint32 v2){
如果(v1==v2){
返回0;
}
如果(v1>=1;
exp2+=指数μ1;
}
uint32_t mr=m1-m2;
while((mr和隐含_位)==0){
先生
如何添加两个符号相反的浮点数

大多数情况下你不会

对于不能依赖“溢出时的两个补码换行”(例如浮点、大数字库等)的数字类型的所有操作,您总是会得到如下结果:

add_signed(v1, v2) {
    if( v1 < 0) {
        if( v2 < 0) {
            // Both negative
            return -add_unsigned(-v1, -v2);
        } else {
            // Different sign, v1 is negative
            return subtract_unsigned(v2, -v1);
        }
    } else {
        if( v2 < 0) {
            // Different sign, v2 is negative
            return subtract_unsigned(v1, -v2);
        } else {
            // Both positive
            return add_unsigned(v1, v2);
        }
    }
 }

subtract_signed(v1, v2) {
    return add_signed(v1, -v2);
}

add_unsigned(v1, v2) {
    // Here we know that v1 and v2 will never be negative, and
    //   we know that the result will never be negative
    ...
}

subtract_unsigned(v1, v2) {
    if(v1 < v2) {
        return -subtract_unsigned(v2, v1);
    }
    // Here we know that v1 and v2 will never be negative, and
    //   we know that the result will never be negative
    ...
}
添加签名(v1、v2){ 如果(v1<0){ 如果(v2<0){ //都是负片