是否存在类型为double(IEEE 64位浮点/二进制64)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

Update

我发现:

static_assert(Sqrt3 * Sqrt3 < 3.0); // pass
static_assert(Sqrt3 * Sqrt3 > 2.999999999999999); // pass
static_assert(Sqrt3 * Sqrt3 > 2.9999999999999999); // fail

因此,文本必须生成下一个较低的值.

我想我需要判断下一个更高的值.可以位转储表示,然后增加尾数的最后一位.

Update 2

对于子孙后代:我最后将此用于Sqrt3常量和测试:

static constexpr double Sqrt3 = 1.7320508075688772;
static_assert(0x1.BB67AE8584CAAP+0 == 1.7320508075688772);
static_assert(Sqrt3 * Sqrt3 == 2.9999999999999996);

推荐答案

我认为用Python进行测试是有效的,因为两者都使用IEEE-754表示double,并使用相同的操作规则.

离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

C++相关问答推荐

有关字符数组指针和次指针以及qsort函数中的cmp函数的问题

如何将一个enum类型类型转换为另一个类型?

Pure Win32 C(++)-除了替换控件的窗口程序之外,还有其他方法可以在输入时禁用按钮吗?

C strlen on char array

如何将不同长度的位转换成字节数组?

为什么删除CAP_DAC_OVERRIDE后创建文件失败?

C是否用0填充多维数组的其余部分?

我的C函数起作用了,但我不确定为什么

为 struct 中的数组动态分配内存时出错

接受任何参数的函数指针是否与接受不同参数的函数兼容

我不知道为什么它不能正常工作,我用了get()和fget(),结果是一样的

程序如何解释变量中的值

在Ubuntu上使用库部署C程序的最佳实践

函数的typedef是标准 C 语法吗?它与函数指针的typedef有何不同?

C/C++编译器可以在编译过程中通过按引用传递来优化按值传递吗?

在C中定义函数指针?

使用复合文字数组初始化的指针数组

将数组返回到链表

C语言程序流程解释

nullptr_t 是否会 destruct 类型双关或指针转换?