不同数制之间的相互转换

不同数制之间的相互转换

import json
import os
import struct

import numpy
import numpy as np
import torch

def float32_to_fp8_binary(value, bias=7, E=4, M=3):
    """
    :param value: float32类型的值
    :param bias: fp8的偏移量
    :param E: fp8的指数位数
    :param M: fp8的尾数位数
    :return: fp8 binary format,such as: 1.34-->00111100
    """
    # 将float32转换为uint32
    float_as_uint32 = struct.unpack('>I', struct.pack('>f', value))[0]
    # 提取float32的符号位
    sign = ((float_as_uint32 >> 31) & 0x1)
    # 18.5: 0 10000011 00101000000000000000000
    # 提取float32的指数部分,并减去127(float32的偏移量),然后将指数转换为FP8所需的格式
    exponent = ((float_as_uint32 >> 23) & 0xFF) - 127

    # FP8有8位指数,所以需要裁剪指数
    if exponent > (2**E-1)-bias:
        exponent = (2**E-1)-bias
    elif exponent < -bias:
        exponent = -bias
    exponent += bias
    # 提取float32的小数部分,并根据需要进行舍入
    fraction = (float_as_uint32 & 0x700000)
    # 对小数部分进行裁剪和对齐,并最终合成FP8的表示
    sign = bin(sign)[2:]
    exponent = ('0' * 8 + bin(exponent)[2:])[-8:][-E:]
    fraction = ('0'* 23 + bin(fraction)[2:])[-23:][:M]
    fp8 = sign + exponent + fraction
    return fp8


def binary_to_hex(binary):
    """
    将二进制转换为十六进制
    :param binary: 00111100
    :return: 0X3C
    """
    num_dict = {"10": 'A', "11": 'B', "12": 'C', "13": 'D', "14": 'E', "15": 'F', }
    hex_str = ""
    for i in range(0, len(binary), 4):
        int_data = int(binary[i:i+4], 2)
        if int_data > 9:
            hex_str += num_dict[str(int_data)]
        else:
            hex_str += str(int_data)
    return hex_str

def float_to_hex(input):
    """
    将float转换为hex,需要用到numpy的 tolist() 函数,仅支持float64/32/16
    :param input:
    :return: (np.float16)0.35 --> '359A'   |   (np.float32)0.35 --> '3EB33333'
    """
    temp = hex(int.from_bytes(input.tobytes(), 'little')).upper().replace('0X', '')
    return temp

def uint16_to_float16(input):
    """
    将uint16转换为float32
    :param input:
    :return:
    """
    uint16 = bin(input)[2:]
    uint16 = ("0" * 16 + uint16)[-16:]
    sign = uint16[:1]
    fp16_exponent = uint16[1:6]
    fp16_fraction = uint16[6:]

    fp16_exp_bias = 15
    fp32_exp_bias = 127

    fp32_exponent = bin(int(fp16_exponent, 2) - fp16_exp_bias + fp32_exp_bias)[2:]
    fp32_exponent = ("0" * 8 + fp32_exponent)[-8:]
    fp32_fraction = fp16_fraction + "0" * 13
    fp32_binary = sign + fp32_exponent + fp32_fraction

    fp16_res = struct.unpack('<f', struct.pack('<I', int(fp32_binary, 2)))[0]
    return fp16_res


if __name__ == '__main__':
    res = binary_to_hex('00111100')
    print(res)
    res = float_to_hex(np.array([1.23456789], dtype=np.float32))
    print(res)
    res = float32_to_fp8_binary(1.23456789)
    print(res)
    res = uint16_to_float16(15744)
    print(res)

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lookaroundd

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值