Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/145.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 浮点数的二进制表示_C++_Double - Fatal编程技术网

C++ 浮点数的二进制表示

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)倍以上。这意味着ε将改变一个二进制数

为什么对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)倍以上。这意味着ε将改变一个二进制数字,该二进制数字是存储在该双精度表中最右边数字的三位数字


如果你想注意到一些变化,你必须加上大约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;
}