尝试用float32运算器实现二个大数的加法

news2024/9/20 0:59:56

尝试用float32运算器实现二个大数的加法

本文尝试用float32运算器实现二个大数的加法。先试图训练一个conv的kernel来实现,不能收敛;最后用float32的向量操作来实现

import numpy as np
import struct
import torch.nn as nn
import torch
import torch.optim as optim

def gen_rand_value(sz):
    return int(''.join('{:d}'.format(np.random.randint(0,10)) for _ in range(sz)))

def to_numpy_array(value,max_len=32):
    # 计算需要多少字节来表示这个整数
    # 注意,这里使用的是向上取整的方式计算字节数
    byte_length = (value.bit_length() + 7) // 8

    # 转换成字节序列
    byte_data = value.to_bytes(byte_length, 'big')

    # 将字节序列转换成uint8的numpy数组
    np_array = np.frombuffer(byte_data, dtype=np.uint8).astype(np.float32)
    
    # 补齐
    padded_arr = np.pad(np_array,(max_len-np_array.shape[0],0))
    return padded_arr

class SimpleConvNet(nn.Module):
    def __init__(self):
        super(SimpleConvNet, self).__init__()
        # 卷积将两个输入通道转换为一个输出通道
        self.conv = nn.Conv2d(1,1, kernel_size=(2,2), stride=(1,1), padding=(0,1),bias=True)

    def forward(self, x):
        x = self.conv(x)
        return x  

# 方案一:不能收敛,不可行
def train_cnn_model_for_add():  
    model = SimpleConvNet()
    criterion = nn.MSELoss()
    optimizer = optim.Adam(model.parameters(), lr=0.01)
      
    num_epochs=200000
    for epoch in range(num_epochs):  
        a=gen_rand_value(64)
        b=gen_rand_value(64)
        c=a+b

        #print("%x" % a)
        #print("%x" % b)
        #print("%x" % c)

        a_arr = to_numpy_array(a)
        b_arr = to_numpy_array(b)
        c_arr = to_numpy_array(c,33)
        #print(c_arr)

        input_arr=np.vstack((a_arr,b_arr))
        #print(input_arr.shape)
        #print(c_arr.shape)

        #(1,1,2,27)
        inputs = torch.from_numpy(input_arr).unsqueeze(0).unsqueeze(0)
        labels=torch.from_numpy(c_arr).unsqueeze(0)
        #print(inputs.shape,labels.shape)

        outputs = model(inputs)
        #print(outputs.shape)
        loss = criterion(outputs, labels)

        # 反向传播和优化
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
        if epoch%1000==0:
             print(f'Epoch [{epoch+1}/{num_epochs}], Loss: {loss.item():.4f}')

# 方案二: 用float32的向量操作实现

# 定义最大计算长度
max_len=32
# 定义uint8最大值
max_value=np.ones((max_len),dtype=np.float32)*256

for epoch in range(10000):
    
    # 设置随机种子,方便复现问题
    np.random.seed(epoch)
    
    # 随机数生成长度为64的十进制大数
    a=gen_rand_value(64)
    b=gen_rand_value(64)

    # 用python实现二个大数相加,做为Ground Truth
    c_gt=a+b

    # 将大数按uint8切分成向量,并转换为float类型
    a_arr = to_numpy_array(a,max_len)
    b_arr = to_numpy_array(b,max_len)
    c_gt_arr = to_numpy_array(c_gt,max_len)         
    
    # a、b二个向量相加
    sum_ab=a_arr+b_arr
    
    # 为了去掉循环中的判断,这里假设最多出现10次进位
    for i in range(10):
        # 得到溢出的值(没有溢出为0)
        sum_ab_overflow=sum_ab-max_value
        # 哪些地方溢出了
        overflow_mask=sum_ab_overflow>=0
        #if overflow_mask.sum()==0:  #如果是DSP,可以用判断,提前退出
        #    break            
        sum_ab_overflow=np.maximum(sum_ab_overflow, 0, sum_ab_overflow)
        # 没有溢出的地方,保留它的值
        sum_ab=sum_ab*(overflow_mask==0)
        
        # 进位标记
        carry_flag=np.zeros((max_len),dtype=np.float32)
        carry_flag[0:max_len-1]=np.array(overflow_mask[1:max_len])

        # 计算结果=溢出情况下的值 + 没有溢出时的位 + 进位的值
        sum_ab=sum_ab_overflow+sum_ab+carry_flag

    # 跟Ground Truth比较误差
    if (sum_ab-c_gt_arr).sum()!=0:
        print(f"epoch:{epoch} error")
        print((sum_ab-c_gt_arr).sum())
        print(sum_ab)
        print(c_gt_arr)
        break
    

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2147459.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Apache subversion 编译流程

目录 1. 概述2. 依赖库简介2.1 Expat2.2 Apache apr2.3 Apache apr-iconv2.4 Apache apr-util2.5 Zlib2.6 OpenSSL2.7 Sqlite2.8 Apache Serf2.9 Apache subversion3. 编译3.1 Expat编译3.1.1 源码信息3.1.2 CMake-GUI3.1.3 编译步骤3.2 APR编译3.2.1 源码信息3.2.2 编译步骤3.…

详解c++菱形继承和多态---下

菱形继承 #include<iostream>using namespace std; class Animal { public:int m_Age; }; class Sheep : public Animal {}; class Tuo : public Animal {}; class SheepTuo : public Sheep, public Tuo {}; void test() {SheepTuo st;st.Sheep::m_Age 18;st.Tuo::m_Age…

数据结构-3.1.栈的基本概念

一.栈的定义&#xff1a; 栈和线性表的区别&#xff1a;栈只能在表尾一端进行插入或者删除的操作&#xff0c;而线性表可以在任意一个地方进行插入或者删除 二.有关栈的关键术语&#xff1a; 三.栈的基本操作&#xff1a; 1.回顾线性表的基本操作&#xff1a; 2.栈的基本操作&…

vue使用vue-i18n实现国际化

我使用的是vue2.6版本&#xff0c;具体使用其他版本可以进行修改 一、安装 npm install vue-i18n -D 二、配置 1、文件配置 ①在src下创建 i18n 目录 ②在 i18n 目录下创建 langs 文件夹 和 index.js文件&#xff0c;具体如下 2、index.js代码如下&#xff0c;这里使用了…

【分立元件】案例:新人加了个TVS管为什么可能导致系统不能正常工作

因为最近在带多个新人,让其设计原理图和PCB总会发现各种电路问题点。比如TVS管接法问题。 TVS是一种限压型的过压保护器,它将过高的电压钳制至一个安全范围,藉以保护后面的电路,有着比其它保护元件更快的反应时间,这使TVS可用在防护lighting、switching、ESD等快速破坏性瞬…

计算机毕业设计 教师科研信息管理系统的设计与实现 Java实战项目 附源码+文档+视频讲解

博主介绍&#xff1a;✌从事软件开发10年之余&#xff0c;专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精…

【字符函数】strcpy函数(字符串复制函数)+strcat函数(字符串追加)+strcmp函数(字符串比较)【笔记】

1.复制函数--------------strcpy函数 函数使用 char*strcpy&#xff08;char* destination, const char* source&#xff09; strcpy函数用于拷贝字符串&#xff0c;即将一个字符串中的内容拷贝到另一个字符串中&#xff08;会覆盖原字符串内容&#xff09;。它的参数是两个指…

TIOBE 编程指数 9 月排行榜公布 VB.Net第七

原文地址&#xff1a;百度安全验证 IT之家 9 月 8 日消息&#xff0c;TIOBE 编程社区指数是一个衡量编程语言受欢迎程度的指标&#xff0c;评判的依据来自世界范围内的工程师、课程、供应商及搜索引擎&#xff0c;今天 TIOBE 官网公布了 2024 年 9 月的编程语言排行榜&#xf…

Element走马灯组件循环播放两个页面是方向不一致

摘要&#xff1a;使用Carousel 走马灯循环播放同一类型的图片、文字等内容&#xff0c;会在循环内容为两组是出现下图 [1]中的现象。本文记录下如何解决 之前项目遇到过一次这个问题&#xff0c;由于indicator-position 指示器不用显示&#xff0c;则判断内容长度为2时&#xf…

恶意Bot流量识别分析实践

1、摘要 随着互联网的发展&#xff0c;自动化工具和脚本&#xff08;Bots&#xff09;的使用越来越普遍。虽然一些善意 Bots 对于网站的正常运行和数据采集至关重要&#xff0c;但恶意 Bots 可能会对网站带来负面影响&#xff0c;如爬取敏感信息、恶意注册、刷流量等。因此&am…

saltstack配置管理

一、saltstack的SSH工作模式 一、salt-ssh介绍 salt-ssh 是 0.17.0 新引入的一个功能&#xff0c;不需要minion对客户端进行管理&#xff0c;也不需要master。salt-ssh 支持salt大部分的功能&#xff1a;如 grains、modules、state 等salt-ssh 没有使用ZeroMQ的通信架构&#…

向日葵好用吗?4款稳定的远程控制软件推荐。

远程控制技术现在已经被应用于很多个领域&#xff0c;像企业办公&#xff0c;远程协助&#xff0c;智能家居&#xff0c;工业控制等等。我们常常会用到的时前两种。而实现远程控制的方式也有多种&#xff0c;但是最方便高效的还是使用第三方软件。我最常使用的是向日葵&#xf…

算法.图论-并查集上

文章目录 1. 并查集介绍2. 并查集的实现2.1 实现逻辑2.2 isSameSet方法2.3 union方法(小挂大优化)2.4 find方法(路径压缩优化) 3. 并查集模板 1. 并查集介绍 定义&#xff1a; 并查集是一种树型的数据结构&#xff0c;用于处理一些不相交集合的合并及查询问题&#xff08;即所…

游戏如何对抗定制挂

近年来&#xff0c;游戏安全对抗强度相比以往更加激烈&#xff0c;具体表现在“定制挂”趋势显著。在近期收集的近万款外挂样本中&#xff0c;定制挂约占比78%&#xff0c;常见的内存修改器、变速器等通用作弊手段占比正在下降。 所谓定制挂&#xff0c;是指针对某款游戏单独开…

SPI接口通信协议浅谈成都自动化开发

沙鸥-成都 1 什么是SPI SPI是串口外设接口的缩写&#xff0c;是一种高速的、全双工、同步的通信协议&#xff0c;是微处理器与外围IC之间常用的一种通讯方式。 SPI是主从式的通信协议&#xff0c;可以一主机一从机通信&#xff0c;也可以一主机多从机通信。 2 SPI的优缺点 SPI接…

【Java版】云HIS系统源码

云HIS系统介绍 云HIS系统是一款满足基层医疗机构各类业务需要的健康云产品。该产品能帮助基层医疗机构完成日常各类业务&#xff0c;提供病患挂号支持、病患问诊、电子病历、开药发药、会员管理、统计查询、医生站和护士站等一系列常规功能&#xff0c;还能与公卫、PACS等各类…

【STM32 HAL库】OLED显示模块

【STM32 HAL库】OLED显示模块 前言理论OLED基本参数OLED基本驱动原理OLED坐标轴 应用CubeMx配置底层函数代码高层封装函数printf显示函数 前言 本文为笔者学习 OLED 的总结&#xff0c;基于keysking的视频内容&#xff0c;如有错误&#xff0c;欢迎指正 理论 OLED基本参数 …

基于224G的超高速以太网端口1.6Tbps 1600G真的来了~

基于224G PAM4 SerDes的1.6T(更激进些的是3.2T&#xff09; 受AI智能算中心的驱动&#xff0c;基于4x112G的400G光模块&#xff0c;和基于8x112G的800G的光模块已经很成熟了&#xff0c;标志就是大家都在降本增效&#xff0c;考虑干掉功耗的DSP&#xff0c;...另外一个标志就是…

关于支持向量机的一份介绍

在这篇文章中&#xff0c;我将介绍与支持向量机有关的东西&#xff0c;我们知道支持向量机主要分两类&#xff0c;就是线性支持向量机和核支持向量机这两种&#xff08;当然还有其他的&#xff0c;如多类支持向量机、 Nu-Support Vector Regression等&#xff09;&#xff0c;因…

AIGC生图基础知识

一、引言 AIGC&#xff0c;即AI-Generated Content&#xff0c;是一种利用大型预训练模型如生成对抗网络&#xff08;GAN&#xff09;、扩散网络&#xff08;Diffusion&#xff09;和语言大模型&#xff08;Transformer&#xff09;等人工智能技术&#xff0c;通过对大量数据进…