是否存在double (IEEE 64位浮点数/ binary64)类型的值K,例如K * K == 3.0?(无理数当然是“3的平方根”)
我试过:
static constexpr double Sqrt3 = 1.732050807568877293527446341505872366942805253810380628055806;
static_assert(Sqrt3 * Sqrt3 == 3.0);但是静态断言失败了。
(我猜,舍入后,3.0的下一个更高或下一个浮点可表示数字平方都不算下一个?)还是浮点文字的解析器很愚蠢?或者它在IEEE标准中是可行的,但是快速的数学优化正在破坏它?)
我认为数字是对的:
$ python
>>> N = 1732050807568877293527446341505872366942805253810380628055806
>>> N * N
2999999999999999999999999999999999999999999999999999999999996\
607078976886330406910974461358291614910225958586655450309636更新
我发现:
static_assert(Sqrt3 * Sqrt3 < 3.0); // pass
static_assert(Sqrt3 * Sqrt3 > 2.999999999999999); // pass
static_assert(Sqrt3 * Sqrt3 > 2.9999999999999999); // fail因此,文字必须产生下一个较低的值。
我想我需要检查下一个更高的值。可以转储表示法,然后增加尾数的最后一点。
更新2
对于后代而言:我最后对Sqrt3常量和测试进行了如下操作:
static constexpr double Sqrt3 = 1.7320508075688772;
static_assert(0x1.BB67AE8584CAAP+0 == 1.7320508075688772);
static_assert(Sqrt3 * Sqrt3 == 2.9999999999999996);发布于 2022-06-06 00:46:00
我认为用Python进行测试是有效的,因为这两种方法都使用IEEE-754表示形式来实现双倍,以及对相同的操作使用规则。
最接近3平方根的二倍是略低的。
>>> Sqrt3 = 3**0.5
>>> Sqrt3*Sqrt3
2.9999999999999996下一个可用值太高。
>>> import numpy as np
>>> Sqrt3p = np.nextafter(Sqrt3,999)
>>> Sqrt3p*Sqrt3p
3.0000000000000004如果你能平分的话,你就有了。
>>> Sqrt3*Sqrt3p
3.0发布于 2022-06-06 01:11:39
C标准没有规定默认的舍入模式。虽然它通常是四舍五入的,但它可能是向上的,而且有些实现支持改变模式。在这种情况下,舍入1.732050807568877193176604123436845839023590087890625而向上四舍五入产生的结果正好是3。
#include <fenv.h>
#include <math.h>
#include <stdio.h>
#pragma STDC FENV_ACCESS ON
int main(void)
{
volatile double x = 1.732050807568877193176604123436845839023590087890625;
fesetround(FE_UPWARD);
printf("%.99g\n", x*x); // Prints “3”.
}x被声明为volatile,以防止编译器在编译时使用不同的舍入模式计算x*x。有些编译器不支持#pragma STDC FENV_ACCESS,但在删除#pragma行后可能支持#pragma。
发布于 2022-06-06 00:54:21
在Ruby中,Float类使用“本机体系结构的双精度浮点表示”,它有名为prev_float和next_float的方法,可以使用最小的步骤迭代不同的可能浮动。使用它,我能够做一个简单的测试,并且看到没有符合您的标准的没有 double (至少在x86_64 Linux上是这样)。Ruby解释器是用C编写的,所以我认为我的结果应该适用于C double类型。
下面是Ruby代码:
x = Math.sqrt(3)
4.times { x = x.prev_float }
9.times do
puts "%.20f squared is %.20f" % [x, x * x]
puts "Success!" if x * x == 3
x = x.next_float
end以及产出:
1.73205080756887630500 squared is 2.99999999999999644729
1.73205080756887652704 squared is 2.99999999999999733546
1.73205080756887674909 squared is 2.99999999999999822364
1.73205080756887697113 squared is 2.99999999999999866773
1.73205080756887719318 squared is 2.99999999999999955591
1.73205080756887741522 squared is 3.00000000000000044409
1.73205080756887763727 squared is 3.00000000000000133227
1.73205080756887785931 squared is 3.00000000000000177636
1.73205080756887808136 squared is 3.00000000000000266454https://stackoverflow.com/questions/72511936
复制相似问题