简体   繁体   English

为什么这种 double 到 int 的转换不起作用?

[英]Why does this double to int conversion not work?

I've been thoroughly searching for a proper explanation of why this is happening, but still don't really understand, so I apologize if this is a repost.我一直在彻底寻找为什么会发生这种情况的正确解释,但仍然不太明白,所以如果这是转发,我深表歉意。

#include <iostream>
int main()
{
    double x = 4.10;
    double j = x * 100;

    int k = (int) j;

    std::cout << k;
 }

 Output: 409

I can't seem to replicate this behavior with any other number.我似乎无法用任何其他数字复制这种行为。 That is, replace 4.10 with any other number in that form and the output is correct.也就是说,将 4.10 替换为该表格中的任何其他数字,output 是正确的。

There must be some sort of low level conversion stuff I'm not understanding.一定有某种我不理解的低级转换的东西。

Thanks!谢谢!

4.1 cannot be exactly represented by a double , it gets approximated by something ever so slightly smaller: 4.1 不能用double精确表示,它可以用稍微小一点的东西来近似:

double x = 4.10;
printf("%.16f\n", x);  // Displays 4.0999999999999996

So j will be something ever so slightly smaller than 410 (ie 409.99...).所以j会比 410 稍微小一点(即 409.99...)。 Casting to int discards the fractional part, so you get 409.转换为int会丢弃小数部分,因此得到 409。

(If you want another number that exhibits similar behaviour, you could try 8.2, or 16.4, or 32.8... see the pattern?) (如果您想要另一个表现出类似行为的数字,您可以尝试 8.2、16.4 或 32.8……看到模式了吗?)

Obligatory link: What Every Computer Scientist Should Know About Floating-Point Arithmetic .必修链接:每个计算机科学家都应该知道的关于浮点运算的知识

The fix修复

int k = (int)(j+(j<0?-0.5:0.5));

The logic逻辑

You're experiencing a problem with number bases.您遇到了数字基础问题。

Although on-screen, 4.10 is a decimal, after compilation, it gets expressed as a binary floating point number, and.10 doesn't convert exactly into binary, and you end up with 4.099999....虽然在屏幕上,4.10 是十进制,但在编译后,它会被表示为二进制浮点数,而.10 并不能完全转换为二进制,你最终会得到 4.099999....

Casting 409.999... to int just drops the digits.将 409.999... 转换为 int 只会删除数字。 If you add 0.5 before casting to int, it effectively rounds to the nearest number, or 410 (409.49 would go to 409.99, cast to 409)如果在转换为 int 之前添加 0.5,它实际上会四舍五入到最接近的数字或 410(409.49 将 go 转换为 409.99,转换为 409)

Try this.尝试这个。

#include <iostream>
#include "math.h"
int main()
{
double x = 4.10;
double j = x * 100;

int k = (int) j;

std::cout << trunc(k);
std::cout << round(k);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM