C 浮点数据类型不确定性
我正在对我开发的数学软件进行数值分析。我想确定我的结果的不确定性。作为C 浮点数据类型不确定性,c,floating-point,precision,epsilon,C,Floating Point,Precision,Epsilon,我正在对我开发的数学软件进行数值分析。我想确定我的结果的不确定性。作为f()我的方法和x一个输入值,我想将结果的y标识为f(x)+/-y。我的f()方法在float变量之间有多个操作。为了研究f()中发生的误差传播,我必须应用不确定度公式的统计传播,并且为了这样做,我必须知道float变量的不确定度 我确实了解IEEE 754标准中规定的float变量的体系结构,以及后者固有的将十进制值转换为float的舍入误差 从我对文献的理解来看,FLT\u EPSILON宏 定义我的y值,但此快速测试证明
f()
我的方法和x
一个输入值,我想将结果的y
标识为f(x)+/-y
。我的f()
方法在float
变量之间有多个操作。为了研究f()
中发生的误差传播,我必须应用不确定度公式的统计传播,并且为了这样做,我必须知道float
变量的不确定度
我确实了解IEEE 754标准中规定的float
变量的体系结构,以及后者固有的将十进制值转换为float
的舍入误差
从我对文献的理解来看,FLT\u EPSILON
宏
定义我的y
值,但此快速测试证明它是错误的:
float f1 = 1.234567f;
float f2 = 1.234567f + 1.192092896e-7f;
float f3 = 1.234567f + 1.192092895e-7f;
printf("Inicial:\t%f\n", f1);
printf("Inicial:\t%f\n", f2);
printf("Inicial:\t%f\n\n", f3);
输出:
Inicial: 1.234567
Inicial: 1.234567
Inicial: 1.234567
Inicial: 1.2345670461654663
Inicial: 1.2345671653747559
Inicial: 1.2345671653747559
预期输出的时间应为:
Inicial: 1.234567
Inicial: 1.234568 <---
Inicial: 1.234567
inical:1.234567
具体数字:1.234568
输出:
Inicial: 1.23456704616546630000
Inicial: 1.23456716537475590000
Inicial: 1.23456716537475590000
不,您的期望是错误的
在第一个printf
调用中,您正在打印变量f1,但没有任何效果,它只是1.234567f
输出:
Inicial: 1.23456704616546630000
Inicial: 1.23456716537475590000
Inicial: 1.23456716537475590000
不,您的期望是错误的
在第一个printf
调用中,您打印的变量f1没有任何效果,它只是1.234567f
,浮点是一个32
位IEEE 754单精度浮点数:1位表示符号,8位表示指数,23位表示值,也就是说,浮点具有7
精度的小数位数
增加printf
打印位数以查看更多内容,但7位数之后仅显示噪音:
#include <stdio.h>
int main(void) {
float f1 = 1.234567f;
float f2 = 1.234567f + 1.192092897e-7f;
float f3 = 1.234567f + 1.192092896e-7f;
printf("Inicial:\t%.16f\n", f1);
printf("Inicial:\t%.16f\n", f2);
printf("Inicial:\t%.16f\n\n", f3);
return 0;
}
浮点是IEEE 754单精度浮点数的32位:1位表示符号,8位表示指数,23位表示值,即浮点具有7位精度的十进制数字
增加printf
打印位数以查看更多内容,但7位数之后仅显示噪音:
#include <stdio.h>
int main(void) {
float f1 = 1.234567f;
float f2 = 1.234567f + 1.192092897e-7f;
float f3 = 1.234567f + 1.192092896e-7f;
printf("Inicial:\t%.16f\n", f1);
printf("Inicial:\t%.16f\n", f2);
printf("Inicial:\t%.16f\n\n", f3);
return 0;
}
来自统计学领域,指的是输入的不确定性如何影响它们的数学函数。对计算算术中出现的错误进行分析是必要的
FLT_EPSILON
不是浮点结果中不确定性或错误的度量。它是1和可在float
类型中表示的下一个值之间的距离。因此,它是数量级为1的可表示数字之间的步长大小
当您将十进制数字转换为浮点时,使用“常用舍入到最近值”模式时,结果的舍入误差可能会达到步长的½。边界为½步长的原因是,对于任何数字x(在浮点格式的有限域内),在½步长(包括)内有一个可表示的值。这是因为,如果一个方向上的可表示数字大于½步长,则另一个方向上的可表示数字小于½步长
步长随数字的大小而变化。对于二进制浮点,它在2处加倍,在4处加倍,然后在8处加倍,依此类推。低于1时,它会减半,然后再次减半至½、¼,依此类推
执行浮点算术运算时,计算中发生的舍入可能会使以前的错误复现或消除。对于最终误差没有通用公式
示例代码中使用的两个数字,1.192092897e-7f
和1.192092896e-7f
非常接近,因此它们转换为相同的浮点值,2−23这就是为什么您的f2
和f3
没有区别
f1
和f2
之间存在差异,但您没有打印足够的数字来显示它
你会问“难道float
x+FLT\u EPSILON
和x-FLT\u EPSILON
的float
值不应该相同吗?”,但你的代码不包含x-FLT\u EPSILON
Re:“我的问题是R
x
的浮点值,y
的y
值是什么,x+y
|x-y
等于相同的R
浮点值?”这是y
=0可以满足的。您的意思是问满足条件的y
的最大值是多少?这有点复杂
一个数x的步长称为x的ULP,我们可以把它看作函数ULP(x)。ULP表示精度最低的单位。它是x的浮点表示形式中最小数字的位置值。它不是一个常数;它是x的函数
对于以浮点格式表示的大多数值,满足您条件的最大y
是x的浮点表示中最小数字的½ULP(x)是偶数,如果该数字是奇数,则刚好低于½ULP(x)。这种复杂性是由于算术结果四舍五入到最接近的可表示值,并且在平局的情况下,选择具有偶数低位的值。因此,将½ULP(x)与x相加将产生一个平局,如果低位为偶数,该平局将四舍五入到x,但如果低位为奇数,该平局将不会四舍五入到x
但是,对于ULP变化边界上的x,满足您条件的最大y
为¼ULP(x)。这是因为,在x以下(量级),步长会发生变化,下一个小于x的数字是x步长的一半,而不是通常的全步长。因此,在更改减法结果之前,只能向该值前进一半,因此最多y
为¼ULP(x)