mr-element 2023-11-13 11:47 采纳率: 60%
浏览 15
已结题

c语言的 浮点数计算程序纠错

我想写一个c语言的 浮点数计算程序,目前是半精度(16位)计算出了问题,单精度(32位)计算正常。目前程序输入
1.0
0.0
16
16
输出的结果是0.00000。
如果是输入1.0 0.0 32 32则输出结果为1.00000这个结果是正确的。请问如何修改这个程序

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>

// 把浮点数转换为二进制表示
char * valueToMachine(float num, int length){
    unsigned int n = *((unsigned int*)&num);
    char * binary = (char*)malloc(length + 1);
    if(binary == NULL){
        printf("Memory allocation failed\n");
        exit(1);
    }
    binary[length] = '\0';
    if(length == 32){
        for(int i = 31; i >= 0; i--){
            binary[i] = (n & 1) ? '1' : '0';
            n >>= 1;
        }
    }else if(length == 16){
        // handle the sign bit, exponent bits and fraction bits separately
        binary[0] = (n >> 15) ? '1' : '0'; // sign bit
        int exponent = (n >> 10) & 0x1F; // exponent bits
        int fraction = n & 0x3FF; // fraction bits
        for(int i = 1; i <= 5; i++){ 
            binary[i] = ((exponent >> (5 - i)) & 1) ? '1' : '0';
        }
        for(int i = 6; i <= 15; i++){ 
            binary[i] = ((fraction >> (15 - i)) & 1) ? '1' : '0';
        }
    }
    return binary;
}

// 把二进制表示转换回浮点数
float machineToValue(char * binary, int length){
    unsigned int n = 0;
    if(length == 32){
        for(int i = 0; i < length; i++){
            n = (n << 1) + (binary[i] == '1' ? 1 : 0);
        }
    } else if(length == 16){
        unsigned int sign = binary[0] == '1' ? 0x8000 : 0; // sign bit
        unsigned int exponent = 0;
        for(int i = 1; i <= 5; i++){ 
            exponent = (exponent << 1) + (binary[i] == '1' ? 1 : 0);
        }
        unsigned int fraction = 0;
        for(int i = 6; i <= 15; i++){ 
            fraction = (fraction << 1) + (binary[i] == '1' ? 1 : 0);
        }
        // Convert back to IEEE 754 single-precision format
        if(exponent == 0 && fraction == 0){
            return (sign == 0) ? 0.0 : -0.0; // Handle the special case of +0 and -0
        } else if(exponent == 0x1F){ //处理特殊值
            return fraction == 0 ? ((sign == 0) ? INFINITY : -INFINITY) : NAN;
        } else{
            n = sign << 15 | ((exponent - 15 + 127) << 10) | fraction; // Add bias to the exponent
        }
    }
    float num;
    memcpy(&num, &n, sizeof(num));
    return num;
}


// 计算两个二进制表示的浮点数的和
char * addfloat(char * float1, char * float2, int length){
    float num1 = machineToValue(float1, length);
    float num2 = machineToValue(float2, length);
    float sum = num1 + num2;
    return valueToMachine(sum, 32); // the result is always in single-precision floating-point format
}

// 计算两个浮点数的和
float computing(float float1, float float2, int n1, int n2){
    char * binary1 = valueToMachine(float1, n1);
    char * binary2 = valueToMachine(float2, n2);
    char * binary_sum = addfloat(binary1, binary2, n1 > n2 ? n1 : n2);
    float sum = machineToValue(binary_sum, 32);
    free(binary1);
    free(binary2);
    free(binary_sum);
    return sum;
}

int main(){
    float float1, float2;
    int n1, n2;
    int result = scanf("%f%f%d%d", &float1, &float2, &n1, &n2);
    if(result != 4 || (n1 != 16 && n1 != 32) || (n2 != 16 && n2 != 32)){
        printf("Invalid input\n");
        return 1;
    }
    float sum = computing(float1, float2, n1, n2);
    printf("%f\n", sum);
    return 0;
}


  • 写回答

10条回答 默认 最新

  • 专家-赤兔[在线] 优质创作者: 编程框架技术领域 2023-11-13 11:47
    关注

    引自强大而免费的微信小程序:皆我百晓生

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <math.h>
     
    // 把浮点数转换为二进制表示
    char * valueToMachine(float num, int length){
        unsigned int n = *((unsigned int*)&num);
        char * binary = (char*)malloc(length + 1);
        if(binary == NULL){
            printf("Memory allocation failed\n");
            exit(1);
        }
        binary[length] = '\0';
        if(length == 32){
            for(int i = 31; i >= 0; i--){
                binary[i] = (n & 1) ? '1' : '0';
                n >>= 1;
            }
        }else if(length == 16){
            // handle the sign bit, exponent bits and fraction bits separately
            binary[0] = (n >> 31) ? '1' : '0'; // sign bit
            int exponent = ((n >> 23) & 0xFF) - 127 + 15; // exponent bits
            if (exponent < 0) exponent = 0;
            if (exponent > 0x1F) exponent = 0x1F;
            int fraction = (n >> 13) & 0x3FF; // fraction bits
            for(int i = 1; i <= 5; i++){ 
                binary[i] = ((exponent >> (5 - i)) & 1) ? '1' : '0';
            }
            for(int i = 6; i <= 15; i++){ 
                binary[i] = ((fraction >> (15 - i)) & 1) ? '1' : '0';
            }
        }
        return binary;
    }
     
    // 把二进制表示转换回浮点数
    float machineToValue(char * binary, int length){
        unsigned int n = 0;
        if(length == 32){
            for(int i = 0; i < length; i++){
                n = (n << 1) + (binary[i] == '1' ? 1 : 0);
            }
        } else if(length == 16){
            unsigned int sign = binary[0] == '1' ? 0x80000000 : 0; // sign bit
            unsigned int exponent = 0;
            for(int i = 1; i <= 5; i++){ 
                exponent = (exponent << 1) + (binary[i] == '1' ? 1 : 0);
            }
            unsigned int fraction = 0;
            for(int i = 6; i <= 15; i++){ 
                fraction = (fraction << 1) + (binary[i] == '1' ? 1 : 0);
            }
            // Convert back to IEEE 754 single-precision format
            n = sign | ((exponent == 0 ? 0 : exponent - 15 + 127) << 23) | (fraction << 13);
        }
        float num;
        memcpy(&num, &n, sizeof(num));
        return num;
    }
     
    // 计算两个二进制表示的浮点数的和
    char * addfloat(char * float1, char * float2, int length){
        float num1 = machineToValue(float1, length);
        float num2 = machineToValue(float2, length);
        float sum = num1 + num2;
        return valueToMachine(sum, 32); // the result is always in single-precision floating-point format
    }
     
    // 计算两个浮点数的和
    float computing(float float1, float float2, int n1, int n2){
        char * binary1 = valueToMachine(float1, n1);
        char * binary2 = valueToMachine(float2, n2);
        char * binary_sum = addfloat(binary1, binary2, n1 > n2 ? n1 : n2);
        float sum = machineToValue(binary_sum, 32);
        free(binary1);
        free(binary2);
        free(binary_sum);
        return sum;
    }
     
    int main(){
        float float1, float2;
        int n1, n2;
        int result = scanf("%f%f%d%d", &float1, &float2, &n1, &n2);
        if(result != 4 || (n1 != 16 && n1 != 32) || (n2 != 16 && n2 != 32)){
            printf("Invalid input\n");
            return 1;
        }
        float sum = computing(float1, float2, n1, n2);
        printf("%f\n", sum);
        return 0;
    }
     
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论 编辑记录
查看更多回答(9条)

报告相同问题?

问题事件

  • 系统已结题 11月22日
  • 已采纳回答 11月14日
  • 创建了问题 11月13日