编辑:我知道浮点运算并不精确。算术甚至不是我的问题。添加给出了我预期的结果。8099.99975f没有。
所以我有这个小程序:
public class Test {
public static void main(String[] args) {
System.out.println(8099.99975f); // 8099.9995
System.out.println(8099.9995f + 0.00025f); // 8100.0
System.out.println(8100f == 8099.99975f); // false
System.out.println(8099.9995f + 0.00025f == 8099.99975f); // false
// I know comparing floats with == can be troublesome
// but here they really should be equal in every bit.
}
}
Run Code Online (Sandbox Code Playgroud)
我编写它是为了检查当编写为 IEEE 754 单精度浮点数时是否8099.99975四舍五入。8100令我惊讶的是,Java 将其转换为8099.9995浮点文字 ( 8099.99975f)。我再次检查了我的计算和 IEEE 标准,但没有发现任何错误。与 一样8100远,但最后一位应该使其成为正确的表示。8099.999758099.99958100 …
我用 C 编写了一个程序来打印浮点数的位模式。
所以我期望收到一个标准 IEEE-754 位模式,即: 1 个符号位 | 8 EXP 位 | 23 个尾数位
当我得到输出并将结果输入 IEEE-754 转换器时,数字是错误的。当我一点点颠倒顺序时,数字是正确的。
所以我问的原因是:我发现了一个线程,其中我了解到该模式可以按字节反转,但我没有发现它完全按位反转。
有人可以澄清一下吗?
这是程序、输出和转换结果的屏幕截图。(如您所见,我以相反的顺序将数字放入转换器中,结果对我来说看起来不错。)
有许多值可以精确表示为 64 位,long但不能表示为 64 位double。(一个简单的例子:2 62 -1。)在给定间距的情况下,舍入是远离零、向零还是到最接近的可能值?
我一直在比较 Intrinsics 向量缩减、朴素向量缩减和使用 openmp 编译指示的向量缩减的运行时间。然而,我发现这些场景的结果是不同的。代码如下 - (内在向量归约取自 - Fastest way to dohorizontal SSE vector sum(或其他归约))
#include <iostream>
#include <chrono>
#include <vector>
#include <numeric>
#include <algorithm>
#include <immintrin.h>
inline float hsum_ps_sse3(__m128 v) {
__m128 shuf = _mm_movehdup_ps(v); // broadcast elements 3,1 to 2,0
__m128 sums = _mm_add_ps(v, shuf);
shuf = _mm_movehl_ps(shuf, sums); // high half -> low half
sums = _mm_add_ss(sums, shuf);
return _mm_cvtss_f32(sums);
}
float hsum256_ps_avx(__m256 v) {
__m128 vlow = _mm256_castps256_ps128(v);
__m128 vhigh = _mm256_extractf128_ps(v, 1); // high …Run Code Online (Sandbox Code Playgroud) 众所周知,并不是所有的十进制数都可以用二进制浮点数精确表示。
然而,似乎所有的二进制浮点数都可以用十进制表示法精确表示。
为什么没有任何浮点数不能用十进制表示,而反过来则不然呢?看起来有些不对称。
float f = 1.0;
while (f != 0.0) f = f / 2.0;
Run Code Online (Sandbox Code Playgroud)
该循环使用 32 位精度运行 150 次。为什么会这样?它是否四舍五入为零?
最近的 (C23) 添加stdckdint.h提供了一种可移植的方法来检查整数算术中的溢出问题。我过去曾在用户提供相关整数的情况下使用过类似的编译器扩展,并且它们非常有帮助。现在我面临着一种情况,提供的值是浮点数,我需要对它们进行算术运算。
我的问题是是否有类似的解决方案(不一定在标准库中),以确保浮点变量(浮点数、双精度数、长双精度数)之间的操作不会遇到任何问题。如果不是,算术运算期间可能出现哪些问题(上溢、下溢等)以及如何检查这些问题?
我有这个代码:
double timeTillTick = 15.0;
private void lower_Tick(object sender, EventArgs e)
{
if (timeTillClear > 0)
{
timeTillClear -= 0.1;
clearingIn10SecondsToolStripMenuItem.Text = "Clearing in " + timeTillClear + " seconds.";
}
else
{
lower.Enabled = false;
}
}
Run Code Online (Sandbox Code Playgroud)
每100毫秒降低一次滴答.当它:
它增加了0.000000000000001.为什么?
我该如何解释如下:
double o = 2.3;
int i = (int) (o * 100000.0);
double d = i / 100000.0;
System.out.println(d);
Run Code Online (Sandbox Code Playgroud)
打印2.29999
double o = 2.3;
double i = o * 100000.0;
double d = i / 100000.0;
System.out.println(d);
Run Code Online (Sandbox Code Playgroud)
打印2.3
将int除以double时,java首先将int转换为double,然后进行除法 - 如果是这样,两个代码块应该有效地打印相同的值?
似乎有一些我缺少的IEEE 754浮点精度规范和/或内联的jvm优化
double i = 2.3 * 100000.0;
double d = i / 100000.0;
Run Code Online (Sandbox Code Playgroud)
as double d = 2.3*100000.0/100000.0; 有效地取消了分裂并使其成为无操作.
思考?
NaN可能具有许多不同的二进制表示,这通常可用于提供有关NaN导致的更多信息.任何IEEE 32位浮点格式x111 1111 1xxx xxxx xxxx xxxx xxxx xxxx为NaN.此外,2个NaN(可能不同的二进制值)之间的任何比较评估为假.
给两个花车:
float a = NaN1;
float b = NaN2;
Run Code Online (Sandbox Code Playgroud)
两者都是NaN,但x上面的位可能有不同的值,比较它们的二进制内容的最正确方法是什么(即检查它们是否是相同类型的NaN)?
对我来说最明显的方法是执行c样式转换,*(uint32_t*)&a == *(uint32_t*)&b 但是,浮点数的大小不能保证为32位.