是否存在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 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。
https://stackoverflow.com/questions/72511936
复制相似问题