当前位置: 首页 > news >正文

float在python中的书写形式错误的是_python实现float/double的0x转化

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

3. 代码

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

/*

*Filename: ftoc.c

*/

#define uchar unsigned char

#define uint unsigned int

void ftoc(float fl, uchar arr[])

{

void *pf;

pf = &fl;

uchar i;

for(i=0; i<4; i++)

{

arr[i] = *((uchar *)pf+i);

}

return ;

}

II. 编译此代码为libftoc.so

gcc -shared -Wl,-soname,libftoc -o libftoc.so -fPIC ftoc.c

shared: 表示需要编译为动态库(.so)

Wl: 告诉编译器将后面的参数传递给链接器

soname: 指定了动态库的soname(简单共享名,Short for shared object name)

o : output,即要编译成目标文件的名字

fPIC: 地址无关代码(.so必须加此参数),详情可自行搜索

III. python 代码

#!/usr/bin/python

import os

import ctypes

lib_name = './libftoc.so' #我自己的 c lib

filename = "rd.txt"

f1 = open(filename, 'r')

f2 = open('result.txt', 'w+')

#-----------------------------------

#check the number is float or not

def is_float(s):

try:

float(s)

return True

except ValueError:

pass

#-----------------------------------

def ftoc(num):

number = ctypes.c_float(num) #covert the python type to c type

arr = ctypes.c_ubyte * 4

parr = arr(ctypes.c_ubyte(), ctypes.c_ubyte(), ctypes.c_ubyte(), ctypes.c_ubyte()) #create a c-type(unsigned char) array

#access the c lib

lib_ftoc = ctypes.CDLL(lib_name)

#call the c lib function!!!

#after this function, parr contains float's dec_number*4

lib_ftoc.ftoc(ctypes.c_float(num), parr)

lst=[]

for i in range(4):

lst.append(parr[i])

lst[i] = hex(lst[i])[2:] #get rid of '0x'

if(len(lst[i]) < 2):

lst[i] = '0'+lst[i] #make data 8-bit

string = lst[3]+lst[2]+lst[1]+lst[0]

string = string.upper() #uppercase the characters

return string

#============================================

# main flow

#===========================================

lst = []

line = f1.readline()

while line:

line.strip('\n')

lst = line.split()

for i in range(len(lst)):

#if the number is digit

if lst[i].isdigit():

lst[i] = hex(int(lst[i]))

lst[i] = lst[i][2:] #get rid of '0x'

lst[i] = lst[i].upper()

if(len(lst[i]) < 8):

lst[i] = '0'*(8-len(lst[i])) + lst[i]

#if the number is float

else:

if is_float(lst[i]):

lst[i] = ftoc(float(lst[i]))

for i in range(len(lst)):

f2.write(lst[i])

f2.write(' ')

f2.write('\n')

line = f1.readline()

f2.write('\n')

f1.close()

f2.close()

VI. 运行结果

运行前的文档:

运行后的结果输出:

相关文章:

  • angular js 使用pdf.js_【新年跳槽必备】2020最新(前端Angular.Js专题)面试题 速领!...
  • 使用dbutils
  • idea怎么运行jsp页面_【学习笔记】Jsp与Servlet技术
  • 获取js渲染后的html_关键渲染路径
  • python merge on多个条件_Python数据核对系列之2—power query VS pandas
  • C语言使用递归法计算n的阶乘
  • python解释器与编译环境_python入门之解释器环境安装
  • HDU 1299 基础数论 分解
  • simpledateformat格式_2020 年,你还在使用 Java 中的 SimpleDateFormat 吗?
  • 人生苦短我学python谁说的_人生苦短,我学python
  • [PY3]——logging
  • python笔记视频_python视频笔记之三(循环和函数)
  • 洛谷P3003 [USACO10DEC]苹果交货Apple Delivery
  • linux添加ip白名单_为什么IP代理需要授权?
  • 事件对象练习
  • [PHP内核探索]PHP中的哈希表
  • JS 中的深拷贝与浅拷贝
  • canvas 绘制双线技巧
  • CSS 三角实现
  • HashMap ConcurrentHashMap
  • IDEA 插件开发入门教程
  • Java知识点总结(JDBC-连接步骤及CRUD)
  • Map集合、散列表、红黑树介绍
  • passportjs 源码分析
  • python 学习笔记 - Queue Pipes,进程间通讯
  • rc-form之最单纯情况
  • springMvc学习笔记(2)
  • thinkphp5.1 easywechat4 微信第三方开放平台
  • Web标准制定过程
  • 阿里研究院入选中国企业智库系统影响力榜
  • 聚类分析——Kmeans
  • 看完九篇字体系列的文章,你还觉得我是在说字体?
  • 如何解决微信端直接跳WAP端
  • 手写一个CommonJS打包工具(一)
  • 算法---两个栈实现一个队列
  • 微信小程序设置上一页数据
  • 我从编程教室毕业
  • 移动端解决方案学习记录
  • 用element的upload组件实现多图片上传和压缩
  • 你对linux中grep命令知道多少?
  • 说说我为什么看好Spring Cloud Alibaba
  • ​MySQL主从复制一致性检测
  • ​渐进式Web应用PWA的未来
  • (iPhone/iPad开发)在UIWebView中自定义菜单栏
  • (ZT)一个美国文科博士的YardLife
  • (附源码)springboot“微印象”在线打印预约系统 毕业设计 061642
  • (十五)使用Nexus创建Maven私服
  • (原創) 物件導向與老子思想 (OO)
  • (转)总结使用Unity 3D优化游戏运行性能的经验
  • .360、.halo勒索病毒的最新威胁:如何恢复您的数据?
  • .bat文件调用java类的main方法
  • .NET Core SkiaSharp 替代 System.Drawing.Common 的一些用法
  • .NET 除了用 Task 之外,如何自己写一个可以 await 的对象?
  • .net6使用Sejil可视化日志
  • .net反编译工具