将double转换为int不准确(1关)

时间:2017-04-02 05:07:31

标签: c

我有以下情况给我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 ......但我很困惑,因为在这种情况下会出现这种情况。

谢谢!

1 个答案:

答案 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"); } } 可以轻松改变结果。