c - 添加到 FLT_MAX 以导致溢出的最小数字
问题描述
我需要找到数字,它是 2 的幂,当添加到 FLT_MAX 时会导致溢出。但是,当我 printf 非常大的幂,比如 2^300,inf 仍然没有出现。另外,我认为由于 FLT_MAX 是表示的最大浮点数,因此将其加 1 会立即导致溢出。
#include <stdio.h>
#include <float.h>
int main(){
float f = FLT_MAX;
printf("%f", f + pow(2,300));
}
任何帮助,将不胜感激。谢谢!
解决方案
答案是(FLT_MAX - nextafterf(FLT_MAX, 0))/2
,即正好是 0x1p+103 或大约 1.014120480e+31。
您用来确定答案的方法有一个错误:标准函数pow
返回 a double
,而C 的“通常的算术转换”(C11 6.3.1.8:1)意味着表达式f + pow(2,300)
被计算为 a double
。然后将其打印为 a double
,因为参数如何传递给可变参数函数。
这个 C 程序展示了如何float
获得FLT_MAX
通过float
加法相加得到float
无穷大的值:
#include <stdio.h>
#include <float.h>
#include <math.h>
int main(){
float f = FLT_MAX;
printf("FLT_MAX: %a\n", f);
float b = nextafterf(f, 0);
printf("number before FLT_MAX: %a\n", b);
float d = f - b;
printf("difference: %a\n", d);
printf("FLT_MAX + d: %a\n", f + d);
printf("FLT_MAX + d/2: %a\n", f + d/2);
printf("FLT_MAX + nextafterf(d/2,0): %a\n", f + nextafterf(d/2,0));
float answer = d/2;
printf("answer: %a %.9e\n", answer, answer);
}
它打印:
FLT_MAX: 0x1.fffffep+127
number before FLT_MAX: 0x1.fffffcp+127
difference: 0x1p+104
FLT_MAX + d: inf
FLT_MAX + d/2: inf
FLT_MAX + nextafterf(d/2,0): 0x1.fffffep+127
answer: 0x1p+103 1.014120480e+31
它表明,如果您将FLT_MAX
其与其较低邻居之间的差异(称为差异d
),如您所料,d
添加到FLT_MAX
productsinf
中。但这不是float
你可以添加到FLT_MAX
生产中的最小的inf
——还有更小的候选者。为了使结果达到 ,正好加上 的一半就足够d
了。另一方面,如果您添加的值小于该值,则结果将向下舍入。FLT_MAX
inf
FLT_MAX
推荐阅读
- go - Golang中的接口变量转换
- corda - Corda 是否可以在同一流程中发布和消费状态
- angular - formControlName 不保存选择中的所有值
- angular - 不能在 Angular 的 *ngFor 中使用子字符串
- image-processing - 验证图像是原始的还是施乐的
- c# - EPPlus - 添加新工作表时为什么索引超出范围
- javascript - 如何使用behavioursubject Angular 5在点击时更新对象值?
- scala - 在 Akka Http 中添加路由时出现 404 错误
- c - Are two C void pointers with the same data different memory objects?
- python - numpy C API 中的 import_array 如何工作?