小工具 - 浮点计算器

概述

在学习CE, 在调试过程中, 经常要看内存中浮点对应的4字节内存到底对应的是啥具体的浮点值. e.g. 0x42860000 => 67.00
转换逻辑挺简单的

float CFloatCalcDlg::uint32_to_float(uint32_t u)
{
	return (*(float*)&u);
}

开始写了一个测试程序, 直接改4字节的值, 编译运行一下, 看打印出的结果.
但是要经常看内存中的4字节数据对应的浮点值, 不胜其烦.
花了半天, 写了一个小工具, 方便多了.
在这里插入图片描述

笔记

编程环境 : vs2019 mfc dlg

FloatCalcDlg.cpp


// FloatCalcDlg.cpp: 实现文件
//

#include "pch.h"
#include "framework.h"
#include "FloatCalc.h"
#include "FloatCalcDlg.h"
#include "afxdialogex.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// 用于应用程序“关于”菜单项的 CAboutDlg 对话框

class CAboutDlg : public CDialogEx
{
public:
	CAboutDlg();

// 对话框数据
#ifdef AFX_DESIGN_TIME
	enum { IDD = IDD_ABOUTBOX };
#endif

	protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持

// 实现
protected:
	DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialogEx(IDD_ABOUTBOX)
{
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
END_MESSAGE_MAP()


// CFloatCalcDlg 对话框



CFloatCalcDlg::CFloatCalcDlg(CWnd* pParent /*=nullptr*/)
	: CDialogEx(IDD_FLOATCALC_DIALOG, pParent)
	, m_cs4ByteIn(_T(""))
	, m_cs4ByteOut(_T(""))
	, m_csFloatIn(_T(""))
	, m_csFloatOut(_T(""))
{
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CFloatCalcDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_EDIT_TIP, m_ctrlTip);
	DDX_Text(pDX, IDC_EDIT_4BYTES_IN, m_cs4ByteIn);
	DDX_Text(pDX, IDC_EDIT_4BYTES_OUT, m_cs4ByteOut);
	DDX_Text(pDX, IDC_EDIT_FLOAT_IN, m_csFloatIn);
	DDX_Text(pDX, IDC_EDIT_FLOAT_OUT, m_csFloatOut);
}

BEGIN_MESSAGE_MAP(CFloatCalcDlg, CDialogEx)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(IDOK, &CFloatCalcDlg::OnBnClickedOk)
	ON_BN_CLICKED(IDCANCEL, &CFloatCalcDlg::OnBnClickedCancel)
	ON_WM_CLOSE()
	ON_BN_CLICKED(IDC_BUTTON_FLOAT_TO_4BYTES, &CFloatCalcDlg::OnBnClickedButtonFloatTo4bytes)
	ON_BN_CLICKED(IDC_BUTTON_4BYTES_TO_FLOAT, &CFloatCalcDlg::OnBnClickedButton4bytesToFloat)
END_MESSAGE_MAP()


// CFloatCalcDlg 消息处理程序

BOOL CFloatCalcDlg::OnInitDialog()
{
	CDialogEx::OnInitDialog();

	// 将“关于...”菜单项添加到系统菜单中。

	// IDM_ABOUTBOX 必须在系统命令范围内。
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);

	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != nullptr)
	{
		BOOL bNameValid;
		CString strAboutMenu;
		bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
		ASSERT(bNameValid);
		if (!strAboutMenu.IsEmpty())
		{
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
	}

	// 设置此对话框的图标。  当应用程序主窗口不是对话框时,框架将自动
	//  执行此操作
	SetIcon(m_hIcon, TRUE);			// 设置大图标
	SetIcon(m_hIcon, FALSE);		// 设置小图标

	// TODO: 在此添加额外的初始化代码
	this->SetWindowTextW(TEXT("浮点计算器"));

	addMsg(TEXT("功能:\r\n"));
	addMsg(TEXT("1. 输入浮点数, 转换成4字节\r\n"));
	addMsg(TEXT("2. 输入4字节, 转换成浮点数\r\n"));

	// for test
	this->m_csFloatIn = TEXT("121");
	this->m_cs4ByteIn = TEXT("0x42F20000");
	this->UpdateData(FALSE);

	return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
}

void CFloatCalcDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
	{
		CAboutDlg dlgAbout;
		dlgAbout.DoModal();
	}
	else
	{
		CDialogEx::OnSysCommand(nID, lParam);
	}
}

// 如果向对话框添加最小化按钮,则需要下面的代码
//  来绘制该图标。  对于使用文档/视图模型的 MFC 应用程序,
//  这将由框架自动完成。

void CFloatCalcDlg::OnPaint()
{
	if (IsIconic())
	{
		CPaintDC dc(this); // 用于绘制的设备上下文

		SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

		// 使图标在工作区矩形中居中
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// 绘制图标
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialogEx::OnPaint();
	}
}

//当用户拖动最小化窗口时系统调用此函数取得光标
//显示。
HCURSOR CFloatCalcDlg::OnQueryDragIcon()
{
	return static_cast<HCURSOR>(m_hIcon);
}



void CFloatCalcDlg::OnBnClickedOk()
{
	CWnd* pWnd = GetFocus();
	if (GetDlgItem(IDOK) == pWnd)
	{
		// 取消默认的回车处理
		CDialogEx::OnOK();
		return;
	}
}


void CFloatCalcDlg::OnBnClickedCancel()
{
	CWnd* pWnd = GetFocus();
	if (GetDlgItem(IDCANCEL) == pWnd)
	{
		// 取消摩恩的ESC键处理
		CDialogEx::OnCancel();
		return;
	}
}


void CFloatCalcDlg::OnClose()
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	CDialog::OnOK();
	CDialogEx::OnClose();
}

void CFloatCalcDlg::addMsg(const TCHAR* pcMsg)
{
	do {
		if (NULL == pcMsg)
		{
			break;
		}

		if (_tcslen(pcMsg) > 0)
		{
			m_ctrlTip.SetSel(-1, -1, TRUE);
			m_ctrlTip.ReplaceSel(pcMsg);
		}
		else {
			// 如果给的文本为空字符串, 就说明要清空消息
			m_ctrlTip.SetSel(0, -1, TRUE);
			m_ctrlTip.ReplaceSel(TEXT(""));
		}

		// 加一个回车
		m_ctrlTip.SetSel(-1, -1, TRUE);
		m_ctrlTip.ReplaceSel(TEXT("\r\n"));

	} while (false);
}

void CFloatCalcDlg::OnBnClickedButtonFloatTo4bytes()
{
	byte ary[4];
	CString cs;
	CString csTmp;

	this->UpdateData(TRUE);
	addMsg(TEXT(""));
	addMsg(TEXT("浮点数转4字节"));

	float f = (float)_ttof(m_csFloatIn);
	uint32_t u = *(uint32_t*)&f;

	uint32_to_4byte(u, ary, 4);
	cs.Format(TEXT("0x%.2X%.2X%.2X%.2X"), ary[0], ary[1], ary[2], ary[3]);

	this->m_cs4ByteOut = cs;

	csTmp.Format(TEXT("%.2f to %s\r\n"), f, cs);
	addMsg(csTmp);

	this->UpdateData(FALSE);
}

void CFloatCalcDlg::uint32_to_4byte(uint32_t u, byte* ary, int aryLen)
{
	_ASSERT(NULL != ary);
	_ASSERT(aryLen >= 4);

	ary[0] = (byte)((u >> (8 * 3)) & 0xff);
	ary[1] = (byte)((u >> (8 * 2)) & 0xff);
	ary[2] = (byte)((u >> (8 * 1)) & 0xff);
	ary[3] = (byte)((u >> (8 * 0)) & 0xff);
}


void CFloatCalcDlg::OnBnClickedButton4bytesToFloat()
{
	CString cs;
	CString csTmp;
	uint32_t u;

	this->UpdateData(TRUE);
	addMsg(TEXT(""));
	addMsg(TEXT("4字节转浮点数"));

	cs = this->m_cs4ByteIn;
	cs.MakeUpper();

	if (cs.GetLength() >= 2)
	{
		if ((TEXT('0') == cs[0]) && ((TEXT('X') == cs[1])))
		{
			cs = cs.Right(cs.GetLength() - 2);
		}
	}

	do {
		// 12345678
		if (cs.GetLength() > 8)
		{
			addMsg(TEXT("err : 4字节最多8个16进制字符"));
			break;
		}

		if (!IsHexPsz((LPCTSTR)cs))
		{
			addMsg(TEXT("err : 请输入16进制字符串"));
			break;
		}

		while (cs.GetLength() < 8)
		{
			cs = _T("0") + cs;
		}

		Hex8CharToUint32((LPCTSTR)cs, u);
		this->m_csFloatOut.Format(TEXT("%.2f"), uint32_to_float(u));
		
		csTmp.Format(TEXT("%s to %s\r\n"), m_cs4ByteIn, this->m_csFloatOut);
		addMsg(csTmp);
	} while (false);

	this->UpdateData(FALSE);
}

float CFloatCalcDlg::uint32_to_float(uint32_t u)
{
	return (*(float*)&u);
}

void CFloatCalcDlg::Hex8CharToUint32(const TCHAR* pszHex8, uint32_t& u)
{
	unsigned char uc1;
	unsigned char uc2;

	_ASSERT(NULL != pszHex8);
	_ASSERT(8 == _tcslen(pszHex8));

	_ASSERT(NULL != pszHex8);
	_ASSERT(8 == _tcslen(pszHex8));

	uc1 = OneHexChar2UChar(pszHex8[0]);
	uc2 = OneHexChar2UChar(pszHex8[1]);
	
	u = uc1;
	u <<= 4;
	u += uc2;
	u <<= 4;

	uc1 = OneHexChar2UChar(pszHex8[2]);
	uc2 = OneHexChar2UChar(pszHex8[3]);

	u += uc1;
	u <<= 4;
	u += uc2;
	u <<= 4;

	uc1 = OneHexChar2UChar(pszHex8[4]);
	uc2 = OneHexChar2UChar(pszHex8[5]);

	u += uc1;
	u <<= 4;
	u += uc2;
	u <<= 4;

	uc1 = OneHexChar2UChar(pszHex8[6]);
	uc2 = OneHexChar2UChar(pszHex8[7]);

	u += uc1;
	u <<= 4;
	u += uc2;
}

unsigned char CFloatCalcDlg::OneHexChar2UChar(TCHAR c)
{
	unsigned char uc = 0;
	_ASSERT(((c >= TEXT('0')) && (c <= TEXT('9'))) || ((c >= TEXT('A')) && (c <= TEXT('F'))));

	if ((c >= TEXT('0')) && (c <= TEXT('9')))
	{
		uc = (unsigned char)(c - TEXT('0'));
	}
	else if ((c >= TEXT('A')) && (c <= TEXT('F')))
	{
		uc = (unsigned char)(c - TEXT('A') + 10);
	}

	return uc;
}

bool CFloatCalcDlg::IsHexPsz(const TCHAR* psz)
{
	int i = 0;
	TCHAR c = 0;
	bool b_ok = true;
	_ASSERT(NULL != psz);

	for (i = 0; i < (int)_tcslen(psz); i++)
	{
		c = psz[i];
		if (((c >= TEXT('0')) && (c <= TEXT('9'))) || (c >= TEXT('A')) && (c <= TEXT('F')))
		{

		}
		else {
			b_ok = false;
			break;
		}
	}

	return b_ok;
}

FloatCalcDlg.h


// FloatCalcDlg.h: 头文件
//

#pragma once


// CFloatCalcDlg 对话框
class CFloatCalcDlg : public CDialogEx
{
// 构造
public:
	CFloatCalcDlg(CWnd* pParent = nullptr);	// 标准构造函数

// 对话框数据
#ifdef AFX_DESIGN_TIME
	enum { IDD = IDD_FLOATCALC_DIALOG };
#endif

	protected:
	virtual void DoDataExchange(CDataExchange* pDX);	// DDX/DDV 支持


// 实现
protected:
	HICON m_hIcon;

	// 生成的消息映射函数
	virtual BOOL OnInitDialog();
	afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
	afx_msg void OnPaint();
	afx_msg HCURSOR OnQueryDragIcon();
	DECLARE_MESSAGE_MAP()
public:
	afx_msg void OnBnClickedOk();
	afx_msg void OnBnClickedCancel();
	afx_msg void OnClose();


private:
	void addMsg(const TCHAR* pcMsg);
	void uint32_to_4byte(uint32_t u, byte* ary, int aryLen);
	void Hex8CharToUint32(const TCHAR* pszHex8, uint32_t& u);
	bool IsHexPsz(const TCHAR* psz);
	unsigned char OneHexChar2UChar(TCHAR c);
	float uint32_to_float(uint32_t u);

public:
	CEdit m_ctrlTip;
	afx_msg void OnBnClickedButtonFloatTo4bytes();
	afx_msg void OnBnClickedButton4bytesToFloat();
	CString m_cs4ByteIn;
	CString m_cs4ByteOut;
	CString m_csFloatIn;
	CString m_csFloatOut;
};

rc

// Microsoft Visual C++ generated resource script.
//
#include "resource.h"

#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#ifndef APSTUDIO_INVOKED
#include "targetver.h"
#endif
#include "afxres.h"
#include "verrsrc.h"

/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS

/////////////////////////////////////////////////////////////////////////////
// 中文(简体,中国) resources

#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS)
LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED

#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//

1 TEXTINCLUDE 
BEGIN
    "resource.h\0"
END

2 TEXTINCLUDE 
BEGIN
    "#ifndef APSTUDIO_INVOKED\r\n"
    "#include ""targetver.h""\r\n"
    "#endif\r\n"
    "#include ""afxres.h""\r\n"
    "#include ""verrsrc.h""\r\n"
    "\0"
END

3 TEXTINCLUDE 
BEGIN
    "#define _AFX_NO_SPLITTER_RESOURCES\r\n"
    "#define _AFX_NO_OLE_RESOURCES\r\n"
    "#define _AFX_NO_TRACKER_RESOURCES\r\n"
    "#define _AFX_NO_PROPERTY_RESOURCES\r\n"
    "\r\n"
    "#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS)\r\n"
    "LANGUAGE 4, 2\r\n"
    "#include ""res\\FloatCalc.rc2""  // 非 Microsoft Visual C++ 编辑的资源\r\n"
    "#include ""l.CHS\\afxres.rc""      // 标准组件\r\n"
    "#if !defined(_AFXDLL)\r\n"
    "#include ""l.CHS\\afxribbon.rc""   // MFC 功能区和控制条资源\r\n"
    "#endif\r\n"
    "#endif\r\n"
    "\0"
END

#endif    // APSTUDIO_INVOKED


/////////////////////////////////////////////////////////////////////////////
//
// Icon
//

// Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems.
IDR_MAINFRAME           ICON                    "res\\FloatCalc.ico"


/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//

IDD_ABOUTBOX DIALOGEX 0, 0, 170, 62
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "关于 FloatCalc"
FONT 9, "MS Shell Dlg", 0, 0, 0x1
BEGIN
    ICON            IDR_MAINFRAME,IDC_STATIC,14,14,21,20
    LTEXT           "FloatCalc,版本 1.0",IDC_STATIC,42,14,114,8,SS_NOPREFIX
    LTEXT           "版权所有 (C) 2024",IDC_STATIC,42,26,114,8
    DEFPUSHBUTTON   "确定",IDOK,113,41,50,14,WS_GROUP
END

IDD_FLOATCALC_DIALOG DIALOGEX 0, 0, 295, 131
STYLE DS_SETFONT | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME
EXSTYLE WS_EX_APPWINDOW
FONT 9, "MS Shell Dlg", 0, 0, 0x1
BEGIN
    CTEXT           "转换之前",IDC_STATIC,78,7,65,14,SS_CENTERIMAGE
    CTEXT           "转换之后",IDC_STATIC,149,7,65,14,SS_CENTERIMAGE
    CTEXT           "输入为浮点数",IDC_STATIC,7,29,65,14,SS_CENTERIMAGE
    EDITTEXT        IDC_EDIT_FLOAT_IN,78,29,65,14,ES_AUTOHSCROLL
    EDITTEXT        IDC_EDIT_4BYTES_OUT,149,29,65,14,ES_AUTOHSCROLL | ES_READONLY
    PUSHBUTTON      "浮点数转4字节",IDC_BUTTON_FLOAT_TO_4BYTES,222,29,65,14,BS_CENTER | BS_VCENTER
    CTEXT           "输入为4字节",IDC_STATIC,7,49,65,14,SS_CENTERIMAGE
    EDITTEXT        IDC_EDIT_4BYTES_IN,78,49,65,14,ES_AUTOHSCROLL
    EDITTEXT        IDC_EDIT_FLOAT_OUT,149,49,65,14,ES_AUTOHSCROLL | ES_READONLY
    PUSHBUTTON      "4字节转浮点数",IDC_BUTTON_4BYTES_TO_FLOAT,222,49,65,14,BS_CENTER | BS_VCENTER
    EDITTEXT        IDC_EDIT_TIP,7,69,281,55,ES_MULTILINE | ES_AUTOHSCROLL | ES_READONLY | ES_WANTRETURN
END


/////////////////////////////////////////////////////////////////////////////
//
// Version
//

VS_VERSION_INFO VERSIONINFO
 FILEVERSION 1,0,0,1
 PRODUCTVERSION 1,0,0,1
 FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
 FILEFLAGS 0x1L
#else
 FILEFLAGS 0x0L
#endif
 FILEOS 0x40004L
 FILETYPE 0x1L
 FILESUBTYPE 0x0L
BEGIN
    BLOCK "StringFileInfo"
    BEGIN
        BLOCK "080404B0"
        BEGIN
            VALUE "CompanyName", "TODO: <公司名>"
            VALUE "FileDescription", "FloatCalc"
            VALUE "FileVersion", "1.0.0.1"
            VALUE "InternalName", "FloatCalc.exe"
            VALUE "LegalCopyright", "TODO:  (C) <公司名>。  保留所有权利。"
            VALUE "OriginalFilename", "FloatCalc.exe"
            VALUE "ProductName", "TODO: <产品名>"
            VALUE "ProductVersion", "1.0.0.1"
        END
    END
    BLOCK "VarFileInfo"
    BEGIN
        VALUE "Translation", 0x804, 1200
    END
END


/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
//

#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO
BEGIN
    IDD_ABOUTBOX, DIALOG
    BEGIN
        LEFTMARGIN, 7
        RIGHTMARGIN, 163
        TOPMARGIN, 7
        BOTTOMMARGIN, 55
    END

    IDD_FLOATCALC_DIALOG, DIALOG
    BEGIN
        LEFTMARGIN, 7
        RIGHTMARGIN, 288
        VERTGUIDE, 78
        VERTGUIDE, 149
        VERTGUIDE, 222
        TOPMARGIN, 7
        BOTTOMMARGIN, 124
        HORZGUIDE, 29
        HORZGUIDE, 49
        HORZGUIDE, 69
    END
END
#endif    // APSTUDIO_INVOKED


/////////////////////////////////////////////////////////////////////////////
//
// AFX_DIALOG_LAYOUT
//

IDD_FLOATCALC_DIALOG AFX_DIALOG_LAYOUT
BEGIN
    0
END


/////////////////////////////////////////////////////////////////////////////
//
// String Table
//

STRINGTABLE
BEGIN
    IDS_ABOUTBOX            "关于 FloatCalc(&A)..."
END

#endif    // 中文(简体,中国) resources
/////////////////////////////////////////////////////////////////////////////



#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
#define _AFX_NO_SPLITTER_RESOURCES
#define _AFX_NO_OLE_RESOURCES
#define _AFX_NO_TRACKER_RESOURCES
#define _AFX_NO_PROPERTY_RESOURCES

#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS)
LANGUAGE 4, 2
#include "res\FloatCalc.rc2"  // 非 Microsoft Visual C++ 编辑的资源
#include "l.CHS\afxres.rc"      // 标准组件
#if !defined(_AFXDLL)
#include "l.CHS\afxribbon.rc"   // MFC 功能区和控制条资源
#endif
#endif

/////////////////////////////////////////////////////////////////////////////
#endif    // not APSTUDIO_INVOKED


END

Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐