Tag: 浮点

如何检查是否使用了IEEE 754单精度(32位)浮点表示?

我想在目标板上测试以下内容: 使用IEEE 754单精度(32位)浮点变量实现’float’吗? 使用IEEE 754双精度(64位)浮点变量实现“双重”吗? 有什么方法可以用简单的C程序测试它。

IEEE 754:它究竟是如何工作的?

为什么以下代码的行为与C中的行为相同? float x = 2147483647; //2^31 printf(“%f\n”, x); //Outputs 2147483648 这是我的思考过程: 2147483647 = 0 1001 1101 1111 1111 1111 1111 1111 111 (0.11111111111111111111111)base2 = (1-(0.5)^23)base10 => (1.11111111111111111111111)base2 = (1 + 1-(0.5)^23)base10 = (1.99999988)base10 因此,要将IEEE 754表示法转换回小数: 1.99999988 * 2^30 = 2147483520 所以从技术上讲,C程序必须打印出2147483520,对吗?

使用标准C数学库实现sinpi()和cospi()

函数sinpi(x)计算sin(πx),函数cospi(x)计算cos(πx),其中与π的乘法隐含在函数内部。 这些函数最初被引入C标准数学库,作为Sun Microsystems在20世纪80年代后期的扩展。 IEEE Std 754™-2008在第9节中规定了等效函数sinPi和cosPi 。 有许多计算,sin(πx)和cos(πx)自然发生。 一个非常简单的例子是Box-Muller变换(GEP Box和Mervin E. Muller,“关于随机正态偏差的一个注记”。 “数学统计年鉴” ,第29卷,第2期,第610-611页) ),给定两个独立的随机变量U 1和U 2均匀分布,产生具有标准正态分布的独立随机变量Z 1和Z 2: Z₁ = √(-2 ln U₁) cos (2 π U₂) Z₂ = √(-2 ln U₁) sin (2 π U₂) 另一个例子是度数参数的正弦和余弦的计算,就像使用Haversine公式计算大圆距离一样: /* This function computes the great-circle distance of two points on earth using the Haversine formula, assuming […]

有效地计算(a-K)/(a + K)并提高精度

在各种情况下,例如对于数学函数的参数减少,需要计算(a – K) / (a + K) ,其中a是正变量参数而K是常数。 在许多情况下, K是2的幂,这是与我的工作相关的用例。 我正在寻找比直接划分更准确地计算这个商的有效方法。 可以假设对融合乘法 – 加法(FMA)的硬件支持,因为此操作由此时所有主要CPU和GPU架构提供,并且可通过函数fma()和fmaf()以C / C ++forms提供。 为了便于探索,我正在尝试float运算。 由于我计划将方法移植到double算法,因此不能使用高于参数和结果的本机精度的操作。 到目前为止我的最佳解决方案是 /* Compute q = (a – K) / (a + K) with improved accuracy. Variant 1 */ m = a – K; p = a + K; r = 1.0f / p; q = m […]

Payne Hanek算法在C中的实现

我正在努力理解如何实现Payne和Hanek发布的范围缩减算法(三角函数的范围缩减) 我见过这个库: http : //www.netlib.org/fdlibm/ 但它看起来如此扭曲,我所创立的所有理论解释都太简单了,无法提供实现。 有一些好的……好的……好的解释吗?

是`x!= x`是一种可以测试NaN的便携方法吗?

在C中,您可以使用isnan(x)测试是否为NaN。 然而,许多地方在线,包括例如这个SO答案说你可以简单地使用x!=x代替。 在任何C规范中x!=x作为保证测试x是NaN的方法吗? 我自己找不到它,我希望我的代码能够与不同的编译器一起工作。

如何测试无损双/整数转换?

我有一个双,一个int64_t。 我想知道它们是否保持完全相同的值,如果将一种类型转换为另一种类型,则不会丢失任何信息。 我目前的实施如下: int int64EqualsDouble(int64_t i, double d) { return (d >= INT64_MIN) && (d < INT64_MAX) && (round(d) == d) && (i == (int64_t)d); } 我的问题是:这个实现是否正确? 如果没有,那么什么是正确答案? 为了正确,它必须不留假阳性,不得假阴性。 一些示例输入: int64EqualsDouble(0,0.0)应该返回1 int64EqualsDouble(1,1.0)应该返回1 int64EqualsDouble(0x3FFFFFFFFFFFFFFF,(double)0x3FFFFFFFFFFFFFFF)应该返回0,因为2 ^ 62-1可以用int64_t精确表示,但不能用double表示。 int64EqualsDouble(0x4000000000000000,(double)0x4000000000000000)应返回1,因为2 ^ 62可以在int64_t和double中精确表示。 int64EqualsDouble(INT64_MAX,(double)INT64_MAX)应返回0,因为INT64_MAX不能完全表示为double int64EqualsDouble(…,1.0e100)应该返回0,因为1.0e100不能完全表示为int64_t。

为什么需要一个明确的`-lm`编译器选项

可能重复: gcc:为什么链接数学库需要-lm标志? 一般来说,除了包含头文件math.h之外,为了使用任何数学函数,您必须使用链接器选项-lm进行链接。 -l这里将指代用于搜索特定库libm.o的链接器选项。 我的问题是 为什么GCC默认不包含此库? 是因为库大量使用数学协处理器,它需要添加额外的代码来初始化浮点初始化(我可能在这里使用了错误的术语)? 注意 我刚刚查看了http://stackoverflow.com链接中提到的所有答案。 这对我来说没什么意义。 归因于三个基本原因 保证标准库可用。 链接其他posix库(如pthread)明确有意义,但为什么我们必须为标准库做一个显式链接。 即使是历史原因也不是很清楚。 为什么libm与libc分开? 为什么我们仍然在最近的gcc编译器中inheritance这些行为? 它有什么简单性? 这是我测试的,没有libm和libm。 没有libm的那个,我已经写了我自己的Pow版本 这是一个例子 abhibhat@abhibhat-VirtualBox:~/Projects/GIPL6_2$ ls -1 Test_*|xargs -I{} sh -c “echo {} && echo “—————–” && cat {}” Test_withlibm.c —————– #include #include int main() { int i=20; double output1=pow(2.618033988749895,i); return 0; } Test_withoutlibm.c —————– #include #include double Pow(double […]

高效忠实地实现错误函数erff()

误差函数与标准正态分布密切相关,并且经常出现在自然科学以及其他领域。 例如,它在定价选项时用于财务。 虽然它首先添加到ISO C99,然后以函数erf() , erff()的forms添加到C ++,但直到最近才出现了至少一个流行的C / C +工具链。 许多项目仍然使用他们自己的错误函数实现,通常基于旧文献的近似,例如Abramowitz和Stegun ,后者又回到 Cecil Hastings Jr,“数字计算机的近似值”。 普林斯顿大学出版社,1955年 在现代计算中,超越函数的忠实圆形实现通常被视为数学库的最低准确度标准; 这样的标准仍然允许高性能实现。 当函数返回最大误差小于1 ulp的结果与整个输入域中的数学值相比时,函数被称为忠实舍入。 当使用IEEE-754单精度操作实现时,较早发布的算法不能提供忠实的圆形结果。 现代计算机硬件提供称为融合乘法 – 加法(或简称FMA)的浮点运算,它计算浮点乘法,然后进行相关的浮点加法,以便在加法中使用完整的未接地产品,并且只有单个舍入发生在操作结束时。 IBM于1990年推出的这种融合操作在许多计算中提供了更高的准确性和更高的性能。 它可用于当今最流行的两种CPU架构(ARM和x86)以及GPU。 它已通过fmaf()和fmaf()函数在C和C ++中fmaf() 。 假设FMA本身是由硬件支持的,那么如何构建单精度错误函数erff() ,它既忠实圆润又高效? 优选地,代码应该是可矢量化的,可能在次要代码修改之后。

如果所有位都为0,那么IEEE浮点值是多少?

如果所有位都为0(例如,我将浮点变量设置为全0),那么gcc中使用的IEEE浮点值是多少? 它保证是0.0? 我想其他浮点格式的结果可能会有所不同。 但我的问题是特定于与gcc一起使用的IEEE浮点数。