EditBox中的浮点数处理问题

Apezyfly 2005-01-23 04:56:25
要实现的功能:
自动处理输入的浮点数,超过n位小数的自动截掉后面的。

我的方法(有缺陷):
///////////
//EditBox定义为double m_d1

UpdateData();
int m = int(pow(10, n));
double d = floor(m_d1 * m);//假设录入的都是正数
m_d1 = d / m;
UpdateData(FALSE);

/////////

但是这里有个很可笑的问题,如果录入的是5.6,出来的就是5.59。
DEBUG发现,5.6其实存进去是5.5999999999999996,最后就倒腾成5.59了……。

各位有没有好方法?
另请教VC中有没有类似DELPHI中的MASKEDIT控件的?
...全文
231 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
Apezyfly 2005-03-23
  • 打赏
  • 举报
回复
补充说明:

关于一下语句:
————
double d;
d = 5.6;
————

在DEBUG中察看d,显示的是“5.5999999999999996”,这是在打过Visual Studio SP6之后的表现,没打过补丁的,显示的是“5.56000000……”(后面具体几个零记不清了),这是我在多台机器上试验的结果。

虽然从形式上“5.60000…”比“5.59999…”看起来更准确,其实后者才是比较“正确”的数值。

一个十进制的浮点数,不一定可以无任何误差的转化为一个二进制数。

“5.6”,是个十进制浮点数;double类型在存储形式上是64bit的二进制。
“5.6”在存放到double类型的变量中的时候,已经存在了误差!

这个误差是比真实值多了还是少了,暂时我说不上。但我猜测“5.59999…”是比较真实反映内存保存内容的数值,而“5.60000…”,应该是在有限位数做了取舍。

相比这也是 VS SP6 的进步吧。

一点收获,欢迎分享和讨论。
Apezyfly 2005-02-07
  • 打赏
  • 举报
回复
我希望对原数进行纯粹的“去尾”,不进行四舍五入等任何处理。
看来Format并不合适。

当我对“5.6”处理的时候,我希望得到的是5.60(假设保留两位小数);
但我原来的方法,第一个帖子里,却得到了5.59。

采用风兄的方法可以正确处理“5.6”,但处理“5.5999999999999996”时却得到了5.60,按我希望的纯粹“去尾”,本来应该是得到5.59的。

问题还是出在double类型的数据存入的时候发生了轻微浮点误差。(5.6变5.5999999999999996)

我最后采用的方式是直接输入字符类型,然后对字符进行去尾操作。这样虽然麻烦,但很纯粹。
fengqinggao 2005-02-07
  • 打赏
  • 举报
回复
Format函数遵循的是四舍五入的方法,你的5.59999999999999996,如果精确,当然应该是5.60(不是5.6),你想要得到5.59,实际上采用的是“去尾”法,这个精度就降低了不少,如你一开始的问题所说,你不是不希望得到5.59么?呵呵,怎么要求变了?
Apezyfly 2005-02-07
  • 打赏
  • 举报
回复
fengqinggao(风清高)的方法有点问题:

当 m_d1 = 5.5999999999999996 的时候,
sTemp.Format("%.2f", m_d1);//这里sTemp会变成5.6,预想应该变成5.59的

我已经找到方法了,实现比较曲折,晚点发代码上来。
基本的方法是把录入的数以字符形式处理,根据小数点位置去掉多的字符。
Apezyfly 2005-02-06
  • 打赏
  • 举报
回复
to truewill(无处不在) :

要处理的数比较大上限是(1000,0000,0000),先转换成整数是很好的思路,但是在C的数据类型中,long int类型才支持到10位,不够用。

我看标准C的C99规范里有long long int类型,可支持的数很大,可惜在VC里不能直接接受该数据类型。(这个问题诸位有好的方法吗?)

fengqinggao(风清高) 的是个不错的方法,打算一试。
fengqinggao 2005-01-23
  • 打赏
  • 举报
回复
先用字符串格式化语句转换成字符串,然后再转换成数据,大体代码如下:
CString sTemp;
sTemp.Format("%.nf", m_dl);//n是保留的小数点位数;
m_dl = atof(sTemp.GetBuffer(sTemp.GetLength()));
UpdateData(FALSE);

应该可行,而且也比较简单,缺陷在于小数点位数必须是已知的,不能用参数代替(受Format语句的限制)
I_Love_CPP 2005-01-23
  • 打赏
  • 举报
回复
static CString strValue;

if(strValue.GetLength() > n)
return;
else
{
继续写数字;
将数字读入strValue;
}
truewill 2005-01-23
  • 打赏
  • 举报
回复
如果确定要n个小数,可以用整数来保存嘛
比如5.6
就存成56

16,465

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

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