- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
在我的计算机科学类(class)中,我们正在研究 float 以及它们在内存中的表示方式。我已经了解它们在内存中的表示方式(尾数/尾数、指数及其偏差以及符号位),并且我了解 float 如何彼此相加和相减(非规范化和所有这些有趣的东西)。然而,在查看一些学习问题时,我发现了一些我无法解释的事情。
当一个无法精确表示的 float 与自身相加多次时,答案会低于我们在数学上的预期,但当同一个 float 乘以一个整数时,答案会精确地得出正确的数字。
这是我们学习问题中的一个示例(该示例是用 Java 编写的,为了简单起见,我对其进行了编辑):
float max = 10.0f; /* Defined outside the function in the original code */
float min = 1.0f; /* Defined outside the function in the original code */
int count = 10; /* Passed to the function in the original code */
float width = (max - min) / count;
float p = min + (width * count);
在此示例中,我们被告知结果恰好为 10.0
。但是,如果我们将此问题视为 float 之和,我们会得到略有不同的结果:
float max = 10.0f; /* Defined outside the function in the original code */
float min = 1.0f; /* Defined outside the function in the original code */
int count = 10; /* Passed to the function in the original code */
float width = (max - min) / count;
for(float p=min; p <= max; p += width){
System.out.printf("%f%n", p);
}
我们得知,此测试中 p
的最终值为 ~9.999999
,两者之间的差异为 -9.536743E-7
p
的最后一个值和 max
的值。从逻辑的角度来看(了解 float 如何工作),这个值是有意义的。
但我不明白的是,为什么我们在第一个示例中得到的结果恰好是 10.0。从数学上讲,我们得到 10.0 是有道理的,但知道 float 如何存储在内存中,这对我来说没有意义。谁能解释一下为什么我们通过将不精确的 float 与整数相乘来得到精确的值?
编辑:澄清一下,在最初的研究问题中,一些值被传递给函数,而其他值则在函数外部声明。我的示例代码是研究问题示例的缩短和简化版本。由于某些值被传递到函数中而不是显式定义为常量,因此我相信可以排除编译时的简化/优化。
最佳答案
首先,一些挑剔:
When a float that cannot be precisely represented
不存在“无法精确表示的 float ”。全部float
s可以精确地表示为float
s。
is added to itself several times, the answer is lower than we would mathematically expect,
当您多次将一个数字与自身相加时,您实际上可以得到比您预期更高的值。我将使用 C99 hexfloat notation 。考虑f = 0x1.000006p+0f
。然后f+f = 0x1.000006p+1f
, f+f+f = 0x1.800008p+1f
, f+f+f+f = 0x1.000006p+2f
, f+f+f+f+f = 0x1.400008p+2f
, f+f+f+f+f+f = 0x1.80000ap+2f
,和f+f+f+f+f+f+f = 0x1.c0000cp+2f
。然而,7.0*f = 0x1.c0000a8p+2
,四舍五入为 0x1.c0000ap+2f
,小于f+f+f+f+f+f+f
.
but when that same float is multiplied by an integer, the answer, comes out precisely to the correct number.
7 * 0x1.000006p+0f
不能表示为 IEEE float
。因此它会被舍入。使用舍入到最近的舍入到偶数的默认舍入模式,当您执行这样的单个算术运算时,您将获得最接近精确结果的 float 。
The thing that I do not understand, though, is why we get exactly 10.0 for the first example. Mathematically, it makes sense that we would get 10.0, but knowing how floats are stored in memory, it does not make sense to me. Could anyone explain why we get a precise and exact value by multiplying an imprecise float with an int?
为了回答你的问题,你会得到不同的结果,因为你做了不同的操作。您在这里得到“正确”答案有点侥幸。
让我们交换一下数字。如果我计算0x1.800002p+0f / 3
,我得到0x1.00000155555...p-1
,四舍五入为 0x1.000002p-1f
。当我将其增加三倍时,我得到 0x1.800003p+0f
,四舍五入(因为我们打破平局)为 0x1.800004p+0f
。这与计算 f+f+f
得到的结果相同在float
算术其中f = 0x1.000002p-1f
.
关于floating-point - 浮点相加与浮点乘以整数的精度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35513136/
这个问题已经有答案了: Invalid types 'double [100][double]' for array subscript (3 个回答) 已关闭 6 年前。 我已复制下面的整个代码并在
您有 2 个功能; f(x)= x(((x+1)^(1/2))-(x^(1/2))) g(x)= x/(((x+1)^(1/2))+(x^(1/2))) 哪个更准确? 旁注:如果你能解释为什么,
我正在从事一个关于java的研究项目,其中必须完成一些艰难的计算。然而,我已经完成了大部分工作,但停留在某个点上。我必须计算以下内容: (2.1-2.3) raised to power 0.3. 但
int main() { float x = 50; float y = 1/x; float result = y * x; float test = 41;
有没有安全的方法来可靠地确定整数类型 T可以存储浮点整数值 f (所以 f == floor(f) )没有任何溢出? 请记住,不能保证浮点类型 F与 IEC 559 (IEEE 754) 兼容,并且有
// value will always be in the range of [0.0 - maximum] float obtainRatio(float value, float maximum
就在今天,我遇到了我们正在使用的第三方软件,在他们的示例代码中,有以下内容: // Defined in somewhere.h static const double BAR = 3.14; //
是否有推荐的方法来清除 jQuery Flot 图表?我在 API 引用中找不到任何内容。 最佳答案 “清除”是指“破坏整个图表”还是只是清除数据? 要核对整个图表:$('#canvas_id').e
我正在学习单精度并想了解错误传播。根据this nice website ,加法是一个危险的操作。 所以我编写了一个小的 C 程序来测试错误累积的速度。我不完全确定这是否是一种有效的测试方法。如果是,
我正在尝试查询数据库,我需要获取权重等于 60.5 的客户列表。问题是 60.5 是一个实数,我以前从未在 where 子句中使用实数查询过数据库。 我已经尝试过这个: SELECT Name FRO
这是我的“ProjectEntity”类中的代码部分(我在其中使用 hibernate 进行 SQL 调用) @Column(name = "BUDGET") private float budget
我用 Haskell 编写了一个应用程序,它调用 Z3 求解器来解决一些复杂公式的约束。感谢 Haskell,我可以快速切换正在使用的数据类型。 当使用 SBV 的 AlgReal 类型进行计算时,我
在 C 中 double/float 有一个集合类型说明符:%f %F %g %G %e %E .有什么区别吗 %f和 %F , %g和 %G , %e和 %E ? 根据 printf和 scanf输
我正在开发一个适用于 Android 的可视化应用程序(包括运行 Android 2.2 的旧设备)。 我的应用程序的输入模型包含一个区域,该区域通常由数万个顶点组成。典型模型有 50000-1000
关闭。这个问题需要多问focused 。目前不接受答案。 想要改进此问题吗?更新问题,使其仅关注一个问题 editing this post . 已关闭 6 年前。 Improve this ques
我被要求编写一个程序来查找我大学中两个输入的总和,因此我应该首先检查输入是否有效。 例如,如果我输入 2534.11s35,程序应该检测到它不是该程序的有效输入,因为输入中存在 s。 最佳答案 to
我正在尝试降低 FPGA 的逻辑利用率,但在网上找不到任何好的 float fastpow。我所说的“好”是指充分减少所使用的逻辑。如果我使用双版本我几乎没有什么改进。如果我使用其他依赖日志的 flo
我有一个 128 字节的内存位置。我尝试用从 1...127 开始的数据填充内存。 我需要编写一个代码来获取两个参数,如偏移量、数据类型。根据参数,我需要将内存中的数据转换为提到的特定数据类型。 举个
我希望能够做到以下几点: float func() { if( error ) return InvalidFloatingPointValue; else return 0.0f;
假设我有两个 float ,我想比较它们。如果一个大于另一个,程序应该采用一个 fork。如果情况正好相反,它应该走另一条路。并且它应该做同样的事情,如果被比较的值在一个仍然应该使它比较真实的方向上被
我是一名优秀的程序员,十分优秀!