我有以下情况给我27而不是28:
double d = 0.35;
int i = 80;
int ans = (int)(d * i);
printf("%d", ans);
但如果我使用它,我会得到正确答案:
int ans = (int)(0.35 * 80);
printf("%d", ans);
或:
double ans = d * i;
printf("%d", (int) ans);
有人可以解释为什么第一种情况是1次关闭而其他情况有效吗?
我做了一些研究,人们说双重存储28个数字为27.999 ......但我很困惑,因为在这种情况下会出现这种情况。
谢谢!
答案 0 :(得分:3)
0.35
的值没有精确的二进制浮点表示。因此,在使用基于IEEE 754的浮点支持的典型平台上,您的double d = 0.35;
根本不是0.35
,而是类似于0.34999999999999998
- 在这种情况下恰好是{ 小于原始0.35
。其余部分如下:乘法产生的28
小于27
,(int)
会将其截断为28
。故事结束。
如果某人从此示例中获得0.35
,则可能意味着他们的编译器使用不同的浮点评估模型,其中原始0.35
可能代表精确或某些值略微更大而不是0.35000000000012
(例如,int ans = (int)(d * i);
printf("%d", ans);
或类似的东西)。优化计算并在编译时执行它们的编译器也属于该类别。
之间的区别
double ans = d * i;
printf("%d", (int) ans);
和
double
在第二种情况下,编译器将中间结果存储在ans
变量double
中可能很容易导致。
实际的乘法可能在CPU的高精度浮点寄存器中执行(其精度高于int
)。在第一种情况下,结果直接存储到double
中。在第二种情况下,它首先转换为精度较低的double
,然后int
转换为double
。这种额外的中间转换为public string LoginAndReadPage() {
WebBrowser wb = new WebBrowser();
wb.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(wb_DocumentCompleted);
wb.Navigate("hxxp://mysite.com/login");
}
private async void wb_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
if (wb.Url.ToString().Contains("login"))
{
wb.Document.GetElementsByTagName("input").GetElementsByName("email")[0].SetAttribute("value", _login);
wb.Document.GetElementsByTagName("input").GetElementsByName("password")[0].SetAttribute("value", _password);
wb.Document.GetElementsByTagName("button")[0].InvokeMember("click");
}
else if (wb.Url.ToString().Contains("dashboard"))
{
return wb.DocumentText; // I want to return the content of mysite.com/dashboard
}
else
{
await Task.Delay(1000); //wait for 1 second just to let the WB catch up
wb.Navigate("hxxp://mysite.com/dashboard");
}
}
可以轻松改变结果。