关于 double 转 int 的困惑

SegmentFault 2011-05-24 10:46:15
如下代码:

#include <iostream>

using namespace std;

int main()
{
double d = 5.09;
double e;
int64_t i;

e = d * 100;
i = (int64_t)(d*100);

cout << "e: " << e << endl;
cout << "i: " << i << endl;

return 0;
}


编译执行后的结果是:

e: 509
i: 508

请教:为什么会这样呢?
...全文
187 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
mythos55 2011-05-26
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 segmentfault 的回复:]
谢谢楼上各位热心朋友的解答。对于 double 值的精确问题,我还是很疑惑,为什么值会不精确呢?但是变量 e 的值为什么又是精确的呢?

如下修改:

int main()
{
double d = 5.09;
double e;
int64_t i;

e = d * 100;
//i = (int64_t)(d*100);
i = (int64_……
[/Quote]
wizard_tiger 2011-05-26
  • 打赏
  • 举报
回复
储存方式和精度不相同。
SegmentFault 2011-05-26
  • 打赏
  • 举报
回复
谢谢楼上各位热心朋友的解答。对于 double 值的精确问题,我还是很疑惑,为什么值会不精确呢?但是变量 e 的值为什么又是精确的呢?

如下修改:

int main()
{
double d = 5.09;
double e;
int64_t i;

e = d * 100;
//i = (int64_t)(d*100);
i = (int64_t)e;

//cout << "e: " << e << endl;
//cout << "i: " << i << endl;

printf("e=%f\n", e);
printf("i=%lld\n", i);

return 0;
}

运行结果是:

e=509.000000 //而不是 508.999999
i=509

SegmentFault 2011-05-26
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 qingtianweichong 的回复:]

我试了一下,应该是输出格式的问题.你可以试一下
[/Quote]

我改用 printf("%f",e) 和 printf("%lld",i)输出,还是不同。
Defonds 2011-05-25
  • 打赏
  • 举报
回复
注意精度的丢失
SegmentFault 2011-05-25
  • 打赏
  • 举报
回复
按LS和1楼朋友的说法,确实就可以了。不过很疑惑为什么 double 值会不精确呢? double 不是双精度吗?

另外不知这样行不行:i = (int64_t)floor(d*100);
qingtianweichong 2011-05-25
  • 打赏
  • 举报
回复
我试了一下,应该是输出格式的问题.你可以试一下
SophiaNM 2011-05-24
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 luciferisnotsatan 的回复:]
double的值不是精确的
比如508.99999,强转int后,截去小数部分,就成了508
[/Quote]

1楼说的对,应该
i = (int64_t)(d*100 + 0.5);
赵4老师 2011-05-24
  • 打赏
  • 举报
回复
C:\Program Files\Microsoft Visual Studio 8\VC\crt\src\limits.h
...
#if _INTEGRAL_MAX_BITS >= 8
#define _I8_MIN (-127i8 - 1) /* minimum signed 8 bit value */
#define _I8_MAX 127i8 /* maximum signed 8 bit value */
#define _UI8_MAX 0xffui8 /* maximum unsigned 8 bit value */
#endif /* _INTEGRAL_MAX_BITS >= 8 */

#if _INTEGRAL_MAX_BITS >= 16
#define _I16_MIN (-32767i16 - 1) /* minimum signed 16 bit value */
#define _I16_MAX 32767i16 /* maximum signed 16 bit value */
#define _UI16_MAX 0xffffui16 /* maximum unsigned 16 bit value */
#endif /* _INTEGRAL_MAX_BITS >= 16 */

#if _INTEGRAL_MAX_BITS >= 32
#define _I32_MIN (-2147483647i32 - 1) /* minimum signed 32 bit value */
#define _I32_MAX 2147483647i32 /* maximum signed 32 bit value */
#define _UI32_MAX 0xffffffffui32 /* maximum unsigned 32 bit value */
#endif /* _INTEGRAL_MAX_BITS >= 32 */

#if _INTEGRAL_MAX_BITS >= 64
/* minimum signed 64 bit value */
#define _I64_MIN (-9223372036854775807i64 - 1)
/* maximum signed 64 bit value */
#define _I64_MAX 9223372036854775807i64
/* maximum unsigned 64 bit value */
#define _UI64_MAX 0xffffffffffffffffui64
#endif /* _INTEGRAL_MAX_BITS >= 64 */

#if _INTEGRAL_MAX_BITS >= 128
/* minimum signed 128 bit value */
#define _I128_MIN (-170141183460469231731687303715884105727i128 - 1)
/* maximum signed 128 bit value */
#define _I128_MAX 170141183460469231731687303715884105727i128
/* maximum unsigned 128 bit value */
#define _UI128_MAX 0xffffffffffffffffffffffffffffffffui128
#endif /* _INTEGRAL_MAX_BITS >= 128 */
...

C:\Program Files\Microsoft Visual Studio 8\VC\crt\src\float.h
...
#define DBL_DIG 15 /* # of decimal digits of precision */
#define DBL_EPSILON 2.2204460492503131e-016 /* smallest such that 1.0+DBL_EPSILON != 1.0 */
#define DBL_MANT_DIG 53 /* # of bits in mantissa */
#define DBL_MAX 1.7976931348623158e+308 /* max value */
#define DBL_MAX_10_EXP 308 /* max decimal exponent */
#define DBL_MAX_EXP 1024 /* max binary exponent */
#define DBL_MIN 2.2250738585072014e-308 /* min positive value */
#define DBL_MIN_10_EXP (-307) /* min decimal exponent */
#define DBL_MIN_EXP (-1021) /* min binary exponent */
#define _DBL_RADIX 2 /* exponent radix */
#define _DBL_ROUNDS 1 /* addition rounding: near */
...
DST_Roger 2011-05-24
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 segmentfault 的回复:]

按LS改的就显示509了。

有没有什么办法不更改 i,e 的变量值,同时又能正确转换数值?我这个是个示例程序,实际要改的程序中的变量值大小是未知的而且不能修改。
[/Quote]

那就用字符串操作吧,不要使用数值了。。
SegmentFault 2011-05-24
  • 打赏
  • 举报
回复
按LS改的就显示509了。

有没有什么办法不更改 i,e 的变量值,同时又能正确转换数值?我这个是个示例程序,实际要改的程序中的变量值大小是未知的而且不能修改。
DST_Roger 2011-05-24
  • 打赏
  • 举报
回复

#include <iostream>

using namespace std;

int main()
{
double d = 5.09;
double e;
int64_t i;

e = d * 10000;
i = (int64_t)e/100;

cout << "e: " << e << endl;
cout << "i: " << i << endl;

return 0;
}


精度问题,试试看这个...
zhuywei123 2011-05-24
  • 打赏
  • 举报
回复
应该与类型在内存中的存储格式有关
luciferisnotsatan 2011-05-24
  • 打赏
  • 举报
回复
double的值不是精确的
比如508.99999,强转int后,截去小数部分,就成了508

33,311

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 新手乐园
社区管理员
  • 新手乐园社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧