gpt4 book ai didi

c++ (double)0.700 * int(1000) => 699(不是 double 问题)

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:50:22 27 4
gpt4 key购买 nike

使用 g++ (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3

我尝试了 scaledvalue2 的不同类型转换,但直到我将乘法存储在 double 变量中,然后存储到 int 中,我才能得到期望的结果..但我无法解释为什么???

我知道 double (0.6999999999999999555910790149937383830547332763671875)是一个问题,但我不明白为什么一种方法可以,另一种不行??

如果精度有问题,我预计两者都会失败。

我不需要解决方案来修复它..但只是一个为什么??(问题已修复)

void main()
{
double value = 0.7;
int scaleFactor = 1000;

double doubleScaled = (double)scaleFactor * value;
int scaledvalue1 = doubleScaled; // = 700

int scaledvalue2 = (double)((double)(scaleFactor) * value); // = 699 ??

int scaledvalue3 = (double)(1000.0 * 0.7); // = 700

std::ostringstream oss;
oss << scaledvalue2;
printf("convert FloatValue[%f] multi with %i to get %f = %i or %i or %i[%s]\r\n",
value,scaleFactor,doubleScaled,scaledvalue1,scaledvalue2,scaledvalue3,oss.str().c_str());

}

或者简而言之:

value = 0.6999999999999999555910790149937383830547332763671875;
int scaledvalue_a = (double)(1000 * value); // = 699??
int scaledvalue_b = (double)(1000 * 0.6999999999999999555910790149937383830547332763671875); // = 700
// scaledvalue_a = 699
// scaledvalue_b = 700

我不知道这里出了什么问题。

输出:

convert FloatValue[0.700000] multi with 1000 to get 700.000000 = 700 or 699 or 700[699]

vendor_id : GenuineIntel

cpu family : 6

model : 54

model name : Intel(R) Atom(TM) CPU N2600 @ 1.60GHz

最佳答案

这会有点麻烦;我昨晚看小熊队赢得世界大赛冠军时起得太晚了,所以不要坚持精确。

评估浮点表达式的规则有些灵活,编译器通常比规则正式允许的更灵活地对待浮点表达式。这使得浮点表达式的计算速度更快,但代价是结果的可预测性有所降低。速度对于浮点计算很重要。 Java 最初犯了对浮点表达式强加精确要求的错误,数字社区痛得尖叫。 Java 不得不向现实世界屈服并放宽这些要求。

double f();
double g();
double d = f() + g(); // 1
double dd1 = 1.6 * d; // 2
double dd2 = 1.6 * (f() + g()); // 3

在 x86 硬件上(即,几乎所有现有的桌面系统),浮点计算实际上以 80 位精度完成(除非你设置了一些会降低性能的开关,如 Java 所要求的),即使 doublefloat 分别是 64 位和 32 位。因此,对于算术运算,操作数最多转换为 80 位,结果转换回 64 或 32 位。这很慢,因此生成的代码通常会尽可能长时间地延迟转换,以 80 位精度进行所有计算。

但是 C 和 C++ 都要求,当一个值存储到一个浮点变量中时,必须进行转换。因此,正式地,在//1 行中,编译器必须将总和转换回 64 位以将其存储到变量 d 中。然后,在//2 行中计算的 dd1 的值必须使用存储到 d 中的值(即 64 位值)进行计算,而该值在行//3 中计算的 dd2 可以使用 f() + g() 计算,即完整的 80 位值。这些额外的位可能会有所不同,dd1 的值可能与 dd2 的值不同。

编译器通常会保留 f() + g() 的 80 位值,并使用它代替存储在 d 中的值计算 dd1 的值。这是一个不符合规范的优化,但据我所知,默认情况下每个编译器都会做这种事情。它们都有命令行开关来强制执行严格要求的行为,所以如果你想要更慢的代码,你可以得到它。

对于严肃的数字运算,速度至关重要,因此欢迎这种灵 active ,并且仔细编写数字运算代码以避免对这种细微差异敏感。人们获得博士学位是因为弄清楚了如何使浮点代码快速有效,所以不要因为看到的结果似乎没有意义而难过。它们没有,但它们足够接近,如果小心处理,它们可以在不影响速度的情况下给出正确的结果。

关于c++ (double)0.700 * int(1000) => 699(不是 double 问题),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40400991/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com