FP号码的指数字段不是我预期的,为什么?
FP number's exponent field is not what I expected, why?
我已经被这个问题难住好几天了。这个程序是我从一本叫《写好代码第一卷:理解机器》的书里选出来的。
这个项目是在c++中做浮点运算。我打算自己用c++实现其他的操作;本书在项目中使用HLA(高级汇编)进行乘法和除法等其他操作。
我想显示指数和其他字段值后,他们已经从FP数字提取;进行调试。然而,我有一个问题:当我在内存中查看这些值时,它们并不像我认为的那样。关键词:我的想法。我相信我理解IEEE FP格式;这本书相当简单,到目前为止我都能理解。
最大的问题是为什么指数变量似乎几乎不可预测;在这个例子中,给定的值是5。为什么呢?我猜应该是两个。2,因为小数点在隐含的小数点右边两位。
我已经将程序中产生的实际值注释到代码中,因此您不必运行程序来了解发生了什么(至少在重要部分)。在这一点上它是未完成的。整个项目还没有在我的计算机上创建。
下面是代码(引用自我从书中复制然后修改的文件):
#include<iostream>
typedef long unsigned real; //typedef our long unsigned ints in to the label "real" so we don't confuse it with other datatypes.
using namespace std; //Just so I don't have to type out std::cout any more!
#define asreal(x) (*((float *) &x)) //Cast the address of X as a float pointer as a pointer. So we don't let the compiler truncate our FP values when being converted.
inline int extractExponent(real from) {
return ((from >> 23) & 0xFF) - 127; //Shift right 23 bits; & with eight ones (0xFF == 1111_1111 ) and make bias with the value by subtracting all ones from it.
}
void fpadd ( real left, real right, real *dest) {
//Left operand field containers
long unsigned int Lexponent = 0;
long unsigned Lmantissa = 0;
int Lsign = 0;
//RIGHT operand field containers
long unsigned int Rexponent = 0;
long unsigned Rmantissa = 0;
int Rsign = 0;
//Resulting operand field containers
long int Dexponent = 0;
long unsigned Dmantissa = 0;
int Dsign = 0;
std::cout << "Size of datatype: long unsigned int is: " << sizeof(long unsigned int); //For debugging
//Properly initialize the above variable's:
//Left
Lexponent = extractExponent(left); //Zero. This value is NOT a flat zero when displayed because we subtract 127 from the exponent after extracting it! //Value is: 0xffffff81
Lmantissa = extractMantissa (left); //Zero. We don't do anything to this number except add a whole number one to it. //Value is: 0x00000000
Lsign = extractSign(left); //Simple.
//Right
**Rexponent = extractExponent(right); //Value is: 0x00000005 <-- why???**
Rmantissa = extractMantissa (right);
Rsign = extractSign(right);
}
int main (int argc, char *argv[]) {
real a, b, c;
asreal(a) = -0.0;
asreal(b) = 45.67;
fpadd(a,b, &c);
printf("Sum of A and B is: %f", c);
std::cin >> a;
return 0;
}
帮助将非常感激;我做这个项目有几天了,非常沮丧!
在本例中,的值为5。为什么呢?
浮点数45.67在内部表示为
2^5 * 1.0110110101011100001010001111010111000010100011110110
实际表示的是数字
45.6700000000000017053025658242404460906982421875
这是float
中最接近的45.67。
如果你感兴趣的是一个数字的指数,只需计算其以2为底的对数并向下舍入。因为45.67在32(2^5)和64(2^6)之间,所以指数是5。
计算机使用二进制表示所有的数字。因此,指数是以2为基数,而不是以10为基数。
相关文章:
- 为什么"do while"循环不断退出,即使条件计算结果为 false?
- 为什么在全局范围内使用"extern int a"似乎不行?
- 为什么在popback()操作之后,它仍然打印完整的矢量
- 为什么随机数生成器不在void函数中随机化数字,而在main函数中随机化
- 为什么两个不同的未命名名称空间可以共存于一个cpp文件中
- 为什么会发生堆损坏
- 为什么使用 "this" 指针调用派生成员函数?
- C++我的数学有什么问题,为什么我的代码不能正确循环
- 为什么比较运算符如此快速
- 为什么 Serial.println(<char[]>);返回随机字符?
- 为什么这个运算符<重载函数对 STL 算法不可见?
- 为什么不;名字在地图上是按顺序排列的吗
- 我的字符计数代码计算错误.为什么
- 为什么在没有显式默认构造函数的情况下,将另一个结构封装在联合中作为成员的结构不能编译
- 为什么我的C#代码在调用回C++COM直到Task时会暂停.等待/线程.加入
- 为什么在C++中使用私有复制构造函数与删除复制构造函数
- 为什么 NodeMCU 发送带有不需要的号码的数据?
- 为什么我没有为第 n 个斐波那契号码的实现获得正确的输出
- FP号码的指数字段不是我预期的,为什么?
- 返回垃圾号码,我不知道为什么