当没有浮点数据类型时,为啥这段代码会出现浮点异常?
Posted
技术标签:
【中文标题】当没有浮点数据类型时,为啥这段代码会出现浮点异常?【英文标题】:Why does this code get floating point exception when there is no float data-type?当没有浮点数据类型时,为什么这段代码会出现浮点异常? 【发布时间】:2018-07-11 22:14:04 【问题描述】:我没有除以零,并且我的代码中没有浮点数据类型,我仍然得到浮点异常。
#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
int main()
unsigned long long int t,n;
cin>>t;
while(t--)
cin>>n;
unsigned long long int deno = pow(10,n-1),count=2,sum = 0,f1=1,f2=1;
while(1)
sum = f1+f2;
f1 = f2;
f2 = sum;
count++;
if((int)(sum/deno)>0)
cout<<count<<endl;
break;
return 0;
之前的所有问题都有类似的除以零的问题,但变量 deno 永远不能像n>=2
那样为零。
我之前的研究:
-
“Floating point exception” in code that contains no floats
Floating Point Exception C++ Why and what is it?
问题说明:https://www.hackerrank.com/contests/projecteuler/challenges/euler025/problem
它通过了 2 个测试用例,失败了 2 个。都是隐藏的测试用例。 Result image
通过输入 1 50 我们可以重现错误。详情:
GDB trace: Reading symbols from solution...done. [New LWP 15127] Core
was generated by `solution'. Program terminated with signal SIGFPE,
Arithmetic exception.
#0 main () at solution.cc:23
23 if((int)(sum/deno)>0)
#0 main () at solution.cc:23
【问题讨论】:
浮点执行是当您尝试除以 0 或取模时。它不是浮点独有的 重现问题需要多长时间?当我运行您的代码时,它会一直运行。 使用你的调试器。观察deno
的值,看看它是否为零。
如果您不知道导致问题的输入,@Yılmazedis 调试不会轻易提供帮助。
您是否意识到unsigned long long
只能上升大约 19 位,而问题需要 5000?即使是long double
也只能达到 308 位(当然会出现浮点错误)。您将需要一种新方法。
【参考方案1】:
整数除法会产生异常,在某些平台(例如 Linux)上报告为“浮点异常”是完全正常的。你可以很容易地从整数除以零得到它,或者,另一个例子,通过触发溢出,如
int i = INT_MIN;
int b = -1;
i = i / b;
http://coliru.stacked-crooked.com/a/07c5fdf47278b696
在某些情况下,此异常可能会根据优化级别出现或消失。该异常通常仅在编译器决定生成实际除法指令(而不是优化除法)时触发。
在您的情况下,使用了无符号整数除法,因此除以零似乎是唯一可能的罪魁祸首。我猜这个
unsigned long long int deno = pow(10,n-1);
恰好在deno
中产生零。 pow
是一个产生浮点结果的浮点函数。如果原始值太大(n
等于 50
就是这种情况),从浮点类型转换为整数类型会导致未定义的行为。请注意,即使目标整数类型是无符号的也是如此。
【讨论】:
谢谢,但是我应该如何更改我的代码来解决这个问题? 感谢您深入研究问题并帮助我解决问题 是的,刚刚检查了1 50
deno
是0
。然而,在 Visual Studio 上是 9223372036854775808
。这确实是UB。
编写自己的 pow() 函数。 std::pow
总是转换整数并返回浮点结果。仅在标准库中没有整数的等价物。网络上有许多 int 等价物。
n>=19 的逻辑在各种平台上都是错误的。它只是溢出了 long long 的 64 位边界。以上是关于当没有浮点数据类型时,为啥这段代码会出现浮点异常?的主要内容,如果未能解决你的问题,请参考以下文章
为啥浮点数据类型在没有类型转换 4.7 的情况下在此代码中不起作用? [复制]