首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >是否存在“双”、“K”类型的值,使`K *K == 3.0‘?

是否存在“双”、“K”类型的值,使`K *K == 3.0‘?
EN

Stack Overflow用户
提问于 2022-06-06 00:12:59
回答 5查看 392关注 0票数 7

是否存在double (IEEE 64位浮点数/ binary64)类型的值K,例如K * K == 3.0?(无理数当然是“3的平方根”)

我试过:

代码语言:javascript
运行
复制
static constexpr double Sqrt3 = 1.732050807568877293527446341505872366942805253810380628055806;
static_assert(Sqrt3 * Sqrt3 == 3.0);

但是静态断言失败了。

(我猜,舍入后,3.0的下一个更高或下一个浮点可表示数字平方都不算下一个?)还是浮点文字的解析器很愚蠢?或者它在IEEE标准中是可行的,但是快速的数学优化正在破坏它?)

我认为数字是对的:

代码语言:javascript
运行
复制
$ python

>>> N = 1732050807568877293527446341505872366942805253810380628055806
>>> N * N
2999999999999999999999999999999999999999999999999999999999996\
607078976886330406910974461358291614910225958586655450309636

更新

我发现:

代码语言:javascript
运行
复制
static_assert(Sqrt3 * Sqrt3 < 3.0); // pass
static_assert(Sqrt3 * Sqrt3 > 2.999999999999999); // pass
static_assert(Sqrt3 * Sqrt3 > 2.9999999999999999); // fail

因此,文字必须产生下一个较低的值。

我想我需要检查下一个更高的值。可以转储表示法,然后增加尾数的最后一点。

更新2

对于后代而言:我最后对Sqrt3常量和测试进行了如下操作:

代码语言:javascript
运行
复制
static constexpr double Sqrt3 = 1.7320508075688772;
static_assert(0x1.BB67AE8584CAAP+0 == 1.7320508075688772);
static_assert(Sqrt3 * Sqrt3 == 2.9999999999999996);
EN

Stack Overflow用户

发布于 2022-06-06 01:11:39

C标准没有规定默认的舍入模式。虽然它通常是四舍五入的,但它可能是向上的,而且有些实现支持改变模式。在这种情况下,舍入1.732050807568877193176604123436845839023590087890625而向上四舍五入产生的结果正好是3。

代码语言:javascript
运行
复制
#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

票数 8
EN
查看全部 5 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72511936

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档