C++ 浮点数的二进制表示
为什么对toBinary函数的这两个调用计算相同的输出(至少在VS2010下)C++ 浮点数的二进制表示,c++,double,C++,Double,为什么对toBinary函数的这两个调用计算相同的输出(至少在VS2010下) #包括 #包括 #包括 使用名称空间std; 模板位集toBinary(const T num) { 位集mybits; const char*const p=reinterpret_cast(&num); 对于(int i=sizeof(T)*字符位1;i>=0;--i) mybits.set(i,(*(p)&(1)表示ε相对于1;这里,相反,将其相加为8.9,比1大8(2^3)倍以上。这意味着ε将改变一个二进制数
#包括
#包括
#包括
使用名称空间std;
模板位集toBinary(const T num)
{
位集mybits;
const char*const p=reinterpret_cast(&num);
对于(int i=sizeof(T)*字符位1;i>=0;--i)
mybits.set(i,(*(p)&(1)表示ε相对于1;这里,相反,将其相加为8.9,比1大8(2^3)倍以上。这意味着ε将改变一个二进制数字,该二进制数字是存储在该双精度表中最右边数字的三位数字
如果你想注意到一些变化,你必须加上大约8.9*epsilon。这个epsilon是相对于1的;这里,你把它加起来是8.9,它比1大8倍多。这意味着epsilon会改变一个二进制数字,它是存储在这个双精度表中最右边的三位数字
如果你想注意到一些变化,你必须在大约8.9*epsilon处添加。你有两个问题。第一个问题是你的toBinary
函数没有做你想要的事情——它应该是这样读的(假设有一点endian CPU):
模板位集为二进制(const T num)
{
位集mybits;
const char*const p=reinterpret_cast(&num);
对于(int i=sizeof(T)-1;i>=0;i--)
对于(int j=CHAR_BIT-1;j>=0;j--)
mybits.set(i*CHAR\u BIT+j,p[i]&(1您有两个问题。第一个问题是您的toBinary
函数没有实现您想要的功能——它应该是这样读的(假设有一点endian CPU):
模板位集为二进制(const T num)
{
位集mybits;
const char*const p=reinterpret_cast(&num);
对于(int i=sizeof(T)-1;i>=0;i--)
对于(int j=CHAR_BIT-1;j>=0;j--)
mybits.set(i*CHAR\u位+j,p[i]&(1)我应该添加哪个值以获得最小的增量,因为如果我添加8.8,我也会得到一个变化?没有一个值可以满足您的要求,但是有一个库函数-请参见我的答案。嗯,我也测试了它并得到了结果,我认为这取决于数字的确切内部表示形式。一个好的经验法则是这个number*epsilon
得到一个值,添加到number
,肯定会改变它,而在它下面你没有保证。我应该添加哪个值来获得最小的增量,因为如果我添加8.8,我也会得到一个改变?没有一个值可以满足你的要求,但是有一个库函数-看到我的答案了。嗯,我也测试了它,得到了这个结果,我认为它取决于数字的精确内部表示。一个好的经验法则是,number*epsilon
得到一个值,这个值加上number
,肯定会改变它,而在它下面你没有保证。我不明白ma函数为什么会出错根据我(*(p)和(1)不,不会。*p
具有类型char
,因此它检索双精度的第一个或最后一个字符位(取决于尾数),并且只读取这些位。因此,大多数循环不是读取double
的位i
,而是读取位7的符号扩展副本。要查看double
的第二个和后续字节,必须先偏移p
,然后再取消引用它,这就是我修改过的循环所做的。我不明白为什么会这样(1因为i
是字节索引。每个循环迭代都需要访问原始值内i*CHAR\u bit+j
处的位。如果使用1,对我来说不自然的是,对于两个不同的字节索引(例如i=0和i=8),我们有相同的掩码(j=0)…所以掩码与i=0的正确位置不匹配,至少在我看来是这样的…我不明白ma函数为什么会出错。根据我(*(p)和(1不,不会。*p
具有类型char
,因此它检索双字符的第一个或最后一个char\u位
位(取决于尾数),并且只读取这些位。因此,大多数循环不是读取double
的位i
,而是读取位7的符号扩展副本。要查看double
的第二个和后续字节,必须先偏移p
,然后再取消引用它,这就是我修改过的循环所做的。我不明白为什么会这样(1因为i
是字节索引。每个循环迭代都需要访问原始值内i*CHAR\u bit+j
处的位。如果使用1,对我来说不自然的是,对于两个不同的字节索引(例如i=0和i=8),我们有相同的掩码(j=0)…所以面具与i=0的正确位置不匹配,至少在我看来。。。
#include <iostream>
#include <bitset>
#include <limits>
using namespace std;
template<class T> bitset<sizeof(T)*CHAR_BIT> toBinary(const T num)
{
bitset<sizeof(T)*CHAR_BIT> mybits;
const char * const p = reinterpret_cast<const char*>(&num);
for (int i = sizeof(T)*CHAR_BIT-1 ; i >= 0 ; --i)
mybits.set(i, (*(p)&(1<<i) ));
return mybits;
}
int main()
{
cout << toBinary(8.9).to_string() << "\n";
cout << toBinary( 8.9 + std::numeric_limits<double>::epsilon() ).to_string() << "\n";
cin.get();
}
template<class T> bitset<sizeof(T)*CHAR_BIT> toBinary(const T num)
{
bitset<sizeof(T)*CHAR_BIT> mybits;
const char * const p = reinterpret_cast<const char*>(&num);
for (int i = sizeof(T)-1; i >= 0; i--)
for (int j = CHAR_BIT-1; j >= 0; j--)
mybits.set(i*CHAR_BIT + j, p[i] & (1 << j));
return mybits;
}