我想知道如何在 C 中处理这些函数。我尝试解决它们但失败了
I want to know how to approach these functions in C. I have tried solving them but failed
#include <stdlib.h>
#include <stdio.h>
#include <float.h>
//-- Sign related constants --//
// PURPOSE: To be the mask to only keep the sign bit.
const int SIGN_MASK = 0x80000000;
// PURPOSE: To tell how many bits to shift the sign bit from the least
// signficant position to where the sign bit belongs.
const int SIGN_SHIFT = 31;
//-- Exponent related constants --//
// PURPOSE: To be the mask to only keep the exponent bit field.
const int EXPONENT_MASK = 0x7F800000;
// PURPOSE: To tell how many bits to shift the exponent bit field from the
// least signficant position to where the exponent bit field belongs.
const int EXPONENT_SHIFT = 23;
// PURPOSE: To tell the 'bias' of the exponent bit field:
// (powerOf2) = (exponentBitPattern) - EXPONENT_BIAS
const int EXPONENT_BIAS = 127;
// PURPOSE: To tell the exponent bit pattern for denormalized numbers
// (including 0.0).
const int EXPONENT_DENORMALIZED_BIT_PATTERN
= 0x00;
// PURPOSE: To tell the exponent bit pattern for 'infinity' and
// 'not-a-number'.
const int EXPONENT_INFINITE_BIT_PATTERN
= 0xFF;
// PURPOSE: To tell the power of 2 for 'infinity' and 'not-a-number'.
const int INFINITE_POWER_OF_2 = +128;
// PURPOSE: To tell the power of 2 for denormalized numbers (including 0.0):
const int DENORMALIZED_POWER_OF_2= -127;
//-- Mantissa related constants --//
// PURPOSE: To tell the mask to only keep the mantissa bit field.
const int MANTISSA_MASK = 0x007FFFFF;
// PURPOSE: To tell how many bits to shift the mantissa bit field from the
// least signficant position to where the mantissa bit field belongs.
const int MANTISSA_SHIFT = 0;
// PURPOSE: To tell position of the hidden bit in the mantissa bit field.
const int MANTISSA_HIDDEN_BIT = 0x00800000;
// PURPOSE: To tell the bits too high for the mantissa to occupy.
const int MANTISSA_TOO_BIG_FIELD = 0xFF000000;
//-- Functions of program: --//
// PURPOSE: To return the base-2 exponent of 'number'.
int base2Exp (float number
)
{
unsigned int u = *(unsigned int*)&number;
int field = (u & MANTISSA_MASK) | (EXPONENT_BIAS << EXPONENT_SHIFT); // CHANGE THAT 0!
return (field); // CHANGE THAT 0!
}
// PURPOSE: To return the mantissa field of 'number'. Turns on hidden bit
// if 'number' is not denormalized.
unsigned int mantissaField (float number
)
{
unsigned int u = *(unsigned int*)&number;
unsigned int field = (u & MANTISSA_MASK) | (EXPONENT_BIAS << EXPONENT_SHIFT); // CHANGE THAT 0!
// YOUR CODE HERE
return(field);
}
// PURPOSE: To return the float with exponent 'exponent' and mantissa-field
// 'mantissa'.
float buildFloat (int exponent,
unsigned int mantissa
)
{
unsigned int exponentPattern;
float number;
// YOUR CODE HERE to compute exponentPattern
// YOUR CODE HERE to turn off the hidden bit in mantissa
*((unsigned int*)&number) = 0; // CHANGE THAT 0!
// It should be an bitwise integer expression
// combining exponentPattern and mantissa
return(number);
}
// PURPOSE: To return '+1.0' plus 'number' for non-negative 'number'.
// Use integer operations only.
float addOne (float number
)
{
int exponent = base2Exp(number);
unsigned int numberMantissa = mantissaField(number);
unsigned int oneMantissa = MANTISSA_HIDDEN_BIT;
// YOUR CODE HERE to handle number so small should return +1.0
// YOUR CODE HERE to handle number so big should return number
// YOUR CODE HERE to handle exponent < 0
// YOUR CODE HERE to handle exponent > 0
// Add mantissas (done)
unsigned int mantissa= numberMantissa + oneMantissa;
// YOUR CODE HERE to handle when mantissa is too big
// Build the resulting float (done)
return(buildFloat(exponent,mantissa));
}
// PURPOSE: To run the add +1.0 program. Ignores parameters.
// Returns &EXIT_SUCCESS& to OS.
int main ()
{
float TEST_ARRAY[] = { +0.0,
+FLT_MIN,
+1e-10,
+0.0625,
+0.5,
+0.75
+1.0,
+2.0,
+3.14159,
+7.5,
+1e+10,
+FLT_MAX
};
const int TEST_ARRAY_LEN = sizeof(TEST_ARRAY) / sizeof(float);
int i;
int j;
int EXPONENT_ARRAY[]= {2,2,
DENORMALIZED_POWER_OF_2,
DENORMALIZED_POWER_OF_2};
int MANTISSA_ARRAY[]= {0x800000,0xC00000,0x400000,0x600000};
float FLOAT_ARRAY[] = {4.0,6.0,5.877471754e-39,8.816207631e-39};
for (i = 0; i < 4; i++)
{
float f = FLOAT_ARRAY[i];
float built = buildFloat(EXPONENT_ARRAY[i],MANTISSA_ARRAY[i]);
printf("%g == %g %s\n",f,built,( (f==built) ? "YAY!" : "Ruh-Roh!" ));
}
for (i = 0; i < TEST_ARRAY_LEN; i++)
{
float addend = TEST_ARRAY[i];
float hardware= 1.0 + addend;
float student = addOne(addend);
printf("1.0 + %11g = (hardware %11g) (you %11g) %s\n",
addend,hardware,student,
(hardware==student) ? "YAY!" : "Ruh-Roh!"
);
}
return(EXIT_SUCCESS);
}
这就是我的代码。我试过做前两个,但我不确定它们是否正确,因为它不会输出任何不同的东西。
我应该得到的输出是这样的:
4 == 4 YAY!
6 == 6 YAY!
5.87747e-39 == 5.87747e-39 YAY!
8.81621e-39 == 8.81621e-39 YAY!
1.0 + 0 = (hardware 1) (you 1) YAY!
1.0 + 1.17549e-38 = (hardware 1) (you 1) YAY!
1.0 + 1e-10 = (hardware 1) (you 1) YAY!
1.0 + 0.0625 = (hardware 1.0625) (you 1.0625) YAY!
1.0 + 0.5 = (hardware 1.5) (you 1.5) YAY!
1.0 + 1.75 = (hardware 2.75) (you 2.75) YAY!
1.0 + 2 = (hardware 3) (you 3) YAY!
1.0 + 3.14159 = (hardware 4.14159) (you 4.14159) YAY!
1.0 + 7.5 = (hardware 8.5) (you 8.5) YAY!
1.0 + 1e+10 = (hardware 1e+10) (you 1e+10) YAY!
1.0 + 3.40282e+38 = (hardware 3.40282e+38) (you 3.40282e+38) YAY!
然而,在我尝试之后,它仍然输出错误的输出。
它输出这个:
4 == 0 Ruh-Roh!
6 == 0 Ruh-Roh!
5.87747e-39 == 0 Ruh-Roh!
8.81621e-39 == 0 Ruh-Roh!
1.0 + 0 = (hardware 1) (you 0) Ruh-Roh!
1.0 + 1.17549e-38 = (hardware 1) (you 0) Ruh-Roh!
1.0 + 1e-10 = (hardware 1) (you 0) Ruh-Roh!
1.0 + 0.0625 = (hardware 1.0625) (you 0) Ruh-Roh!
1.0 + 0.5 = (hardware 1.5) (you 0) Ruh-Roh!
1.0 + 1.75 = (hardware 2.75) (you 0) Ruh-Roh!
1.0 + 2 = (hardware 3) (you 0) Ruh-Roh!
1.0 + 3.14159 = (hardware 4.14159) (you 0) Ruh-Roh!
1.0 + 7.5 = (hardware 8.5) (you 0) Ruh-Roh!
1.0 + 1e+10 = (hardware 1e+10) (you 0) Ruh-Roh!
1.0 + 3.40282e+38 = (hardware 3.40282e+38) (you 0) Ruh-Roh!
如果有人能指导我解决这个问题,我将不胜感激。刚开始学C,迷路了
谢谢
我快速浏览了代码和您需要完成的任务。几点建议:
base2Exp()
的正确实施将至少通过最后两个测试。
- 对于您的
field
变量,您从 (u & MANTISSA_MASK)
开始是正确的。之后您需要做一些其他事情(见下文)。
- 查看常量的注释,因为它们会给您一些提示。
- 例如,
EXPONENT_BIAS
的注释告诉您 (powerOf2) = (exponentBitPattern) - EXPONENT_BIAS
。这意味着 base2Exp()
需要减法。
- 前几个测试需要
buildFloat()
才能实现。
#include <stdlib.h>
#include <stdio.h>
#include <float.h>
//-- Sign related constants --//
// PURPOSE: To be the mask to only keep the sign bit.
const int SIGN_MASK = 0x80000000;
// PURPOSE: To tell how many bits to shift the sign bit from the least
// signficant position to where the sign bit belongs.
const int SIGN_SHIFT = 31;
//-- Exponent related constants --//
// PURPOSE: To be the mask to only keep the exponent bit field.
const int EXPONENT_MASK = 0x7F800000;
// PURPOSE: To tell how many bits to shift the exponent bit field from the
// least signficant position to where the exponent bit field belongs.
const int EXPONENT_SHIFT = 23;
// PURPOSE: To tell the 'bias' of the exponent bit field:
// (powerOf2) = (exponentBitPattern) - EXPONENT_BIAS
const int EXPONENT_BIAS = 127;
// PURPOSE: To tell the exponent bit pattern for denormalized numbers
// (including 0.0).
const int EXPONENT_DENORMALIZED_BIT_PATTERN
= 0x00;
// PURPOSE: To tell the exponent bit pattern for 'infinity' and
// 'not-a-number'.
const int EXPONENT_INFINITE_BIT_PATTERN
= 0xFF;
// PURPOSE: To tell the power of 2 for 'infinity' and 'not-a-number'.
const int INFINITE_POWER_OF_2 = +128;
// PURPOSE: To tell the power of 2 for denormalized numbers (including 0.0):
const int DENORMALIZED_POWER_OF_2= -127;
//-- Mantissa related constants --//
// PURPOSE: To tell the mask to only keep the mantissa bit field.
const int MANTISSA_MASK = 0x007FFFFF;
// PURPOSE: To tell how many bits to shift the mantissa bit field from the
// least signficant position to where the mantissa bit field belongs.
const int MANTISSA_SHIFT = 0;
// PURPOSE: To tell position of the hidden bit in the mantissa bit field.
const int MANTISSA_HIDDEN_BIT = 0x00800000;
// PURPOSE: To tell the bits too high for the mantissa to occupy.
const int MANTISSA_TOO_BIG_FIELD = 0xFF000000;
//-- Functions of program: --//
// PURPOSE: To return the base-2 exponent of 'number'.
int base2Exp (float number
)
{
unsigned int u = *(unsigned int*)&number;
int field = (u & MANTISSA_MASK) | (EXPONENT_BIAS << EXPONENT_SHIFT); // CHANGE THAT 0!
return (field); // CHANGE THAT 0!
}
// PURPOSE: To return the mantissa field of 'number'. Turns on hidden bit
// if 'number' is not denormalized.
unsigned int mantissaField (float number
)
{
unsigned int u = *(unsigned int*)&number;
unsigned int field = (u & MANTISSA_MASK) | (EXPONENT_BIAS << EXPONENT_SHIFT); // CHANGE THAT 0!
// YOUR CODE HERE
return(field);
}
// PURPOSE: To return the float with exponent 'exponent' and mantissa-field
// 'mantissa'.
float buildFloat (int exponent,
unsigned int mantissa
)
{
unsigned int exponentPattern;
float number;
// YOUR CODE HERE to compute exponentPattern
// YOUR CODE HERE to turn off the hidden bit in mantissa
*((unsigned int*)&number) = 0; // CHANGE THAT 0!
// It should be an bitwise integer expression
// combining exponentPattern and mantissa
return(number);
}
// PURPOSE: To return '+1.0' plus 'number' for non-negative 'number'.
// Use integer operations only.
float addOne (float number
)
{
int exponent = base2Exp(number);
unsigned int numberMantissa = mantissaField(number);
unsigned int oneMantissa = MANTISSA_HIDDEN_BIT;
// YOUR CODE HERE to handle number so small should return +1.0
// YOUR CODE HERE to handle number so big should return number
// YOUR CODE HERE to handle exponent < 0
// YOUR CODE HERE to handle exponent > 0
// Add mantissas (done)
unsigned int mantissa= numberMantissa + oneMantissa;
// YOUR CODE HERE to handle when mantissa is too big
// Build the resulting float (done)
return(buildFloat(exponent,mantissa));
}
// PURPOSE: To run the add +1.0 program. Ignores parameters.
// Returns &EXIT_SUCCESS& to OS.
int main ()
{
float TEST_ARRAY[] = { +0.0,
+FLT_MIN,
+1e-10,
+0.0625,
+0.5,
+0.75
+1.0,
+2.0,
+3.14159,
+7.5,
+1e+10,
+FLT_MAX
};
const int TEST_ARRAY_LEN = sizeof(TEST_ARRAY) / sizeof(float);
int i;
int j;
int EXPONENT_ARRAY[]= {2,2,
DENORMALIZED_POWER_OF_2,
DENORMALIZED_POWER_OF_2};
int MANTISSA_ARRAY[]= {0x800000,0xC00000,0x400000,0x600000};
float FLOAT_ARRAY[] = {4.0,6.0,5.877471754e-39,8.816207631e-39};
for (i = 0; i < 4; i++)
{
float f = FLOAT_ARRAY[i];
float built = buildFloat(EXPONENT_ARRAY[i],MANTISSA_ARRAY[i]);
printf("%g == %g %s\n",f,built,( (f==built) ? "YAY!" : "Ruh-Roh!" ));
}
for (i = 0; i < TEST_ARRAY_LEN; i++)
{
float addend = TEST_ARRAY[i];
float hardware= 1.0 + addend;
float student = addOne(addend);
printf("1.0 + %11g = (hardware %11g) (you %11g) %s\n",
addend,hardware,student,
(hardware==student) ? "YAY!" : "Ruh-Roh!"
);
}
return(EXIT_SUCCESS);
}
这就是我的代码。我试过做前两个,但我不确定它们是否正确,因为它不会输出任何不同的东西。 我应该得到的输出是这样的:
4 == 4 YAY!
6 == 6 YAY!
5.87747e-39 == 5.87747e-39 YAY!
8.81621e-39 == 8.81621e-39 YAY!
1.0 + 0 = (hardware 1) (you 1) YAY!
1.0 + 1.17549e-38 = (hardware 1) (you 1) YAY!
1.0 + 1e-10 = (hardware 1) (you 1) YAY!
1.0 + 0.0625 = (hardware 1.0625) (you 1.0625) YAY!
1.0 + 0.5 = (hardware 1.5) (you 1.5) YAY!
1.0 + 1.75 = (hardware 2.75) (you 2.75) YAY!
1.0 + 2 = (hardware 3) (you 3) YAY!
1.0 + 3.14159 = (hardware 4.14159) (you 4.14159) YAY!
1.0 + 7.5 = (hardware 8.5) (you 8.5) YAY!
1.0 + 1e+10 = (hardware 1e+10) (you 1e+10) YAY!
1.0 + 3.40282e+38 = (hardware 3.40282e+38) (you 3.40282e+38) YAY!
然而,在我尝试之后,它仍然输出错误的输出。
它输出这个:
4 == 0 Ruh-Roh!
6 == 0 Ruh-Roh!
5.87747e-39 == 0 Ruh-Roh!
8.81621e-39 == 0 Ruh-Roh!
1.0 + 0 = (hardware 1) (you 0) Ruh-Roh!
1.0 + 1.17549e-38 = (hardware 1) (you 0) Ruh-Roh!
1.0 + 1e-10 = (hardware 1) (you 0) Ruh-Roh!
1.0 + 0.0625 = (hardware 1.0625) (you 0) Ruh-Roh!
1.0 + 0.5 = (hardware 1.5) (you 0) Ruh-Roh!
1.0 + 1.75 = (hardware 2.75) (you 0) Ruh-Roh!
1.0 + 2 = (hardware 3) (you 0) Ruh-Roh!
1.0 + 3.14159 = (hardware 4.14159) (you 0) Ruh-Roh!
1.0 + 7.5 = (hardware 8.5) (you 0) Ruh-Roh!
1.0 + 1e+10 = (hardware 1e+10) (you 0) Ruh-Roh!
1.0 + 3.40282e+38 = (hardware 3.40282e+38) (you 0) Ruh-Roh!
如果有人能指导我解决这个问题,我将不胜感激。刚开始学C,迷路了
谢谢
我快速浏览了代码和您需要完成的任务。几点建议:
base2Exp()
的正确实施将至少通过最后两个测试。- 对于您的
field
变量,您从(u & MANTISSA_MASK)
开始是正确的。之后您需要做一些其他事情(见下文)。
- 对于您的
- 查看常量的注释,因为它们会给您一些提示。
- 例如,
EXPONENT_BIAS
的注释告诉您(powerOf2) = (exponentBitPattern) - EXPONENT_BIAS
。这意味着base2Exp()
需要减法。
- 例如,
- 前几个测试需要
buildFloat()
才能实现。