Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/161.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++_Floating Point_Rounding - Fatal编程技术网

C++ 浮点限制代码不能产生正确的结果

C++ 浮点限制代码不能产生正确的结果,c++,floating-point,rounding,C++,Floating Point,Rounding,我绞尽脑汁想弄明白为什么这段代码没有得到正确的结果。我正在寻找浮点正和负溢出/下溢级别的十六进制表示形式。该代码基于此站点和一个: 7f7f ffff≈ 3.4028234×1038(最大单精度)——来自维基百科条目,对应正溢出 代码如下: #include <iostream> #include <cstdio> #include <cstdlib> #include <cmath> using namespace std; int main

我绞尽脑汁想弄明白为什么这段代码没有得到正确的结果。我正在寻找浮点正和负溢出/下溢级别的十六进制表示形式。该代码基于此站点和一个:

7f7f ffff≈ 3.4028234×1038(最大单精度)——来自维基百科条目,对应正溢出

代码如下:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>

using namespace std;

int main(void) {

    float two = 2;
    float twentyThree = 23;
    float one27 = 127;
    float one49 = 149;


    float posOverflow, negOverflow, posUnderflow, negUnderflow;

    posOverflow = two - (pow(two, -twentyThree) * pow(two, one27));
    negOverflow = -(two - (pow(two, one27) * pow(two, one27)));


    negUnderflow = -pow(two, -one49);
    posUnderflow = pow(two, -one49);


    cout << "Positive overflow occurs when value greater than: " << hex << *(int*)&posOverflow << endl;


    cout << "Neg overflow occurs when value less than: " << hex << *(int*)&negOverflow << endl;


    cout << "Positive underflow occurs when value greater than: " << hex << *(int*)&posUnderflow << endl;


    cout << "Neg overflow occurs when value greater than: " << hex << *(int*)&negUnderflow << endl;

}
#包括
#包括
#包括
#包括
使用名称空间std;
内部主(空){
浮点数2=2;
浮动二十三=23;
浮点数27=127;
浮点数49=149;
浮动位置溢出、负溢出、正下溢、负下溢;
posOverflow=2-(pow(2,-23)*pow(2,one27));
negOverflow=-(二-(二,一27)*二,一27));
负下溢=-pow(2,-1 49);
posUnderflow=功率(2,-1 49);

cout您的代码假设整数的大小与浮点相同(顺便说一句,除了您链接的页面上的一些帖子外,其他所有帖子都是这样做的)。您可能需要以下内容:

for (size_t s = 0; s < sizeof(myVar); ++s) {
    unsigned char *byte = reinterpret_cast<unsigned char*>(myVar)[s];
    //sth byte is byte
}
for(size_t s=0;s
也就是说,类似于该页面上的模板化代码

您的编译器可能未使用这些特定的IEEE 754类型。您需要检查其文档


也可以考虑使用<代码>://>代码> > />代码>(或)>或>代码> cFoo> <代码> FLT<<代码>常量来确定其中的一些值。

< P>最高可表示的正浮点的表达式是错误的。链接的页使用<代码>(2-PoW(2,-23))*POW(2, 127)< /> >,并且您有<代码> 2。(2,-23)*pow(2,127))
。类似地,对于最小的可表示负浮动

但是,您的下溢表达式看起来是正确的,它们的十六进制输出也是正确的


请注意,
posUnderflow
negUnderflow
只是
+FLT_MAX
-FLT_MAX
。但是请注意,您的
posUnderflow
negUnderflow
实际上比
FLT_MIN
小(因为它们是非标准的,
FLT_MIN
是最小的正标准浮动).

当数字变大时,浮点会失去精度。2127量级的数字在添加2时不会改变

除此之外,我并没有真正理解你的代码。用单词拼写数字让我很难阅读

以下是获取机器浮点限制的标准方法:

#include <limits>
#include <iostream>
#include <iomanip>

std::ostream &show_float( std::ostream &s, float f ) {
    s << f << " = ";
    std::ostream s_hex( s.rdbuf() );
    s_hex << std::hex << std::setfill( '0' );
    for ( char const *c = reinterpret_cast< char const * >( & f );
          c != reinterpret_cast< char const * >( & f + 1 );
          ++ c ) {
        s_hex << std::setw( 2 ) << ( static_cast< unsigned int >( * c ) & 0xff );
    }
    return s;
}

int main() {
    std::cout << std::hex;
    std::cout << "Positive overflow occurs when value greater than: ";
    show_float( std::cout, std::numeric_limits< float >::max() ) << '\n';
    std::cout << "Neg overflow occurs when value less than: ";
    show_float( std::cout, - std::numeric_limits< float >::max() ) << '\n';
    std::cout << "Positive underflow occurs when value less than: ";
    show_float( std::cout, std::numeric_limits< float >::denormal_min() ) << '\n';
    std::cout << "Neg underflow occurs when value greater than: ";
    show_float( std::cout, - std::numeric_limits< float >::min() ) << '\n';
}
输出取决于机器的尾数。这里的字节由于尾数顺序很小而颠倒


请注意,在这种情况下,“下溢”不是灾难性的零结果,而是逐渐降低精度的非规范化(但可能对性能造成灾难性影响)。您还可以检查
数值限制::denorm_min()
生成
1.4013e-45=01000000

您可能应该使用
double
而不是
float
@LokiAstari您不能简单地将
double
替换为该代码,所有相关表达式都需要更改,因为它们在不同的值上下流动。此外,由于这段代码中的e似乎更好地理解了IEEE浮点运算,我认为
float
正是他应该使用的。
*(int*)&
假设
float
int
的大小相同(并且编译器会让严格的别名冲突消失)。您的代码假设了机器的终结性(或者,当您尝试使用字节时,它就会出现)。执行此操作的所有“正确”方法都取决于体系结构或编译器。
numeric_limits::min()
是最小的可表示规范化浮点,而不是最小的可表示浮点。因此,在这些情况下,您实际上找到了与链接文章不同的值。@JohnCalsbeek是的,在您发布时正在编辑:)已修复。
Positive overflow occurs when value greater than: 3.40282e+38 = ffff7f7f
Neg overflow occurs when value less than: -3.40282e+38 = ffff7fff
Positive underflow occurs when value less than: 1.17549e-38 = 00008000
Neg underflow occurs when value greater than: -1.17549e-38 = 00008080