从另一个人的.c文件中,我看到了这个:
const float c = 0.70710678118654752440084436210485f;
Run Code Online (Sandbox Code Playgroud)
他想避免计算的地方sqrt(1/2).
这可以用普通的方式存储C/C++吗?我的意思是没有失去精确度.对我来说似乎不可能.
我正在使用C++,但我不相信这两种语言之间的精确差异太大(如果有的话),那就是为什么我没有测试它.
所以,我写了几行,看看代码的行为:
std::cout << "Number: 0.70710678118654752440084436210485\n";
const float f = 0.70710678118654752440084436210485f;
std::cout << "float: " << std::setprecision(32) << f << std::endl;
const double d = 0.70710678118654752440084436210485; // no f extension
std::cout << "double: " << std::setprecision(32) << d << std::endl;
const double df = 0.70710678118654752440084436210485f;
std::cout << "doublef: " << std::setprecision(32) << df << std::endl;
const long double ld = 0.70710678118654752440084436210485;
std::cout << "l double: " << std::setprecision(32) << ld << std::endl;
const long double ldl = 0.70710678118654752440084436210485l; // l suffix!
std::cout << "l doublel: " << std::setprecision(32) << ldl << std::endl;
Run Code Online (Sandbox Code Playgroud)
输出是这样的:
* ** ***
v v v
Number: 0.70710678118654752440084436210485 // 32 decimal digits
float: 0.707106769084930419921875 // 24 >> >>
double: 0.70710678118654757273731092936941
doublef: 0.707106769084930419921875 // same as float
l double: 0.70710678118654757273731092936941 // same as double
l doublel: 0.70710678118654752438189403651592 // suffix l
Run Code Online (Sandbox Code Playgroud)
哪个*是最后一个准确数字float,**最后一个准确数字double和***最后一个准确数字long double.
输出double有32位十进制数,因为我已经设置了std::cout该值的精度.
float输出有24个,如预期,如说在这里:
float has 24 binary bits of precision, and double has 53.
Run Code Online (Sandbox Code Playgroud)
我希望最后一个输出与前一个输出相同,即f后缀不会阻止数字成为a double.我想当我写这篇文章时:
const double df = 0.70710678118654752440084436210485f;
Run Code Online (Sandbox Code Playgroud)
会发生的是,首先数字变为float1,然后存储为a double,所以在第24个十进制数字之后,它有零,这就是为什么double精度停在那里.
我对么?
从这个答案我发现了一些相关的信息:
float x = 0 has an implicit typecast from int to float.
float x = 0.0f does not have such a typecast.
float x = 0.0 has an implicit typecast from double to float.
Run Code Online (Sandbox Code Playgroud)
[编辑]
关于__float128,它不是标准的,因此它不在竞争中.在这里查看更多.
从标准:
有三种浮点类型:float,double和long double.double类型提供至少与float一样多的精度,long double类型提供至少与double一样多的精度.float类型的值集是double类型的值集的子集; double类型的值集是long double类型的值集的子集.浮点类型的值表示是实现定义的.
所以你可以在这个问题上看到你的问题:标准实际上没有说明精确浮点数是多少.
在标准实现方面,您需要查看IEEE754,这意味着Irineau和Davidmh的另外两个答案是解决问题的完美有效方法.
至于后缀字母表示类型,再看标准:
除非由su ffi x明确指定,否则浮动文字的类型是双重的.su ffi xes f和F指定float,su ffi xes l和L指定long double.
因此,除非使用后缀,否则创建long double遗嘱的尝试与double分配给它的文字具有相同的精度L.
我知道其中一些答案可能看起来不太令人满意,但在您解决答案之前,有相关标准需要进行大量的背景阅读.这个答案已经比预期的要长,所以我不会试着在这里解释一切.
最后要注意的是:由于精度没有明确定义,为什么不能获得比它需要的更长的常数?似乎总是定义一个足够精确的常量,以便始终可以表示,而不管类型如何.
| 归档时间: |
|
| 查看次数: |
1976 次 |
| 最近记录: |