Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/powerbi/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 浮点数据类型不确定性_C_Floating Point_Precision_Epsilon - Fatal编程技术网

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)