1. 问题引出

最近遇到了一个小问题,即:

读取文本文件的内容,然后将文件中出现的数字(包括double, int, float等)转化为16进制0x存储

原本以为非常简单的内容,然后就着手去写了python,但是写着写着发现不对:

python貌似没办法直接读取内存数据;

因此不得不借助于C语言,这样又引出了python如何调用C lib

开始写c发现又有问题了:

int 类型的数据和float/double数据在内存中的存储方式是不同的

因此花了一些力气解决了这些问题,成功得将数字转化为了16进制0x的存储类型,特记录一下,以备后续查询,也可以让有需要的童鞋有个参考。

2. 基本知识

完成本实验前,你必须具备以下的基础知识:

1). float/double在内存中的存储方式

浮点数在内存中的存储形式为二进制的科学计数法,即





其中,S为符号,P为阶码,F为尾数

其长度如下表所示:

总长度 符号 阶码 尾数
float 32 bit 1 8 23
double 64 bit 1 11 52

> **符号位 S:** 0代表正数,1代表负数
> **阶码位 P:** 为unsigned, 计算时候,需要将实际尾数减去`7F`, 即实际计算用的`P=eb-0x7F`
> **尾数位 F:** 用二进制科学计算法表示后,去掉前面的恒定`1`,只保留小数点后的二进制数据

例1:32bit二进制 0x42 0xOA 0x1A 0xA0 转化为十进制浮点数

符号位:S=0,0x42的最高位为0

阶码位:0x42<<1=0x84, 0x84-0x7F = 5

尾数位:0x0A1AA0为换算为十进制然后小数点前加1得到1.0789375

计算:1.0789375*2^5 = 34.526

例2:将十进制数50.265转化为32位规格化的浮点数

N = 50.265

S = 0

N/2^P = 1.xxx, 因此,P=5

F=N/2^P=50.265/32=1.57078125

由以上可知:

符号位S=0

eb = P+0x7F=0x84

尾数d[2]d[1]d[0]= 0x490F5C

因此,最终结果为:0x42490F5C (记住eb需要移位哦)

2). python如何调用C lib

简单起见,可参考该博客:http://blog.csdn.net/golden1314521/article/details/44055523

详细内容可参考python官方文档:https://docs.python.org/2/library/ctypes.html

3. 代码

I. C 代码:读取float所在的内存地址

  1. /*
  2. *Filename: ftoc.c
  3. */
  4. #define uchar unsigned char
  5. #define uint unsigned int
  6. void ftoc(float fl, uchar arr[])
  7. {
  8. void *pf;
  9. pf = &fl;
  10. uchar i;
  11. for(i=0; i<4; i++)
  12. {
  13. arr[i] = *((uchar *)pf+i);
  14. }
  15. return ;
  16. }

II. 编译此代码为libftoc.so

  1. gcc -shared -Wl,-soname,libftoc -o libftoc.so -fPIC ftoc.c
  • shared: 表示需要编译为动态库(.so)
  • Wl: 告诉编译器将后面的参数传递给链接器
  • soname: 指定了动态库的soname(简单共享名,Short for shared object name)

更加详细的介绍可参考:http://blog.csdn.net/zhoujiaxq/article/details/10213655

  • o : output,即要编译成目标文件的名字
  • fPIC: 地址无关代码(.so必须加此参数),详情可自行搜索

III. python 代码

  1. #!/usr/bin/python
  2. import os
  3. import ctypes
  4. lib_name = './libftoc.so' #我自己的 c lib
  5. filename = "rd.txt"
  6. f1 = open(filename, 'r')
  7. f2 = open('result.txt', 'w+')
  8. #-----------------------------------
  9. #check the number is float or not
  10. def is_float(s):
  11. try:
  12. float(s)
  13. return True
  14. except ValueError:
  15. pass
  16. #-----------------------------------
  17. def ftoc(num):
  18. number = ctypes.c_float(num) #covert the python type to c type
  19. arr = ctypes.c_ubyte * 4
  20. parr = arr(ctypes.c_ubyte(), ctypes.c_ubyte(), ctypes.c_ubyte(), ctypes.c_ubyte()) #create a c-type(unsigned char) array
  21. #access the c lib
  22. lib_ftoc = ctypes.CDLL(lib_name)
  23. #call the c lib function!!!
  24. #after this function, parr contains float's dec_number*4
  25. lib_ftoc.ftoc(ctypes.c_float(num), parr)
  26. lst=[]
  27. for i in range(4):
  28. lst.append(parr[i])
  29. lst[i] = hex(lst[i])[2:] #get rid of '0x'
  30. if(len(lst[i]) < 2):
  31. lst[i] = '0'+lst[i] #make data 8-bit
  32. string = lst[3]+lst[2]+lst[1]+lst[0]
  33. string = string.upper() #uppercase the characters
  34. return string
  35. #============================================
  36. # main flow
  37. #===========================================
  38. lst = []
  39. line = f1.readline()
  40. while line:
  41. line.strip('\n')
  42. lst = line.split()
  43. for i in range(len(lst)):
  44. #if the number is digit
  45. if lst[i].isdigit():
  46. lst[i] = hex(int(lst[i]))
  47. lst[i] = lst[i][2:] #get rid of '0x'
  48. lst[i] = lst[i].upper()
  49. if(len(lst[i]) < 8):
  50. lst[i] = '0'*(8-len(lst[i])) + lst[i]
  51. #if the number is float
  52. else:
  53. if is_float(lst[i]):
  54. lst[i] = ftoc(float(lst[i]))
  55. for i in range(len(lst)):
  56. f2.write(lst[i])
  57. f2.write(' ')
  58. f2.write('\n')
  59. line = f1.readline()
  60. f2.write('\n')
  61. f1.close()
  62. f2.close()

VI. 运行结果


运行前的文档:




运行后的结果输出:

python实现float/double的0x转化的更多相关文章

  1. Python之☞float浮点数精度问题

    Python的浮点数损失精度问题(转) 一个简单的面试题: >>>0.1+0.1+0.1 0.2 >>>0.1+0.1+0.1 0.3000000000000000 ...

  2. QT中QString 与 int float double 等类型的相互转换

    Qt中 int ,float ,double转换为QString 有两种方法 1.使用 QString::number(); 如: long a = 63; QString s = QString:: ...

  3. 关于c中 int, float, double转换中存在的精度损失问题

    先看一段代码实验: #include<limits> #include<iostream> using namespace std; int main() { unsigned ...

  4. C语言中float,double类型,在内存中的结构(存储方式)

    C语言中float,double类型,在内存中的结构(存储方式)从存储结构和算法上来讲,double和float是一样的,不一样的地方仅仅是float是32位的,double是64位的,所以doubl ...

  5. C++中将string类型转换为int, float, double类型 主要通过以下几种方式:

      C++中将string类型转换为int, float, double类型 主要通过以下几种方式: # 方法一: 使用stringstream stringstream在int或float类型转换为 ...

  6. MySQL中Decimal类型和Float Double的区别 & BigDecimal与Double使用场景

    MySQL中存在float,double等非标准数据类型,也有decimal这种标准数据类型. 其区别在于,float,double等非标准类型,在DB中保存的是近似值,而Decimal则以字符串的形 ...

  7. MySQL中 DECIMAL FLOAT DOUBLE的区别

    第一篇文章: MySQL中Decimal类型和Float Double等区别 MySQL中存在float,double等非标准数据类型,也有decimal这种标准数据类型. 其区别在于,float,d ...

  8. 数据库类型空间效率探索(五)- decimal/float/double/varchar

    以下测试为userinfo增加一列,列类型分别为decimal.float.double.varchar.由于innodb不支持optimize,所以每次测试,都会删除表test.userinfo,重 ...

  9. MySQL中Decimal类型和Float Double等区别

    MySQL中存在float,double等非标准数据类型,也有decimal这种标准数据类型. 其区别在于,float,double等非标准类型,在DB中保存的是近似值,而Decimal则以字符串的形 ...

随机推荐

  1. 阿里巴巴集团2013实习生招聘技术类笔试卷(B)

    一.单选题 1.在常用的网络协议中,___是面向连接的.有重传功能的协议. A.IP   B.TCP    C.UDP    D.DXP 2.500张多米诺骨牌整齐地排成一列,依顺序编号为1.2.3… ...

  2. linux系统编程之文件与IO(一):文件描述符、open,close

    什么是IO? 输入/输出是主存和外部设备之间拷贝数据的过程 设备->内存(输入操作) 内存->设备(输出操作) 高级I/O ANSI C提供的标准I/O库称为高级I/O,通常也称为带缓冲的 ...

  3. C# 创建、部署和调用WebService简单示例

    webservice 可以用于分布式应用程序之间的交互,和不同程序之间的交互. 概念性的东西就不说太多,下面开始创建一个简单的webservice的例子.这里我用的是Visual Studio 201 ...

  4. ASP.NET Core 2 学习笔记(七)路由

    ASP.NET Core通过路由(Routing)设定,将定义的URL规则找到相对应行为:当使用者Request的URL满足特定规则条件时,则自动对应到相符合的行为处理.从ASP.NET就已经存在的架 ...

  5. C# 对象引擎,以路径形式访问对象属性(data.Product[1].Name)

    对象引擎,以路径形式访问对象属性,例data.Product[1].Name. 在做excel模板引擎的时候,为了能方便的调用对象属性,找了一些模板引擎,不是太大就是不太适用于excel, 因为exc ...

  6. 微信小程序开发教程(一)—介绍和准备

    前言: 因为客户需要,也为了更好的发展我们公司的产品,所以决定扩展移动端.但是由于公司没有原生安卓开发人员,而且开发安卓成本比较高,所以公司一致决定开发微信小程序,也是由于微信小程序最近的火热. 后台 ...

  7. 使用JQuery插件Jcrop进行图片截取

    Jcrop插件本身并不含有图片截取功能,它仅仅是在前端层面构建一套截取动画效果并产生4个坐标点,插件使用者将这4个坐标点传回至服务器接口上进行截取操作.其优点是具有较高的通用性.浏览器兼容性(IE6+ ...

  8. NGINX部署配置参考.

    请求动态页面 1. uwsgi.ini配置文件.(主从负载uwsgi1.) 2. uwsgi2 的配置文件 3.查看. 4.结构图 5.配置 NGINX服务器  定义上游有哪些服务器. 定义转交给up ...

  9. 如何在Qt资源文件中包含和释放exe等各种类型文件?

    操作系统:Windows 10 X64 企业版 Qt: 5.8.0 QtCreater: 4.2.1 刚刚开始学习Qt,不断遇到困难和挑战,前几天在各个QQ群里询问如何在Qt的资源文件中包含和释放ex ...

  10. [Swift实际操作]七、常见概念-(9)使用定时组件Timer执行定时任务

    本文将为你演示计时器的使用,使用计时器可以每隔一定时间执行某个函数. 在左侧的项目导航区,打开视图控制器的代码文件:ViewController.swift现在开始编写代码,实现任务定时的功能.定义一 ...