2019-06-15 23:07

# vs2010 MFC 问一个关于浮点数小数点的处理

0.00077777->0
0.200000->0.2
2.00000->2
2.55555->2.55
1000.66666->1000.66
1999.00000->1999
->后面是最后想要的字符。

``````        CString strTemp，Section2
FLOAT XX=atof(strTemp);  //必须先转浮点数，用来计算。
strTemp.Format("%.2f",XX); //先转化成字符，截断，保留小数点后两位。
XX=atof(strTemp);    //再转化成浮点，因为浮点，这里不会小数点后两位。
Section2.Format("X=%g",XX);//这里好像四舍五入，再去掉零，最后得到想要的结果，
``````
• 写回答
• 好问题 提建议
• 关注问题
• 收藏
• 邀请回答

#### 3条回答默认 最新

• threenewbee 2019-06-16 09:25
已采纳
``````// Q766008.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "Q766008.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// The one and only application object

CWinApp theApp;

using namespace std;

void conv1(double d, int* a, int *b)
{
// int id = (int)(d * 100 + 0.5);如果要四舍五入，用这个
int id = (int)(d * 100);
*a = id / 100;
*b = id % 100;
}

void conv(double d, char * buffer)
{
int x;
int y;
conv1(d, &x, &y);
if (x == 0 && y == 0)
{
sprintf(buffer, "0");
}
else if (y == 0)
{
sprintf(buffer, "%d", x);
}
else if (y < 10)
{
sprintf(buffer, "%d.0%d", x, y);
}
else
{
if (y % 10 != 0)
sprintf(buffer, "%d.%d", x, y);
else
sprintf(buffer, "%d.%d", x, y / 10);
}

}

int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
int nRetCode = 0;

// initialize MFC and print and error on failure
if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
{
// TODO: change error code to suit your needs
cerr << _T("Fatal Error: MFC initialization failed") << endl;
nRetCode = 1;
}
else
{
// TODO: code your application's behavior here.
//CString strHello;
//strHello.LoadString(IDS_HELLO);
//cout << (LPCTSTR)strHello << endl;
double arr[] = { 0.00077777, 0.200000, 2.00000, 2.55555, 1000.66666, 1999.00000 };
for (int i = 0; i < 6; i++)
{
char buffer[100];
conv(arr[i], buffer);
CString str = (CString)buffer;
cout << (LPCTSTR)str << endl;
}

}

return nRetCode;
}

``````

0
0.2
2
2.55
1000.66
1999
Press any key to continue

本代码的限制：
转换的值必须是>=0
转换的值必须小于2100万。

可以保证在以上条件下满足你的需求

已采纳该答案
评论
解决 无用
打赏 举报
• Next66 2019-06-17 09:29

首先第一个你的做法是:
先将字符串转换成float,然后通过转换成字符串的方式获得保留2位小数后的字符串,最后将字符串再转化为float;
其实完全可以简化下:
先处理字符串,直接保留字符串小数量后的2位字符,然后再转换成float就行了

还有一个问题就是你怕Section2.Format("X=%g",XX)会以指数形式输出; 这个是不会的 因为你的范围是0-1999.99,具体参考https://blog.csdn.net/you_shou/article/details/51198615

我写了个测试代码了看下是否能用上吧,我用的是通过正则表达式去掉小数点后2位后的所有字符:

``````#include<iostream>
#include<regex>
int main(void){
std::string str = "1999.9957819";
std::regex pattern("(.*?\\.\\d{2})(.*?)\$");
str = std::regex_replace(str, pattern,"\$1");
std::cout << str << std::endl;
float ft = atof(str.c_str());
printf("%g",ft);
return 0;
}
``````

运行结果:

评论
解决 无用
打赏 举报
• dabocaiqq 2019-06-17 09:39

# 辛苦编写代码不容易，这个代码没有使用正则表达式，因此效率上可以保证，而且杜绝了不同平台正则表达式解析差异导致的程序结果不一致。是最完美的办法，请采纳一下，以后会多多回你的问题。

``````#include "stdio.h"
#include "string.h"

//将字符串转换为定点数，int存储定点数，pos存储定点数的模
void str2Dec(char* str, int* val, int* pos)
{
*val = 0;
*pos = 0;
for (int i = 0; i < strlen(str); i++)
{
if (str[i] == '.')
{
*pos = 1;
}
else
{
*val *= 10;
*val += (str[i] - '0');
if (*pos != 0) *pos *= 10;
}
}
if (*pos == 0) *pos = 1;
}

//这里借鉴下前面专家的代码
void conv(int x, int y, char * buffer)
{
if (x == 0 && y == 0)
{
sprintf(buffer, "0");
}
else if (y == 0)
{
sprintf(buffer, "%d", x);
}
else if (y < 10)
{
sprintf(buffer, "%d.0%d", x, y);
}
else
{
if (y % 10 != 0)
sprintf(buffer, "%d.%d", x, y);
else
sprintf(buffer, "%d.%d0", x, y / 10);
}

}

int main(int argc, char* argv[])
{
char * s = "1.123111";
char x[100];
int v, p;
str2Dec(s, &v, &p);
conv(v / p, (v * 100 / p) % 100, x);
printf("%s\n", x);

return 0;
}

``````

为什么说有一个人是回答错误
首先
regex不是所有编译器都支持

其次，regex在一些情况下造成内存泄漏，不能实现可靠的代码
最后，这个不用我说，lz自己测试下

``````#include <iostream>
#include <sstream>
#include <string>
#include<regex>

using namespace std;
template <class T>
std::string ConvertToString(T value) {
stringstream ss;
ss << value;
return ss.str();
}

int main(void){
for (int i = 0; i < 99999; i++)
{
std::string str = ConvertToString(i);
str = "0." + str;
std::regex pattern("(.*?\\.\\d{2})(.*?)\$");
str = std::regex_replace(str, pattern,"\$1");
std::cout << str << " ";
float ft = atof(str.c_str());
printf("%g\n",ft);
}
return 0;
}
``````

转换10万次，不是很多次吧，要多少时间，慢不慢？

评论
解决 无用
打赏 举报