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