我正在绞尽脑汁想弄清楚为什么这段代码没有得到正确的结果。我正在寻找浮点正负溢出/下溢水平的十六进制表示。该代码基于此网站和Wikipedia entry:
7f7fffff≈3.44028234×10 38 (最大单精度) - 来自维基百科条目,对应正溢出
以下是代码:
#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;
}
输出结果为:
当值大于:
时,会发生负溢出f3800000
时,会发生正溢出 值小于:7f800000
时发生否溢出 当值大于:1
时,会发生正下溢 当值大于:80000001
要获取浮点的十六进制表示,我使用的是here描述的方法:
为什么代码不起作用?我知道如果积极溢出= 7f7f ffff
,它会起作用。
答案 0 :(得分:3)
你表达最高可表示的正浮动是错误的。您关联的网页使用(2-pow(2, -23)) * pow(2, 127)
,您有2 - (pow(2, -23) * pow(2, 127))
。同样,对于最小的可表示负浮动。
然而,您的下溢表达式看起来是正确的,它们的十六进制输出也是如此。
请注意,posOverflow
和negOverflow
只是+FLT_MAX
和-FLT_MAX
。但请注意,您的posUnderflow
和negUnderflow
实际上小于而不是FLT_MIN
(因为它们是非正规的,FLT_MIN
是最小的正正常浮动)。
答案 1 :(得分:2)
随着数字变大,浮点失去精度。当你加2时,数量为2 127 的数量不会改变。
除此之外,我并没有真正关注你的代码。使用单词拼出数字使我很难阅读。
以下是获取机器浮点限制的标准方法:
#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';
}
输出:
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
输出取决于机器的字节顺序。由于little-endian顺序,这里的字节被反转。
注意,在这种情况下,“下溢”不是灾难性的零结果,而只是逐渐降低精度的非规范化。 (但这可能对性能造成灾难性影响。)您也可以检查生成numeric_limits< float >::denorm_min()
的{{1}}。
答案 2 :(得分:1)
你的代码假定整数与浮点数相同(所以除了你链接的页面上的一些帖子之外,btw。)你可能想要一些类似的东西:
for (size_t s = 0; s < sizeof(myVar); ++s) {
unsigned char *byte = reinterpret_cast<unsigned char*>(myVar)[s];
//sth byte is byte
}
即类似于该页面上的模板化代码。
您的编译器可能没有使用那些特定的IEEE 754类型。您需要查看其文档。
另外,请考虑使用std::numeric_limits<float>.min()
/ max()
或cfloat
FLT_
常量来确定其中一些值。