我想写一个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;
}